summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/llcommon/llpointer.h126
-rwxr-xr-xindra/llinventory/llinventory.h1
-rwxr-xr-xindra/newview/llagentwearables.cpp8
-rwxr-xr-xindra/newview/llagentwearablesfetch.cpp15
-rwxr-xr-xindra/newview/llappearancemgr.cpp103
-rwxr-xr-xindra/newview/llappearancemgr.h13
-rwxr-xr-xindra/newview/llinventorybridge.cpp32
-rwxr-xr-xindra/newview/llpaneleditwearable.cpp15
-rwxr-xr-xindra/newview/llviewerinventory.cpp212
-rwxr-xr-xindra/newview/llviewerinventory.h27
10 files changed, 336 insertions, 216 deletions
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 88c09c8dca..dd43e3aaa2 100755
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -171,4 +171,130 @@ protected:
Type* mPointer;
};
+template <class Type> class LLConstPointer
+{
+public:
+ LLConstPointer() :
+ mPointer(NULL)
+ {
+ }
+
+ LLConstPointer(const Type* ptr) :
+ mPointer(ptr)
+ {
+ ref();
+ }
+
+ LLConstPointer(const LLConstPointer<Type>& ptr) :
+ mPointer(ptr.mPointer)
+ {
+ ref();
+ }
+
+ // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLConstPointer(const LLConstPointer<Subclass>& ptr) :
+ mPointer(ptr.get())
+ {
+ ref();
+ }
+
+ ~LLConstPointer()
+ {
+ unref();
+ }
+
+ const Type* get() const { return mPointer; }
+ const Type* operator->() const { return mPointer; }
+ const Type& operator*() const { return *mPointer; }
+
+ operator BOOL() const { return (mPointer != NULL); }
+ operator bool() const { return (mPointer != NULL); }
+ bool operator!() const { return (mPointer == NULL); }
+ bool isNull() const { return (mPointer == NULL); }
+ bool notNull() const { return (mPointer != NULL); }
+
+ operator const Type*() const { return mPointer; }
+ bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
+ bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
+ bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+
+ LLConstPointer<Type>& operator =(const Type* ptr)
+ {
+ if( mPointer != ptr )
+ {
+ unref();
+ mPointer = ptr;
+ ref();
+ }
+
+ return *this;
+ }
+
+ LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
+ {
+ if( mPointer != ptr.mPointer )
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ref();
+ }
+ return *this;
+ }
+
+ // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
+ {
+ if( mPointer != ptr.get() )
+ {
+ unref();
+ mPointer = ptr.get();
+ ref();
+ }
+ return *this;
+ }
+
+ // Just exchange the pointers, which will not change the reference counts.
+ static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
+ {
+ const Type* temp = a.mPointer;
+ a.mPointer = b.mPointer;
+ b.mPointer = temp;
+ }
+
+protected:
+#ifdef LL_LIBRARY_INCLUDE
+ void ref();
+ void unref();
+#else
+ void ref()
+ {
+ if (mPointer)
+ {
+ mPointer->ref();
+ }
+ }
+
+ void unref()
+ {
+ if (mPointer)
+ {
+ const Type *tempp = mPointer;
+ mPointer = NULL;
+ tempp->unref();
+ if (mPointer != NULL)
+ {
+ llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
+ unref();
+ }
+ }
+ }
+#endif
+protected:
+ const Type* mPointer;
+};
+
#endif
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index b718f0f9b7..dd504fb155 100755
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -48,6 +48,7 @@ class LLInventoryObject : public LLRefCount
{
public:
typedef std::list<LLPointer<LLInventoryObject> > object_list_t;
+ typedef std::list<LLConstPointer<LLInventoryObject> > const_object_list_t;
//--------------------------------------------------------------------
// Initialization
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 8c33a778e3..f3c9998a7d 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -952,15 +952,15 @@ public:
/* virtual */ void fire(const LLUUID& inv_item)
{
llinfos << "One item created " << inv_item.asString() << llendl;
- LLViewerInventoryItem *item = gInventory.getItem(inv_item);
- mItemsToLink.put(item);
+ LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item);
+ mItemsToLink.push_back(item);
updatePendingWearable(inv_item);
}
~OnWearableItemCreatedCB()
{
llinfos << "All items created" << llendl;
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
- LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
+ link_inventory_array(LLAppearanceMgr::instance().getCOF(),
mItemsToLink,
link_waiter);
}
@@ -1011,7 +1011,7 @@ public:
}
private:
- LLInventoryModel::item_array_t mItemsToLink;
+ LLInventoryObject::const_object_list_t mItemsToLink;
std::vector<LLViewerWearable*> mWearablesAwaitingItems;
};
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 014c610a5c..a2a667e660 100755
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -117,26 +117,21 @@ public:
// Link to all fetched items in COF.
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
+ LLInventoryObject::const_object_list_t item_array;
for (uuid_vec_t::iterator it = mIDs.begin();
it != mIDs.end();
++it)
{
LLUUID id = *it;
- LLViewerInventoryItem *item = gInventory.getItem(*it);
+ LLConstPointer<LLInventoryObject> item = gInventory.getItem(*it);
if (!item)
{
- llwarns << "fetch failed!" << llendl;
+ llwarns << "fetch failed for item " << (*it) << "!" << llendl;
continue;
}
-
- link_inventory_item(gAgent.getID(),
- item->getLinkedUUID(),
- LLAppearanceMgr::instance().getCOF(),
- item->getName(),
- item->getDescription(),
- LLAssetType::AT_LINK,
- link_waiter);
+ item_array.push_back(item);
}
+ link_inventory_array(LLAppearanceMgr::instance().getCOF(), item_array, link_waiter);
}
};
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 3818bd8aec..c4bc6f648f 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -909,20 +909,15 @@ void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLView
}
LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
- LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+ LLConstPointer<LLInventoryObject> itemp = gInventory.getItem(item_id);
wearable->setItemID(item_id);
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
holder->eraseTypeToRecover(type);
llassert(itemp);
if (itemp)
{
- link_inventory_item( gAgent.getID(),
- item_id,
- LLAppearanceMgr::instance().getCOF(),
- itemp->getName(),
- itemp->getDescription(),
- LLAssetType::AT_LINK,
- cb);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+
+ link_inventory_object(LLAppearanceMgr::instance().getCOF(), itemp, cb);
}
}
@@ -1551,6 +1546,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
LLInventoryModel::item_array_t* items;
gInventory.getDirectDescendentsOf(src_id, cats, items);
llinfos << "copying " << items->count() << " items" << llendl;
+ LLInventoryObject::const_object_list_t link_array;
for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
iter != items->end();
++iter)
@@ -1561,14 +1557,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(),
- item->getLinkedUUID(),
- dst_id,
- item->getName(),
- item->getActualDescription(),
- LLAssetType::AT_LINK, cb);
+ link_array.push_back(LLConstPointer<LLInventoryObject>(item));
break;
}
case LLAssetType::AT_LINK_FOLDER:
@@ -1578,12 +1567,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
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,
- item->getName(),
- item->getDescription(),
- LLAssetType::AT_LINK_FOLDER, cb);
+ link_array.push_back(LLConstPointer<LLInventoryObject>(item));
}
break;
}
@@ -1606,6 +1590,11 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
break;
}
}
+ if (!link_array.empty())
+ {
+ const bool resolve_links = true;
+ link_inventory_array(dst_id, link_array, cb, resolve_links);
+ }
}
BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id)
@@ -1753,42 +1742,6 @@ void LLAppearanceMgr::filterWearableItems(
}
}
-// Create links to all listed items.
-void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
- LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb)
-{
- for (S32 i=0; i<items.count(); i++)
- {
- const LLInventoryItem* item = items.get(i).get();
- link_inventory_item(gAgent.getID(),
- item->getLinkedUUID(),
- cat_uuid,
- item->getName(),
- item->getActualDescription(),
- LLAssetType::AT_LINK,
- cb);
-
- const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
- const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL;
-#endif
- }
-}
-
-void LLAppearanceMgr::removeAll(LLInventoryModel::item_array_t& items_to_kill,
- LLPointer<LLInventoryCallback> cb)
-{
- for (LLInventoryModel::item_array_t::iterator it = items_to_kill.begin();
- it != items_to_kill.end();
- ++it)
- {
- LLViewerInventoryItem *item = *it;
- remove_inventory_item(item->getUUID(), cb);
- }
-}
-
void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
{
LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
@@ -1934,8 +1887,7 @@ void LLAppearanceMgr::createBaseOutfitLink(const LLUUID& category, LLPointer<LLI
if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
{
- link_inventory_item(gAgent.getID(), category, cof, catp->getName(), "",
- LLAssetType::AT_LINK_FOLDER, link_waiter);
+ link_inventory_object(cof, catp, link_waiter);
new_outfit_name = catp->getName();
}
@@ -2027,7 +1979,7 @@ void item_array_diff(LLInventoryModel::item_array_t& full_list,
S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
LLAssetType::EType type,
S32 max_items,
- LLInventoryModel::item_array_t& items_to_kill)
+ LLInventoryObject::object_list_t& items_to_kill)
{
S32 to_kill_count = 0;
@@ -2045,7 +1997,7 @@ S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
it != kill_items.end();
++it)
{
- items_to_kill.push_back(*it);
+ items_to_kill.push_back(LLPointer<LLInventoryObject>(*it));
to_kill_count++;
}
return to_kill_count;
@@ -2053,7 +2005,7 @@ S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id,
- LLInventoryModel::item_array_t& items_to_kill)
+ LLInventoryObject::object_list_t& items_to_kill)
{
findExcessOrDuplicateItems(cat_id,LLAssetType::AT_BODYPART,
1, items_to_kill);
@@ -2065,14 +2017,13 @@ void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id,
void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb)
{
- LLInventoryModel::item_array_t items_to_kill;
+ LLInventoryObject::object_list_t items_to_kill;
findAllExcessOrDuplicateItems(getCOF(), items_to_kill);
if (items_to_kill.size()>0)
{
// Remove duplicate or excess wearables. Should normally be enforced at the UI level, but
// this should catch anything that gets through.
- removeAll(items_to_kill, cb);
- return;
+ remove_inventory_items(items_to_kill, cb);
}
}
@@ -2525,7 +2476,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id,
void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,
LLPointer<LLInventoryCallback> cb,
const std::string description)
-{
+{
const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
if (!vitem)
{
@@ -2577,18 +2528,10 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,
if (!linked_already)
{
- std::string link_description = description;
- if (vitem->getIsLinkType())
- {
- link_description = vitem->getActualDescription();
- }
- link_inventory_item( gAgent.getID(),
- vitem->getLinkedUUID(),
- getCOF(),
- vitem->getName(),
- link_description,
- LLAssetType::AT_LINK,
- cb);
+ LLInventoryObject::const_object_list_t obj_array;
+ obj_array.push_back(LLConstPointer<LLInventoryObject>(vitem));
+ const bool resolve_links = true;
+ link_inventory_array(getCOF(), obj_array, cb, resolve_links);
}
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 8c8b5e2489..346577ab9a 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -67,9 +67,9 @@ public:
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
LLAssetType::EType type,
S32 max_items,
- LLInventoryModel::item_array_t& items_to_kill);
+ LLInventoryObject::object_list_t& items_to_kill);
void findAllExcessOrDuplicateItems(const LLUUID& cat_id,
- LLInventoryModel::item_array_t& items_to_kill);
+ LLInventoryObject::object_list_t& items_to_kill);
void enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb);
S32 getActiveCopyOperations() const;
@@ -139,15 +139,6 @@ public:
void registerAttachment(const LLUUID& item_id);
void setAttachmentInvLinkEnable(bool val);
- // utility function for bulk linking.
- void linkAll(const LLUUID& category,
- LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb);
-
- // And bulk removal.
- void removeAll(LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb);
-
// Add COF link to individual item.
void addCOFItemLink(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
void addCOFItemLink(const LLInventoryItem *item, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index cb3f40a5bb..0481bf5f45 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3223,28 +3223,9 @@ void LLFolderBridge::pasteLinkFromClipboard()
dropToOutfit(item, move_is_into_current_outfit);
}
}
- else if (LLInventoryCategory *cat = model->getCategory(object_id))
+ else if (LLConstPointer<LLInventoryObject> obj = model->getObject(object_id))
{
- const std::string empty_description = "";
- link_inventory_item(
- gAgent.getID(),
- cat->getUUID(),
- parent_id,
- cat->getName(),
- empty_description,
- LLAssetType::AT_LINK_FOLDER,
- LLPointer<LLInventoryCallback>(NULL));
- }
- else if (LLInventoryItem *item = model->getItem(object_id))
- {
- link_inventory_item(
- gAgent.getID(),
- item->getLinkedUUID(),
- parent_id,
- item->getName(),
- item->getDescription(),
- LLAssetType::AT_LINK,
- LLPointer<LLInventoryCallback>(NULL));
+ link_inventory_object(parent_id, obj, LLPointer<LLInventoryCallback>(NULL));
}
}
// Change mode to paste for next paste
@@ -3830,14 +3811,7 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c
else
{
LLPointer<LLInventoryCallback> cb = NULL;
- link_inventory_item(
- gAgent.getID(),
- inv_item->getLinkedUUID(),
- mUUID,
- inv_item->getName(),
- inv_item->getDescription(),
- LLAssetType::AT_LINK,
- cb);
+ link_inventory_object(mUUID, LLConstPointer<LLInventoryObject>(inv_item), cb);
}
}
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index a1222424ee..0532370ff2 100755
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1095,13 +1095,14 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)
LL_DEBUGS("Avatar") << "link refresh, creating new link to " << link_item->getLinkedUUID()
<< " removing old link at " << link_item->getUUID()
<< " wearable item id " << mWearablePtr->getItemID() << llendl;
- link_inventory_item( gAgent.getID(),
- link_item->getLinkedUUID(),
- LLAppearanceMgr::instance().getCOF(),
- link_item->getName(),
- description,
- LLAssetType::AT_LINK,
- gAgentAvatarp->mEndCustomizeCallback);
+
+ LLInventoryObject::const_object_list_t obj_array;
+ obj_array.push_back(LLConstPointer<LLInventoryObject>(link_item));
+ const bool resolve_links = true;
+ link_inventory_array(LLAppearanceMgr::instance().getCOF(),
+ obj_array,
+ gAgentAvatarp->mEndCustomizeCallback,
+ resolve_links);
// Remove old link
remove_inventory_item(link_item->getUUID(), gAgentAvatarp->mEndCustomizeCallback);
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index bff6767617..33186a5a88 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1074,77 +1074,133 @@ void copy_inventory_item(
gAgent.sendReliableMessage();
}
-void link_inventory_item(
- const LLUUID& agent_id,
- const LLUUID& item_id,
- const LLUUID& parent_id,
- const std::string& new_name,
- const std::string& new_description,
- const LLAssetType::EType asset_type,
- LLPointer<LLInventoryCallback> cb)
+// Create link to single inventory object.
+void link_inventory_object(const LLUUID& category,
+ LLConstPointer<LLInventoryObject> baseobj,
+ LLPointer<LLInventoryCallback> cb)
{
- const LLInventoryObject *baseobj = gInventory.getObject(item_id);
if (!baseobj)
{
- llwarns << "attempt to link to unknown item, linked-to-item's itemID " << item_id << llendl;
- return;
- }
- if (baseobj && baseobj->getIsLinkType())
- {
- llwarns << "attempt to create a link to a link, linked-to-item's itemID " << item_id << llendl;
+ llwarns << "Attempt to link to non-existent object" << llendl;
return;
}
- if (baseobj && !LLAssetType::lookupCanLink(baseobj->getType()))
- {
- // Fail if item can be found but is of a type that can't be linked.
- // Arguably should fail if the item can't be found too, but that could
- // be a larger behavioral change.
- llwarns << "attempt to link an unlinkable item, type = " << baseobj->getActualType() << llendl;
- return;
- }
-
- LLUUID transaction_id;
- LLInventoryType::EType inv_type = LLInventoryType::IT_NONE;
- if (dynamic_cast<const LLInventoryCategory *>(baseobj))
- {
- inv_type = LLInventoryType::IT_CATEGORY;
- }
- else
+ LLInventoryObject::const_object_list_t obj_array;
+ obj_array.push_back(baseobj);
+ link_inventory_array(category, obj_array, cb);
+}
+
+void link_inventory_object(const LLUUID& category,
+ const LLUUID& id,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLConstPointer<LLInventoryObject> baseobj = gInventory.getObject(id);
+ link_inventory_object(category, baseobj, cb);
+}
+
+// Create links to all listed inventory objects.
+void link_inventory_array(const LLUUID& category,
+ LLInventoryObject::const_object_list_t& baseobj_array,
+ LLPointer<LLInventoryCallback> cb,
+ bool resolve_links /* = false */)
+{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ const LLViewerInventoryCategory *cat = gInventory.getCategory(category);
+ const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";
+#endif
+ LLInventoryObject::const_object_list_t::const_iterator it = baseobj_array.begin();
+ LLInventoryObject::const_object_list_t::const_iterator end = baseobj_array.end();
+ for (; it != end; ++it)
{
- const LLViewerInventoryItem *baseitem = dynamic_cast<const LLViewerInventoryItem *>(baseobj);
- if (baseitem)
+ const LLInventoryObject* baseobj = *it;
+ if (!baseobj)
{
- inv_type = baseitem->getInventoryType();
+ llwarns << "attempt to link to unknown object" << llendl;
+ continue;
+ }
+ if (!resolve_links && baseobj->getIsLinkType())
+ {
+ llwarns << "attempt to create a link to a link, linked-to-object's ID " << baseobj->getUUID() << llendl;
+ continue;
}
- }
-#if 1 // debugging stuff
- LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
- lldebugs << "cat: " << cat << llendl;
-
+ if (!LLAssetType::lookupCanLink(baseobj->getType()))
+ {
+ // Fail if item can be found but is of a type that can't be linked.
+ // Arguably should fail if the item can't be found too, but that could
+ // be a larger behavioral change.
+ llwarns << "attempt to link an unlinkable object, type = " << baseobj->getActualType() << llendl;
+ continue;
+ }
+
+ LLUUID transaction_id;
+ LLInventoryType::EType inv_type = LLInventoryType::IT_NONE;
+ LLAssetType::EType asset_type = LLAssetType::AT_NONE;
+ std::string new_desc;
+ LLUUID linkee_id;
+ if (dynamic_cast<const LLInventoryCategory *>(baseobj))
+ {
+ inv_type = LLInventoryType::IT_CATEGORY;
+ asset_type = LLAssetType::AT_LINK_FOLDER;
+ linkee_id = baseobj->getUUID();
+ }
+ else
+ {
+ const LLViewerInventoryItem *baseitem = dynamic_cast<const LLViewerInventoryItem *>(baseobj);
+ if (baseitem)
+ {
+ inv_type = baseitem->getInventoryType();
+ new_desc = baseitem->getActualDescription();
+ switch (baseitem->getActualType())
+ {
+ case LLAssetType::AT_LINK:
+ case LLAssetType::AT_LINK_FOLDER:
+ linkee_id = baseobj->getLinkedUUID();
+ asset_type = baseitem->getActualType();
+ break;
+ default:
+ linkee_id = baseobj->getUUID();
+ asset_type = LLAssetType::AT_LINK;
+ break;
+ }
+ }
+ else
+ {
+ llwarns << "could not convert object into an item or category: " << baseobj->getUUID() << llendl;
+ continue;
+ }
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LinkInventoryItem);
+ msg->nextBlock(_PREHASH_AgentData);
+ {
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ }
+ msg->nextBlock(_PREHASH_InventoryBlock);
+ {
+ msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
+ msg->addUUIDFast(_PREHASH_FolderID, category);
+ msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
+ msg->addUUIDFast(_PREHASH_OldItemID, linkee_id);
+ msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
+ msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
+ msg->addStringFast(_PREHASH_Name, baseobj->getName());
+ msg->addStringFast(_PREHASH_Description, new_desc);
+ }
+ gAgent.sendReliableMessage();
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ LL_DEBUGS("Inventory") << "Linking Object [ name:" << baseobj->getName()
+ << " UUID:" << baseobj->getUUID()
+ << " ] into Category [ name:" << cat_name
+ << " UUID:" << category << " ] " << LL_ENDL;
#endif
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_LinkInventoryItem);
- msg->nextBlock(_PREHASH_AgentData);
- {
- msg->addUUIDFast(_PREHASH_AgentID, agent_id);
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
- msg->nextBlock(_PREHASH_InventoryBlock);
- {
- msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
- msg->addUUIDFast(_PREHASH_FolderID, parent_id);
- msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
- msg->addUUIDFast(_PREHASH_OldItemID, item_id);
- msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
- msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
- msg->addStringFast(_PREHASH_Name, new_name);
- msg->addStringFast(_PREHASH_Description, new_description);
- }
- gAgent.sendReliableMessage();
}
+
+
void move_inventory_item(
const LLUUID& agent_id,
const LLUUID& session_id,
@@ -1301,14 +1357,41 @@ void update_inventory_category(
}
}
+void remove_inventory_items(
+ LLInventoryObject::object_list_t& items_to_kill,
+ LLPointer<LLInventoryCallback> cb)
+{
+ for (LLInventoryObject::object_list_t::iterator it = items_to_kill.begin();
+ it != items_to_kill.end();
+ ++it)
+ {
+ remove_inventory_item(*it, cb);
+ }
+}
+
void remove_inventory_item(
const LLUUID& item_id,
LLPointer<LLInventoryCallback> cb)
{
- LLPointer<LLViewerInventoryItem> obj = gInventory.getItem(item_id);
- LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << llendl;
+ LLPointer<LLInventoryObject> obj = gInventory.getItem(item_id);
+ if (obj)
+ {
+ remove_inventory_item(obj, cb);
+ }
+ else
+ {
+ LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << "(NOT FOUND)" << llendl;
+ }
+}
+
+void remove_inventory_item(
+ LLPointer<LLInventoryObject> obj,
+ LLPointer<LLInventoryCallback> cb)
+{
if(obj)
{
+ const LLUUID item_id(obj->getUUID());
+ LL_DEBUGS("Inventory") << "item_id: [" << item_id << "] name " << obj->getName() << llendl;
if (AISCommand::isAPIAvailable())
{
LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb);
@@ -1336,7 +1419,8 @@ void remove_inventory_item(
}
else
{
- llwarns << "remove_inventory_item called for invalid or nonexistent item " << item_id << llendl;
+ // *TODO: Clean up callback?
+ llwarns << "remove_inventory_item called for invalid or nonexistent item." << llendl;
}
}
@@ -1632,13 +1716,7 @@ void slam_inventory_folder(const LLUUID& folder_id,
++it)
{
const LLSD& item_contents = *it;
- link_inventory_item(gAgent.getID(),
- item_contents["linked_id"].asUUID(),
- folder_id,
- item_contents["name"].asString(),
- item_contents["desc"].asString(),
- LLAssetType::EType(item_contents["type"].asInteger()),
- cb);
+ link_inventory_object(folder_id, item_contents["linked_id"].asUUID(), cb);
}
remove_folder_contents(folder_id,false,cb);
}
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 6bc6343f3f..cc715ae21d 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -351,14 +351,17 @@ void copy_inventory_item(
const std::string& new_name,
LLPointer<LLInventoryCallback> cb);
-void link_inventory_item(
- const LLUUID& agent_id,
- const LLUUID& item_id,
- const LLUUID& parent_id,
- const std::string& new_name,
- const std::string& new_description,
- const LLAssetType::EType asset_type,
- LLPointer<LLInventoryCallback> cb);
+// utility functions for inventory linking.
+void link_inventory_object(const LLUUID& category,
+ LLConstPointer<LLInventoryObject> baseobj,
+ LLPointer<LLInventoryCallback> cb);
+void link_inventory_object(const LLUUID& category,
+ const LLUUID& id,
+ LLPointer<LLInventoryCallback> cb);
+void link_inventory_array(const LLUUID& category,
+ LLInventoryObject::const_object_list_t& baseobj_array,
+ LLPointer<LLInventoryCallback> cb,
+ bool resolve_links = false);
void move_inventory_item(
const LLUUID& agent_id,
@@ -382,6 +385,14 @@ void update_inventory_category(
const LLSD& updates,
LLPointer<LLInventoryCallback> cb);
+void remove_inventory_items(
+ LLInventoryObject::object_list_t& items,
+ LLPointer<LLInventoryCallback> cb);
+
+void remove_inventory_item(
+ LLPointer<LLInventoryObject> obj,
+ LLPointer<LLInventoryCallback> cb);
+
void remove_inventory_item(
const LLUUID& item_id,
LLPointer<LLInventoryCallback> cb);