summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/newview/llaisapi.cpp5
-rwxr-xr-xindra/newview/llappearancemgr.cpp121
-rwxr-xr-xindra/newview/llappearancemgr.h8
-rwxr-xr-xindra/newview/llfloateropenobject.cpp20
-rwxr-xr-xindra/newview/llfloateropenobject.h11
-rwxr-xr-xindra/newview/llinventorymodel.cpp72
-rwxr-xr-xindra/newview/llinventorymodel.h9
-rwxr-xr-xindra/newview/llpaneloutfitsinventory.cpp2
-rwxr-xr-xindra/newview/llstartup.cpp4
-rwxr-xr-xindra/newview/llviewerinventory.cpp3
-rwxr-xr-xindra/newview/llviewerinventory.h6
11 files changed, 165 insertions, 96 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 8037654812..6d5f1951f9 100755
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -440,8 +440,9 @@ void AISUpdate::doUpdate()
LLViewerInventoryCategory *cat = gInventory.getCategory(id);
if (cat->getVersion() != version)
{
- llwarns << "Possible version mismatch, viewer " << cat->getVersion()
- << " server " << version << llendl;
+ llwarns << "Possible version mismatch for category " << cat->getName()
+ << ", viewer version " << cat->getVersion()
+ << " server version " << version << llendl;
}
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 57a836c070..118f557c97 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -53,6 +53,7 @@
#include "llsdutil.h"
#include "llsdserialize.h"
#include "llhttpretrypolicy.h"
+#include "llaisapi.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -1449,6 +1450,58 @@ void LLAppearanceMgr::shallowCopyCategory(const LLUUID& src_id, const LLUUID& ds
gInventory.notifyObservers();
}
+void LLAppearanceMgr::copyCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
+ bool include_folder_links, LLPointer<LLInventoryCallback> cb)
+{
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ LLSD contents = LLSD::emptyArray();
+ gInventory.getDirectDescendentsOf(src_id, cats, items);
+ llinfos << "copying " << items->count() << " items" << llendl;
+ for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
+ iter != items->end();
+ ++iter)
+ {
+ const LLViewerInventoryItem* item = (*iter);
+ switch (item->getActualType())
+ {
+ 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
+ LLSD item_contents;
+ item_contents["name"] = item->getName();
+ item_contents["desc"] = item->getActualDescription();
+ item_contents["linked_id"] = item->getLinkedUUID();
+ item_contents["type"] = LLAssetType::AT_LINK;
+ contents.append(item_contents);
+ break;
+ }
+ case LLAssetType::AT_LINK_FOLDER:
+ {
+ LLViewerInventoryCategory *catp = item->getLinkedCategory();
+ if (catp && include_folder_links)
+ {
+ LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << llendl;
+ LLSD base_contents;
+ base_contents["name"] = catp->getName();
+ base_contents["desc"] = ""; // categories don't have descriptions.
+ base_contents["linked_id"] = catp->getLinkedUUID();
+ base_contents["type"] = LLAssetType::AT_LINK_FOLDER;
+ contents.append(base_contents);
+ }
+ break;
+ }
+ default:
+ {
+ // Linux refuses to compile unless all possible enums are handled. Really, Linux?
+ break;
+ }
+ }
+ }
+ slam_inventory_folder(dst_id, contents, cb);
+}
// Copy contents of src_id to dst_id.
void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb)
@@ -1466,6 +1519,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(),
@@ -1482,6 +1536,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
// Skip copying outfit links.
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,
@@ -1496,7 +1551,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_GESTURE:
{
- llinfos << "copying inventory item " << item->getName() << llendl;
+ LL_DEBUGS("Avatar") << "copying inventory item " << item->getName() << llendl;
copy_inventory_item(gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),
@@ -2815,11 +2870,14 @@ bool LLAppearanceMgr::updateBaseOutfit()
llassert(!isOutfitLocked());
return false;
}
+
+
setOutfitLocked(true);
gAgentWearables.notifyLoadingStarted();
const LLUUID base_outfit_id = getBaseOutfitUUID();
+ LL_DEBUGS("Avatar") << "updating base outfit to " << base_outfit_id << llendl;
if (base_outfit_id.isNull()) return false;
updateClothingOrderingInfo();
@@ -3334,12 +3392,14 @@ void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
return;
}
+ LL_DEBUGS("Avatar") << "called" << llendl;
LLSD key;
//EXT-7727. For new accounts inventory callback is created during login process
// and may be processed after login process is finished
if (show_panel)
{
+ LL_DEBUGS("Avatar") << "showing panel" << llendl;
LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
}
@@ -3358,32 +3418,59 @@ void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
// link, since, the COF version has changed. There is a race
// condition in initial outfit setup which can lead to rez
// failures - SH-3860.
+ LL_DEBUGS("Avatar") << "requesting appearance update after createBaseOutfitLink" << llendl;
LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb);
}
-LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
+void LLAppearanceMgr::onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel)
{
- if (!isAgentAvatarValid()) return LLUUID::null;
-
- gAgentWearables.notifyLoadingStarted();
+ LLPointer<LLInventoryCallback> cb =
+ new LLBoostFuncInventoryCallback(no_op_inventory_func,
+ boost::bind(&LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered,this,folder_id,show_panel));
+ updateClothingOrderingInfo(LLUUID::null, false, cb);
+}
- // First, make a folder in the My Outfits directory.
- const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
- LLUUID folder_id = gInventory.createNewCategory(
- parent_id,
- LLFolderType::FT_OUTFIT,
- new_folder_name);
+void LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel)
+{
+ LLPointer<LLInventoryCallback> cb =
+ new LLBoostFuncInventoryCallback(no_op_inventory_func,
+ boost::bind(show_created_outfit,folder_id,show_panel));
+ bool copy_folder_links = false;
+ copyCategoryLinks(getCOF(), folder_id, copy_folder_links, cb);
+}
- updateClothingOrderingInfo();
+void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
+{
+ if (!isAgentAvatarValid()) return;
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,
- boost::bind(show_created_outfit,folder_id,show_panel));
- shallowCopyCategoryContents(getCOF(),folder_id, cb);
+ LL_DEBUGS("Avatar") << "creating new outfit" << llendl;
- dumpCat(folder_id,"COF, new outfit");
+ gAgentWearables.notifyLoadingStarted();
- return folder_id;
+ // First, make a folder in the My Outfits directory.
+ const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ std::string cap;
+ if (AISCommand::getCap(cap))
+ {
+ // cap-based category creation was buggy until recently. use
+ // existence of AIS as an indicator the fix is present. Does
+ // not actually use AIS to create the category.
+ inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
+ LLUUID folder_id = gInventory.createNewCategory(
+ parent_id,
+ LLFolderType::FT_OUTFIT,
+ new_folder_name,
+ func);
+ }
+ else
+ {
+ LLUUID folder_id = gInventory.createNewCategory(
+ parent_id,
+ LLFolderType::FT_OUTFIT,
+ new_folder_name);
+ onOutfitFolderCreated(folder_id, show_panel);
+ }
}
void LLAppearanceMgr::wearBaseOutfit()
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index a257f30ea5..4d7c536b3d 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -73,6 +73,10 @@ public:
void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb);
S32 getActiveCopyOperations() const;
+
+ // Copy all links via the slam command (single inventory operation where supported)
+ void copyCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
+ bool include_folder_links, LLPointer<LLInventoryCallback> cb);
// Copy all items and the src category itself.
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
@@ -186,7 +190,9 @@ public:
void removeItemFromAvatar(const LLUUID& item_id);
- LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
+ void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
+ void onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel);
+ void makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel = true);
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 4bfef8b45f..9986bdbd7f 100755
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -162,21 +162,17 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
{
parent_category_id = gInventory.getRootFolderID();
}
-
- LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
-
+
+ inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear);
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLFolderType::FT_NONE,
name,
- callbackCreateInventoryCategory,
- (void*)cat_data);
+ func);
//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;
@@ -198,20 +194,17 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
}
// static
-void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
+void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear)
{
- 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->mWear = wear;
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,
+ BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
callbackMoveInventory,
(void*)wear_data);
if (!success)
@@ -221,7 +214,6 @@ void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, vo
LLNotificationsUtil::add("OpenObjectCannotCopy");
}
- delete cat_data;
}
// static
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index bf7fe69c65..8e472804a4 100755
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -45,15 +45,6 @@ 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;
@@ -72,7 +63,7 @@ protected:
void onClickMoveToInventory();
void onClickMoveAndWear();
- static void callbackCreateInventoryCategory(const LLSD& result, void* data);
+ static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear);
static void callbackMoveInventory(S32 result, void* data);
private:
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index aadf87ab35..e1fd2e02fa 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -472,11 +472,9 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
LOG_CLASS(LLCreateInventoryCategoryResponder);
public:
LLCreateInventoryCategoryResponder(LLInventoryModel* model,
- void (*callback)(const LLSD&, void*),
- void* user_data) :
- mModel(model),
- mCallback(callback),
- mData(user_data)
+ boost::optional<inventory_func_type> callback):
+ mModel(model),
+ mCallback(callback)
{
}
@@ -497,7 +495,7 @@ protected:
}
LLUUID category_id = content["folder_id"].asUUID();
-
+ LL_DEBUGS("Avatar") << ll_pretty_print_sd(content) << llendl;
// Add the category to the internal representation
LLPointer<LLViewerInventoryCategory> cat =
new LLViewerInventoryCategory( category_id,
@@ -510,17 +508,15 @@ protected:
LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
mModel->accountForUpdate(update);
mModel->updateCategory(cat);
-
- if (mCallback && mData)
+
+ if (mCallback)
{
- mCallback(content, mData);
+ mCallback.get()(category_id);
}
-
}
private:
- void (*mCallback)(const LLSD&, void*);
- void* mData;
+ boost::optional<inventory_func_type> mCallback;
LLInventoryModel* mModel;
};
@@ -531,8 +527,7 @@ private:
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& pname,
- void (*callback)(const LLSD&, void*), //Default to NULL
- void* user_data) //Default to NULL
+ boost::optional<inventory_func_type> callback)
{
LLUUID id;
@@ -559,33 +554,32 @@ 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() && callback.get_ptr())
{
- LLViewerRegion* viewer_region = gAgent.getRegion();
- std::string url;
- if ( viewer_region )
- url = viewer_region->getCapability("CreateInventoryCategory");
+ //Let's use the new capability.
- 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;
- }
+ 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;
+
+ LL_DEBUGS("Avatar") << "create category request: " << ll_pretty_print_sd(request) << llendl;
+ // viewer_region->getCapAPI().post(request);
+ LLHTTPClient::post(
+ url,
+ body,
+ new LLCreateInventoryCategoryResponder(this, callback) );
+
+ return LLUUID::null;
}
// Add the category to the internal representation
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 5de951ed05..ee0d4e1994 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -34,6 +34,7 @@
#include "llhttpclient.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
+#include "llviewerinventory.h"
#include "llstring.h"
#include "llmd5.h"
#include <map>
@@ -45,14 +46,9 @@ class LLInventoryObserver;
class LLInventoryObject;
class LLInventoryItem;
class LLInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
-class LLViewerInventoryItem;
-class LLViewerInventoryCategory;
class LLMessageSystem;
class LLInventoryCollectFunctor;
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLInventoryModel
//
@@ -394,8 +390,7 @@ public:
LLUUID createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& name,
- void (*callback)(const LLSD&, void*) = NULL,
- void* user_data = NULL );
+ boost::optional<inventory_func_type> callback = boost::optional<inventory_func_type>());
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/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index d6c927ab58..21b77ef471 100755
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -184,7 +184,7 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD&
LLStringUtil::trim(outfit_name);
if( !outfit_name.empty() )
{
- LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
+ LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
LLSidepanelAppearance* panel_appearance = getAppearanceSP();
if (panel_appearance)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 8890df199b..84d42c6345 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2613,10 +2613,10 @@ void LLStartUp::saveInitialOutfit()
if (sWearablesLoadedCon.connected())
{
- lldebugs << "sWearablesLoadedCon is connected, disconnecting" << llendl;
+ LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << llendl;
sWearablesLoadedCon.disconnect();
}
- lldebugs << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
+ LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << llendl;
LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 26aecd39d1..9725ea6456 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -69,8 +69,9 @@
#include "llclipboard.h"
#include "llhttpretrypolicy.h"
-// Two do-nothing ops for use in callbacks.
+// do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
+void no_op_llsd_func(const LLSD&) {}
void no_op() {}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 032efd9542..de1f3daa1e 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -263,9 +263,11 @@ private:
};
typedef boost::function<void(const LLUUID&)> inventory_func_type;
-void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
-
+typedef boost::function<void(const LLSD&)> llsd_func_type;
typedef boost::function<void()> nullary_func_type;
+
+void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
+void no_op_llsd_func(const LLSD&); // likewise for LLSD
void no_op(); // A do-nothing nullary func.
// Shim between inventory callback and boost function/callable