summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerinventory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerinventory.cpp')
-rw-r--r--indra/newview/llviewerinventory.cpp386
1 files changed, 327 insertions, 59 deletions
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index ed3d6a0464..9e58acdcd3 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -2,31 +2,25 @@
* @file llviewerinventory.cpp
* @brief Implementation of the viewer side inventory objects.
*
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,10 +30,10 @@
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "message.h"
-#include "indra_constants.h"
#include "llagent.h"
#include "llagentcamera.h"
+#include "llagentwearables.h"
#include "llviewerfoldertype.h"
#include "llfolderview.h"
#include "llviewercontrol.h"
@@ -54,6 +48,7 @@
#include "llinventorybridge.h"
#include "llinventorypanel.h"
#include "llfloaterinventory.h"
+#include "lllandmarkactions.h"
#include "llviewerassettype.h"
#include "llviewerregion.h"
@@ -62,12 +57,15 @@
#include "llviewerwindow.h"
#include "lltrans.h"
#include "llappearancemgr.h"
-#include "llfloatercustomize.h"
#include "llcommandhandler.h"
#include "llviewermessage.h"
+#include "llsidepanelappearance.h"
+#include "llavatarnamecache.h"
+#include "llavataractions.h"
+#include "lllogininstance.h"
///----------------------------------------------------------------------------
-/// Helper class to store special inventory item names
+/// Helper class to store special inventory item names and their localized values.
///----------------------------------------------------------------------------
class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary>
{
@@ -91,11 +89,78 @@ public:
mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt");
mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha");
mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo");
+ mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics");
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
+ mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
+ mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
mInventoryItemsDict["Contents"] = LLTrans::getString("Contents");
+
+ mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture");
+ mInventoryItemsDict["Male Gestures"] = LLTrans::getString("Male Gestures");
+ mInventoryItemsDict["Female Gestures"] = LLTrans::getString("Female Gestures");
+ mInventoryItemsDict["Other Gestures"] = LLTrans::getString("Other Gestures");
+ mInventoryItemsDict["Speech Gestures"] = LLTrans::getString("Speech Gestures");
+ mInventoryItemsDict["Common Gestures"] = LLTrans::getString("Common Gestures");
+
+ //predefined gestures
+
+ //male
+ mInventoryItemsDict["Male - Excuse me"] = LLTrans::getString("Male - Excuse me");
+ mInventoryItemsDict["Male - Get lost"] = LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319
+ mInventoryItemsDict["Male - Blow kiss"] = LLTrans::getString("Male - Blow kiss");
+ mInventoryItemsDict["Male - Boo"] = LLTrans::getString("Male - Boo");
+ mInventoryItemsDict["Male - Bored"] = LLTrans::getString("Male - Bored");
+ mInventoryItemsDict["Male - Hey"] = LLTrans::getString("Male - Hey");
+ mInventoryItemsDict["Male - Laugh"] = LLTrans::getString("Male - Laugh");
+ mInventoryItemsDict["Male - Repulsed"] = LLTrans::getString("Male - Repulsed");
+ mInventoryItemsDict["Male - Shrug"] = LLTrans::getString("Male - Shrug");
+ mInventoryItemsDict["Male - Stick tougue out"] = LLTrans::getString("Male - Stick tougue out");
+ mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow");
+
+ //female
+ mInventoryItemsDict["Female - Chuckle"] = LLTrans::getString("Female - Chuckle");
+ mInventoryItemsDict["Female - Cry"] = LLTrans::getString("Female - Cry");
+ mInventoryItemsDict["Female - Embarrassed"] = LLTrans::getString("Female - Embarrassed");
+ mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me");
+ mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319
+ mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss");
+ mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo");
+ mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored");
+ mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey");
+ mInventoryItemsDict["Female - Hey baby"] = LLTrans::getString("Female - Hey baby");
+ mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh");
+ mInventoryItemsDict["Female - Looking good"] = LLTrans::getString("Female - Looking good");
+ mInventoryItemsDict["Female - Over here"] = LLTrans::getString("Female - Over here");
+ mInventoryItemsDict["Female - Please"] = LLTrans::getString("Female - Please");
+ mInventoryItemsDict["Female - Repulsed"] = LLTrans::getString("Female - Repulsed");
+ mInventoryItemsDict["Female - Shrug"] = LLTrans::getString("Female - Shrug");
+ mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out");
+ mInventoryItemsDict["Female - Wow"] = LLTrans::getString("Female - Wow");
+
+ }
+
+ /**
+ * Finds passed name in dictionary and replaces it with found localized value.
+ *
+ * @param object_name - string to be localized.
+ * @return true if passed name was found and localized, false otherwise.
+ */
+ bool localizeInventoryObjectName(std::string& object_name)
+ {
+ LL_DEBUGS("InventoryLocalize") << "Searching for localization: " << object_name << LL_ENDL;
+
+ std::map<std::string, std::string>::const_iterator dictionary_iter = mInventoryItemsDict.find(object_name);
+
+ bool found = dictionary_iter != mInventoryItemsDict.end();
+ if(found)
+ {
+ object_name = dictionary_iter->second;
+ LL_DEBUGS("InventoryLocalize") << "Found, new name is: " << object_name << LL_ENDL;
+ }
+ return found;
}
};
@@ -118,6 +183,12 @@ public:
return false;
}
+ if (!LLUI::sSettingGroups["config"]->getBOOL("EnableInventory"))
+ {
+ LLNotificationsUtil::add("NoInventory", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
// support secondlife:///app/inventory/show
if (params[0].asString() == "show")
{
@@ -151,6 +222,7 @@ public:
};
LLInventoryHandler gInventoryHandler;
+
///----------------------------------------------------------------------------
/// Class LLViewerInventoryItem
///----------------------------------------------------------------------------
@@ -299,10 +371,14 @@ void LLViewerInventoryItem::fetchFromServer(void) const
// we have to check region. It can be null after region was destroyed. See EXT-245
if (region)
{
- if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
- url = region->getCapability("FetchLib");
- else
- url = region->getCapability("FetchInventory");
+ if(gAgent.getID() != mPermissions.getOwner())
+ {
+ url = region->getCapability("FetchLib2");
+ }
+ else
+ {
+ url = region->getCapability("FetchInventory2");
+ }
}
else
{
@@ -351,16 +427,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* bloc
{
BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
- std::string localized_str;
-
- std::map<std::string, std::string>::const_iterator dictionary_iter;
-
- dictionary_iter = LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.find(mName);
-
- if(dictionary_iter != LLLocalizedInventoryItemsDictionary::getInstance()->mInventoryItemsDict.end())
- {
- mName = dictionary_iter->second;
- }
+ LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);
mIsComplete = TRUE;
return rv;
@@ -567,6 +634,7 @@ bool LLViewerInventoryCategory::fetch()
if((VERSION_UNKNOWN == mVersion)
&& mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads.
{
+ LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL;
const F32 FETCH_TIMER_EXPIRY = 10.0f;
mDescendentsRequested.reset();
mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY);
@@ -584,14 +652,22 @@ bool LLViewerInventoryCategory::fetch()
// AIS folks are aware of the issue and have a fix in process.
// see ticket for details.
- std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
+ std::string url;
+ if (gAgent.getRegion())
+ {
+ url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2");
+ }
+ else
+ {
+ llwarns << "agent region is null" << llendl;
+ }
if (!url.empty()) //Capability found. Build up LLSD and use it.
{
LLInventoryModelBackgroundFetch::instance().start(mUUID, false);
}
else
{ //Deprecated, but if we don't have a capability, use the old system.
- llinfos << "WebFetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl;
+ llinfos << "FetchInventoryDescendents2 capability not found. Using deprecated UDP message." << llendl;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("FetchInventoryDescendents");
msg->nextBlock("AgentData");
@@ -724,8 +800,8 @@ void LLViewerInventoryCategory::determineFolderType()
return;
if (item->isWearableType())
{
- const EWearableType wearable_type = item->getWearableType();
- const std::string& wearable_name = LLWearableDictionary::getTypeName(wearable_type);
+ const LLWearableType::EType wearable_type = item->getWearableType();
+ const std::string& wearable_name = LLWearableType::getTypeName(wearable_type);
U64 valid_folder_types = LLViewerFolderType::lookupValidFolderTypes(wearable_name);
folder_valid |= valid_folder_types;
folder_invalid |= ~valid_folder_types;
@@ -771,6 +847,11 @@ void LLViewerInventoryCategory::changeType(LLFolderType::EType new_folder_type)
gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
}
+void LLViewerInventoryCategory::localizeName()
+{
+ LLLocalizedInventoryItemsDictionary::getInstance()->localizeInventoryObjectName(mName);
+}
+
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
@@ -798,6 +879,21 @@ LLInventoryCallbackManager::~LLInventoryCallbackManager()
sInstance = NULL;
}
+//static
+void LLInventoryCallbackManager::destroyClass()
+{
+ if (sInstance)
+ {
+ for (callback_map_t::iterator it = sInstance->mMap.begin(), end_it = sInstance->mMap.end(); it != end_it; ++it)
+ {
+ // drop LLPointer reference to callback
+ it->second = NULL;
+ }
+ sInstance->mMap.clear();
+ }
+}
+
+
U32 LLInventoryCallbackManager::registerCB(LLPointer<LLInventoryCallback> cb)
{
if (cb.isNull())
@@ -834,19 +930,25 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item)
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
if (item)
{
- wear_inventory_item_on_avatar(item);
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
}
}
void ModifiedCOFCallback::fire(const LLUUID& inv_item)
{
LLAppearanceMgr::instance().updateAppearanceFromCOF();
- if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
+
+ // Start editing the item if previously requested.
+ gAgentWearables.editWearableIfRequested(inv_item);
+
+ // TODO: camera mode may not be changed if a debug setting is tweaked
+ if( gAgentCamera.cameraCustomizeAvatar() )
{
// If we're in appearance editing mode, the current tab may need to be refreshed
- if (gFloaterCustomize)
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
+ if (panel)
{
- gFloaterCustomize->switchToDefaultSubpart();
+ panel->showDefaultSubpart();
}
}
}
@@ -875,6 +977,11 @@ void ActivateGestureCallback::fire(const LLUUID& inv_item)
{
if (inv_item.isNull())
return;
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (!item)
+ return;
+ if (item->getType() != LLAssetType::AT_GESTURE)
+ return;
LLGestureMgr::instance().activateGesture(inv_item);
}
@@ -909,7 +1016,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
const LLUUID& parent, const LLTransactionID& transaction_id,
const std::string& name,
const std::string& desc, LLAssetType::EType asset_type,
- LLInventoryType::EType inv_type, EWearableType wtype,
+ LLInventoryType::EType inv_type, LLWearableType::EType wtype,
U32 next_owner_perm,
LLPointer<LLInventoryCallback> cb)
{
@@ -1072,6 +1179,14 @@ void move_inventory_item(
void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
{
+ if (NULL == src)
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "Null pointer to item was passed for object_id "
+ << object_id << " and notecard_inv_id "
+ << notecard_inv_id << LL_ENDL;
+ return;
+ }
+
LLViewerRegion* viewer_region = NULL;
LLViewerObject* vo = NULL;
if (object_id.notNull() && (vo = gObjectList.findObject(object_id)) != NULL)
@@ -1094,6 +1209,16 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar
return;
}
+ // check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
+ std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
+ if (url.empty())
+ {
+ LL_WARNS("copy_inventory_from_notecard") << "There is no 'CopyInventoryFromNotecard' capability"
+ << " for region: " << viewer_region->getName()
+ << LL_ENDL;
+ return;
+ }
+
LLSD request, body;
body["notecard-id"] = notecard_inv_id;
body["object-id"] = object_id;
@@ -1196,13 +1321,11 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
else
{
// Use for all clothing and body parts. Adding new wearable types requires updating LLWearableDictionary.
- EWearableType wearable_type = LLWearableDictionary::typeNameToType(type_name);
- if (wearable_type >= WT_SHAPE && wearable_type < WT_COUNT)
+ LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name);
+ if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT)
{
- LLAssetType::EType asset_type = LLWearableDictionary::getAssetType(wearable_type);
- LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type);
- const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(folder_type);
- LLFolderBridge::createWearable(parent_id, wearable_type);
+ const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null;
+ LLAgentWearables::createWearable(wearable_type, false, parent_id);
}
else
{
@@ -1303,6 +1426,8 @@ public:
S32 getSortIndex(const LLUUID& inv_item_id);
void removeSortIndex(const LLUUID& inv_item_id);
+ void getSLURL(const LLUUID& asset_id);
+
/**
* Implementation of LLDestroyClass. Calls cleanup() instance method.
*
@@ -1329,9 +1454,20 @@ private:
void load();
void save();
+ void saveFavoritesSLURLs();
+
+ // Remove record of current user's favorites from file on disk.
+ void removeFavoritesRecordOfUser();
+
+ void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
+ void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
typedef std::map<LLUUID, S32> sort_index_map_t;
sort_index_map_t mSortIndexes;
+ typedef std::map<LLUUID, std::string> slurls_map_t;
+ slurls_map_t mSLURLs;
+
bool mIsDirty;
struct IsNotInFavorites
@@ -1386,10 +1522,31 @@ void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
mIsDirty = true;
}
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+ if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+ LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+ boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+ if (lm)
+ {
+ onLandmarkLoaded(asset_id, lm);
+ }
+}
+
// static
void LLFavoritesOrderStorage::destroyClass()
{
LLFavoritesOrderStorage::instance().cleanup();
+ if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+ {
+ LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+ }
+ else
+ {
+ LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+ }
}
void LLFavoritesOrderStorage::load()
@@ -1412,6 +1569,98 @@ void LLFavoritesOrderStorage::load()
}
}
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+ // Do not change the file if we are not logged in yet.
+ if (!LLLoginInstance::getInstance()->authSuccess()) return;
+
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+ if (user_dir.empty()) return;
+
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ llifstream in_file;
+ in_file.open(filename);
+ LLSD fav_llsd;
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, in_file);
+ }
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ LLSD user_llsd;
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
+ {
+ LLSD value;
+ value["name"] = (*it)->getName();
+ value["asset_id"] = (*it)->getAssetUUID();
+
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+ if (slurl_iter != mSLURLs.end())
+ {
+ value["slurl"] = slurl_iter->second;
+ user_llsd[(*it)->getSortField()] = value;
+ }
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ fav_llsd[av_name.getLegacyName()] = user_llsd;
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename);
+ if (!file.is_open()) return;
+ LLSDSerialize::fromXML(fav_llsd, file);
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ if (fav_llsd.has(av_name.getLegacyName()))
+ {
+ fav_llsd.erase(av_name.getLegacyName());
+ }
+
+ llofstream out_file;
+ out_file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+ if (!landmark) return;
+
+ LLVector3d pos_global;
+ if (!landmark->getGlobalPos(pos_global))
+ {
+ // If global position was unknown on first getGlobalPos() call
+ // it should be set for the subsequent calls.
+ landmark->getGlobalPos(pos_global);
+ }
+
+ if (!pos_global.isExactlyZero())
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+ boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+ }
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+ mSLURLs[asset_id] = slurl;
+}
+
void LLFavoritesOrderStorage::save()
{
// nothing to save if clean
@@ -1468,6 +1717,12 @@ S32 LLViewerInventoryItem::getSortField() const
void LLViewerInventoryItem::setSortField(S32 sortField)
{
LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
+ getSLURL();
+}
+
+void LLViewerInventoryItem::getSLURL()
+{
+ LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
}
const LLPermissions& LLViewerInventoryItem::getPermissions() const
@@ -1537,14 +1792,13 @@ bool LLViewerInventoryItem::isWearableType() const
return (getInventoryType() == LLInventoryType::IT_WEARABLE);
}
-EWearableType LLViewerInventoryItem::getWearableType() const
+LLWearableType::EType LLViewerInventoryItem::getWearableType() const
{
if (!isWearableType())
{
- llwarns << "item is not a wearable" << llendl;
- return WT_INVALID;
+ return LLWearableType::WT_INVALID;
}
- return EWearableType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
+ return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
}
@@ -1650,11 +1904,25 @@ bool LLViewerInventoryItem::checkPermissionsSet(PermissionMask mask) const
return ((curr_mask & mask) == mask);
}
+PermissionMask LLViewerInventoryItem::getPermissionMask() const
+{
+ const LLPermissions& permissions = getPermissions();
+
+ BOOL copy = permissions.allowCopyBy(gAgent.getID());
+ BOOL mod = permissions.allowModifyBy(gAgent.getID());
+ BOOL xfer = permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ PermissionMask perm_mask = 0;
+ if (copy) perm_mask |= PERM_COPY;
+ if (mod) perm_mask |= PERM_MODIFY;
+ if (xfer) perm_mask |= PERM_TRANSFER;
+ return perm_mask;
+}
+
//----------
-void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name)
+void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group)
{
- rename(first_name + " " + last_name);
+ rename(name);
gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());
gInventory.notifyObservers();
}