diff options
Diffstat (limited to 'indra/newview')
23 files changed, 1016 insertions, 797 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5c7e9c8db2..bc838e20e4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -74,6 +74,7 @@ set(viewer_SOURCE_FILES      llagentpilot.cpp      llagentui.cpp      llagentwearables.cpp +    llagentwearablesfetch.cpp      llanimstatelabels.cpp      llappearancemgr.cpp      llappviewer.cpp @@ -574,6 +575,7 @@ set(viewer_HEADER_FILES      llagentpilot.h      llagentui.h      llagentwearables.h +    llagentwearablesfetch.h      llanimstatelabels.h      llappearance.h      llappearancemgr.h diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 879408d6e4..02c3dfc6e0 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.0.0.200030"; -CFBundleGetInfoString = "Second Life version 2.0.0.200030, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.0.0.203110"; +CFBundleGetInfoString = "Second Life version 2.0.0.203110, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 38ebb22b84..4cb01a0f33 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>2.0.0.200030</string> +	<string>2.0.0.203110</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 73fb24e4eb..92226f4148 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4609,7 +4609,7 @@      <key>Type</key>      <string>Boolean</string>      <key>Value</key> -    <integer>1</integer> +    <integer>0</integer>    </map>    <key>MediaShowOutsideParcel</key>    <map> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 6e983747b2..0542e73bfd 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -36,6 +36,7 @@  #include "llaccordionctrltab.h"  #include "llagent.h"  #include "llagentcamera.h" +#include "llagentwearablesfetch.h"  #include "llappearancemgr.h"  #include "llcallbacklist.h"  #include "llfloatercustomize.h" @@ -57,77 +58,6 @@  #include <boost/scoped_ptr.hpp> -//-------------------------------------------------------------------- -// Classes for fetching initial wearables data -//-------------------------------------------------------------------- -// Outfit folder fetching callback structure. -class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver -{ -public: -	LLInitialWearablesFetch() {} -	~LLInitialWearablesFetch(); -	virtual void done(); - -	struct InitialWearableData -	{ -		EWearableType mType; -		LLUUID mItemID; -		LLUUID mAssetID; -		InitialWearableData(EWearableType type, LLUUID& itemID, LLUUID& assetID) : -			mType(type), -			mItemID(itemID), -			mAssetID(assetID) -		{} -	}; - -	typedef std::vector<InitialWearableData> initial_wearable_data_vec_t; -	initial_wearable_data_vec_t mCOFInitialWearables; // Wearables from the Current Outfit Folder -	initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg - -protected: -	void processWearablesMessage(); -	void processContents(); -}; - -class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver -{ -public: -	enum ELibraryOutfitFetchStep { -		LOFS_FOLDER = 0, -		LOFS_OUTFITS, -		LOFS_LIBRARY, -		LOFS_IMPORTED, -		LOFS_CONTENTS -	}; -	LLLibraryOutfitsFetch() : mCurrFetchStep(LOFS_FOLDER), mOutfitsPopulated(false)  -	{ -		mMyOutfitsID = LLUUID::null; -		mClothingID = LLUUID::null; -		mLibraryClothingID = LLUUID::null; -		mImportedClothingID = LLUUID::null; -		mImportedClothingName = "Imported Library Clothing"; -	} -	~LLLibraryOutfitsFetch() {} -	virtual void done(); -	void doneIdle(); -	LLUUID mMyOutfitsID; -	void importedFolderFetch(); -protected: -	void folderDone(void); -	void outfitsDone(void); -	void libraryDone(void); -	void importedFolderDone(void); -	void contentsDone(void); -	enum ELibraryOutfitFetchStep mCurrFetchStep; -	uuid_vec_t mLibraryClothingFolders; -	uuid_vec_t mImportedClothingFolders; -	bool mOutfitsPopulated; -	LLUUID mClothingID; -	LLUUID mLibraryClothingID; -	LLUUID mImportedClothingID; -	std::string mImportedClothingName; -}; -  LLAgentWearables gAgentWearables;  BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -1014,8 +944,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs  				// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.  				LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update -				outfit->mAgentInitialWearables.push_back(wearable_data); -				 +				outfit->add(wearable_data);  			}  			lldebugs << "       " << LLWearableDictionary::getTypeLabel(type) << llendl; @@ -2147,463 +2076,3 @@ void LLAgentWearables::populateMyOutfitsFolder(void)  		outfits->done();  	}  } - -void LLLibraryOutfitsFetch::done() -{ -	// Delay this until idle() routine, since it's a heavy operation and -	// we also can't have it run within notifyObservers. -	doOnIdle(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this)); -	gInventory.removeObserver(this); // Prevent doOnIdle from being added twice. -} - -void LLLibraryOutfitsFetch::doneIdle() -{ -	gInventory.addObserver(this); // Add this back in since it was taken out during ::done() -	 -	switch (mCurrFetchStep) -	{ -		case LOFS_FOLDER: -			folderDone(); -			mCurrFetchStep = LOFS_OUTFITS; -			break; -		case LOFS_OUTFITS: -			outfitsDone(); -			mCurrFetchStep = LOFS_LIBRARY; -			break; -		case LOFS_LIBRARY: -			libraryDone(); -			mCurrFetchStep = LOFS_IMPORTED; -			break; -		case LOFS_IMPORTED: -			importedFolderDone(); -			mCurrFetchStep = LOFS_CONTENTS; -			break; -		case LOFS_CONTENTS: -			contentsDone(); -			break; -		default: -			llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl; -			mOutfitsPopulated = TRUE; -			break; -	} - -	// We're completely done.  Cleanup. -	if (mOutfitsPopulated) -	{ -		gInventory.removeObserver(this); -		delete this; -		return; -	} -} - -void LLLibraryOutfitsFetch::folderDone(void) -{ -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t wearable_array; -	gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,  -								  LLInventoryModel::EXCLUDE_TRASH); -	// Early out if we already have items in My Outfits. -	if (cat_array.count() > 0 || wearable_array.count() > 0) -	{ -		mOutfitsPopulated = true; -		return; -	} - -	mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING); -	mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); - -	// If Library->Clothing->Initial Outfits exists, use that. -	LLNameCategoryCollector matchFolderFunctor("Initial Outfits"); -	gInventory.collectDescendentsIf(mLibraryClothingID, -									cat_array, wearable_array,  -									LLInventoryModel::EXCLUDE_TRASH, -									matchFolderFunctor); -	if (cat_array.count() > 0) -	{ -		const LLViewerInventoryCategory *cat = cat_array.get(0); -		mLibraryClothingID = cat->getUUID(); -	} - -	mCompleteFolders.clear(); -	 -	// Get the complete information on the items in the inventory. -	uuid_vec_t folders; -	folders.push_back(mClothingID); -	folders.push_back(mLibraryClothingID); -	fetchDescendents(folders); -	if (isEverythingComplete()) -	{ -		done(); -	} -} - -void LLLibraryOutfitsFetch::outfitsDone(void) -{ -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t wearable_array; -	uuid_vec_t folders; -	 -	// Collect the contents of the Library's Clothing folder -	gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,  -								  LLInventoryModel::EXCLUDE_TRASH); -	 -	llassert(cat_array.count() > 0); -	for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); -		 iter != cat_array.end(); -		 ++iter) -	{ -		const LLViewerInventoryCategory *cat = iter->get(); -		 -		// Get the names and id's of every outfit in the library, skip "Ruth" -		// because it's a low quality legacy outfit -		if (cat->getName() != "Ruth") -		{ -			// Get the name of every outfit in the library  -			folders.push_back(cat->getUUID()); -			mLibraryClothingFolders.push_back(cat->getUUID()); -		} -	} -	cat_array.clear(); -	wearable_array.clear(); - -	// Check if you already have an "Imported Library Clothing" folder -	LLNameCategoryCollector matchFolderFunctor(mImportedClothingName); -	gInventory.collectDescendentsIf(mClothingID,  -									cat_array, wearable_array,  -									LLInventoryModel::EXCLUDE_TRASH, -									matchFolderFunctor); -	if (cat_array.size() > 0) -	{ -		const LLViewerInventoryCategory *cat = cat_array.get(0); -		mImportedClothingID = cat->getUUID(); -	} -	 -	mCompleteFolders.clear(); -	 -	fetchDescendents(folders); -	if (isEverythingComplete()) -	{ -		done(); -	} -} - -class LLLibraryOutfitsCopyDone: public LLInventoryCallback -{ -public: -	LLLibraryOutfitsCopyDone(LLLibraryOutfitsFetch * fetcher): -	mFireCount(0), mLibraryOutfitsFetcher(fetcher) -	{ -	} -	 -	virtual ~LLLibraryOutfitsCopyDone() -	{ -		if (!LLApp::isExiting() && mLibraryOutfitsFetcher) -		{ -			gInventory.addObserver(mLibraryOutfitsFetcher); -			mLibraryOutfitsFetcher->done(); -		} -	} -	 -	/* virtual */ void fire(const LLUUID& inv_item) -	{ -		mFireCount++; -	} -private: -	U32 mFireCount; -	LLLibraryOutfitsFetch * mLibraryOutfitsFetcher; -}; - -// Copy the clothing folders from the library into the imported clothing folder -void LLLibraryOutfitsFetch::libraryDone(void) -{ -	if (mImportedClothingID != LLUUID::null) -	{ -		// Skip straight to fetching the contents of the imported folder -		importedFolderFetch(); -		return; -	} - -	// Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone. -	gInventory.removeObserver(this); -	 -	LLPointer<LLInventoryCallback> copy_waiter = new LLLibraryOutfitsCopyDone(this); -	mImportedClothingID = gInventory.createNewCategory(mClothingID, -													   LLFolderType::FT_NONE, -													   mImportedClothingName); -	// Copy each folder from library into clothing unless it already exists. -	for (uuid_vec_t::const_iterator iter = mLibraryClothingFolders.begin(); -		 iter != mLibraryClothingFolders.end(); -		 ++iter) -	{ -		const LLUUID& src_folder_id = (*iter); // Library clothing folder ID -		const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id); -		if (!cat) -		{ -			llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl; -			continue; -		} -		 -		if (!LLAppearanceMgr::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id)) -		{ -			llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl; -			continue; -		} -		 -		// Don't copy the category if it already exists. -		LLNameCategoryCollector matchFolderFunctor(cat->getName()); -		LLInventoryModel::cat_array_t cat_array; -		LLInventoryModel::item_array_t wearable_array; -		gInventory.collectDescendentsIf(mImportedClothingID,  -										cat_array, wearable_array,  -										LLInventoryModel::EXCLUDE_TRASH, -										matchFolderFunctor); -		if (cat_array.size() > 0) -		{ -			continue; -		} - -		LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID, -															LLFolderType::FT_NONE, -															cat->getName()); -		LLAppearanceMgr::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter); -	} -} - -void LLLibraryOutfitsFetch::importedFolderFetch(void) -{ -	// Fetch the contents of the Imported Clothing Folder -	uuid_vec_t folders; -	folders.push_back(mImportedClothingID); -	 -	mCompleteFolders.clear(); -	 -	fetchDescendents(folders); -	if (isEverythingComplete()) -	{ -		done(); -	} -} - -void LLLibraryOutfitsFetch::importedFolderDone(void) -{ -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t wearable_array; -	uuid_vec_t folders; -	 -	// Collect the contents of the Imported Clothing folder -	gInventory.collectDescendents(mImportedClothingID, cat_array, wearable_array,  -								  LLInventoryModel::EXCLUDE_TRASH); -	 -	for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); -		 iter != cat_array.end(); -		 ++iter) -	{ -		const LLViewerInventoryCategory *cat = iter->get(); -		 -		// Get the name of every imported outfit -		folders.push_back(cat->getUUID()); -		mImportedClothingFolders.push_back(cat->getUUID()); -	} -	 -	mCompleteFolders.clear(); -	fetchDescendents(folders); -	if (isEverythingComplete()) -	{ -		done(); -	} -} - -void LLLibraryOutfitsFetch::contentsDone(void) -{		 -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t wearable_array; -	 -	for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin(); -		 folder_iter != mImportedClothingFolders.end(); -		 ++folder_iter) -	{ -		const LLUUID &folder_id = (*folder_iter); -		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); -		if (!cat) -		{ -			llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl; -			continue; -		} -		 -		// First, make a folder in the My Outfits directory. -		LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName()); -		 -		cat_array.clear(); -		wearable_array.clear(); -		// Collect the contents of each imported clothing folder, so we can create new outfit links for it -		gInventory.collectDescendents(folder_id, cat_array, wearable_array,  -									  LLInventoryModel::EXCLUDE_TRASH); -		 -		for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin(); -			 wearable_iter != wearable_array.end(); -			 ++wearable_iter) -		{ -			const LLViewerInventoryItem *item = wearable_iter->get(); -			link_inventory_item(gAgent.getID(), -								item->getLinkedUUID(), -								new_outfit_folder_id, -								item->getName(), -								LLAssetType::AT_LINK, -								NULL); -		} -	} - -	mOutfitsPopulated = true; -} - -//-------------------------------------------------------------------- -// InitialWearablesFetch -//  -// This grabs contents from the COF and processes them. -// The processing is handled in idle(), i.e. outside of done(), -// to avoid gInventory.notifyObservers recursion. -//-------------------------------------------------------------------- - -LLInitialWearablesFetch::~LLInitialWearablesFetch() -{ -} - -// virtual -void LLInitialWearablesFetch::done() -{ -	// Delay processing the actual results of this so it's not handled within -	// gInventory.notifyObservers.  The results will be handled in the next -	// idle tick instead. -	gInventory.removeObserver(this); -	doOnIdle(boost::bind(&LLInitialWearablesFetch::processContents,this)); -} - -void LLInitialWearablesFetch::processContents() -{ -	// Fetch the wearable items from the Current Outfit Folder -	LLInventoryModel::cat_array_t cat_array; -	LLInventoryModel::item_array_t wearable_array; -	LLFindWearables is_wearable; -	gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array,  -									LLInventoryModel::EXCLUDE_TRASH, is_wearable); - -	LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); -	if (wearable_array.count() > 0) -	{ -		LLAppearanceMgr::instance().updateAppearanceFromCOF(); -	} -	else -	{ -		// if we're constructing the COF from the wearables message, we don't have a proper outfit link -		LLAppearanceMgr::instance().setOutfitDirty(true); -		processWearablesMessage(); -	} -	delete this; -} - -class LLFetchAndLinkObserver: public LLInventoryFetchObserver -{ -public: -	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): -		m_ids(ids), -		LLInventoryFetchObserver(true) // retry for missing items -	{ -	} -	~LLFetchAndLinkObserver() -	{ -	} -	virtual void done() -	{ -		gInventory.removeObserver(this); - -		// Link to all fetched items in COF. -		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; -		for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); -			 it != m_ids.end(); -			 ++it) -		{ -			LLUUID id = *it; -			LLViewerInventoryItem *item = gInventory.getItem(*it); -			if (!item) -			{ -				llwarns << "fetch failed!" << llendl; -				continue; -			} - -			link_inventory_item(gAgent.getID(), -								item->getLinkedUUID(), -								LLAppearanceMgr::instance().getCOF(), -								item->getName(), -								LLAssetType::AT_LINK, -								link_waiter); -		} -	} -private: -	LLInventoryFetchObserver::item_ref_t m_ids; -}; - -void LLInitialWearablesFetch::processWearablesMessage() -{ -	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead. -	{ -		const LLUUID current_outfit_id = LLAppearanceMgr::instance().getCOF(); -		LLInventoryFetchObserver::item_ref_t ids; -		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i) -		{ -			// Populate the current outfit folder with links to the wearables passed in the message -			InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback. -			 -			if (wearable_data->mAssetID.notNull()) -			{ -				ids.push_back(wearable_data->mItemID); -			} -			else -			{ -				llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID " -				<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl; -				delete wearable_data; -			} -		} - -		// Add all current attachments to the requested items as well. -		if (isAgentAvatarValid()) -		{ -			for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();  -				 iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) -			{ -				LLViewerJointAttachment* attachment = iter->second; -				if (!attachment) continue; -				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -					 attachment_iter != attachment->mAttachedObjects.end(); -					 ++attachment_iter) -				{ -					LLViewerObject* attached_object = (*attachment_iter); -					if (!attached_object) continue; -					const LLUUID& item_id = attached_object->getItemID(); -					if (item_id.isNull()) continue; -					ids.push_back(item_id); -				} -			} -		} - -		// Need to fetch the inventory items for ids, then create links to them after they arrive. -		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids); -		fetcher->fetchItems(ids); -		// If no items to be fetched, done will never be triggered. -		// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition. -		if (fetcher->isEverythingComplete()) -		{ -			fetcher->done(); -		} -		else -		{ -			gInventory.addObserver(fetcher); -		} -	} -	else -	{ -		LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL; -	} -} - - diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp new file mode 100644 index 0000000000..45274a8e2c --- /dev/null +++ b/indra/newview/llagentwearablesfetch.cpp @@ -0,0 +1,516 @@ +/**  + * @file llagentwearablesfetch.cpp + * @brief LLAgentWearblesFetch class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * 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 + *  + * 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 + *  + * 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. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llagentwearablesfetch.h" + +#include "llagent.h" +#include "llagentwearables.h" +#include "llappearancemgr.h" +#include "llinventoryfunctions.h" +#include "llvoavatarself.h" + +LLInitialWearablesFetch::LLInitialWearablesFetch() +{ +} + +LLInitialWearablesFetch::~LLInitialWearablesFetch() +{ +} + +// virtual +void LLInitialWearablesFetch::done() +{ +	// Delay processing the actual results of this so it's not handled within +	// gInventory.notifyObservers.  The results will be handled in the next +	// idle tick instead. +	gInventory.removeObserver(this); +	doOnIdle(boost::bind(&LLInitialWearablesFetch::processContents,this)); +} + +void LLInitialWearablesFetch::add(InitialWearableData &data) + +{ +	mAgentInitialWearables.push_back(data); +} + +void LLInitialWearablesFetch::processContents() +{ +	// Fetch the wearable items from the Current Outfit Folder +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	LLFindWearables is_wearable; +	gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array,  +									LLInventoryModel::EXCLUDE_TRASH, is_wearable); + +	LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); +	if (wearable_array.count() > 0) +	{ +		LLAppearanceMgr::instance().updateAppearanceFromCOF(); +	} +	else +	{ +		// if we're constructing the COF from the wearables message, we don't have a proper outfit link +		LLAppearanceMgr::instance().setOutfitDirty(true); +		processWearablesMessage(); +	} +	delete this; +} + +class LLFetchAndLinkObserver: public LLInventoryFetchObserver +{ +public: +	LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids): +		m_ids(ids), +		LLInventoryFetchObserver(true) // retry for missing items +	{ +	} +	~LLFetchAndLinkObserver() +	{ +	} +	virtual void done() +	{ +		gInventory.removeObserver(this); + +		// Link to all fetched items in COF. +		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; +		for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin(); +			 it != m_ids.end(); +			 ++it) +		{ +			LLUUID id = *it; +			LLViewerInventoryItem *item = gInventory.getItem(*it); +			if (!item) +			{ +				llwarns << "fetch failed!" << llendl; +				continue; +			} + +			link_inventory_item(gAgent.getID(), +								item->getLinkedUUID(), +								LLAppearanceMgr::instance().getCOF(), +								item->getName(), +								LLAssetType::AT_LINK, +								link_waiter); +		} +	} +private: +	LLInventoryFetchObserver::item_ref_t m_ids; +}; + +void LLInitialWearablesFetch::processWearablesMessage() +{ +	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead. +	{ +		const LLUUID current_outfit_id = LLAppearanceMgr::instance().getCOF(); +		LLInventoryFetchObserver::item_ref_t ids; +		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i) +		{ +			// Populate the current outfit folder with links to the wearables passed in the message +			InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback. +			 +			if (wearable_data->mAssetID.notNull()) +			{ +				ids.push_back(wearable_data->mItemID); +			} +			else +			{ +				llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID " +				<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl; +				delete wearable_data; +			} +		} + +		// Add all current attachments to the requested items as well. +		if (isAgentAvatarValid()) +		{ +			for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();  +				 iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) +			{ +				LLViewerJointAttachment* attachment = iter->second; +				if (!attachment) continue; +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter) +				{ +					LLViewerObject* attached_object = (*attachment_iter); +					if (!attached_object) continue; +					const LLUUID& item_id = attached_object->getItemID(); +					if (item_id.isNull()) continue; +					ids.push_back(item_id); +				} +			} +		} + +		// Need to fetch the inventory items for ids, then create links to them after they arrive. +		LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids); +		fetcher->fetchItems(ids); +		// If no items to be fetched, done will never be triggered. +		// TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition. +		if (fetcher->isEverythingComplete()) +		{ +			fetcher->done(); +		} +		else +		{ +			gInventory.addObserver(fetcher); +		} +	} +	else +	{ +		LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL; +	} +} + +LLLibraryOutfitsFetch::LLLibraryOutfitsFetch() :  +	mCurrFetchStep(LOFS_FOLDER),  +	mOutfitsPopulated(false)  +{ +	mMyOutfitsID = LLUUID::null; +	mClothingID = LLUUID::null; +	mLibraryClothingID = LLUUID::null; +	mImportedClothingID = LLUUID::null; +	mImportedClothingName = "Imported Library Clothing"; +} + +LLLibraryOutfitsFetch::~LLLibraryOutfitsFetch() +{ +} + +void LLLibraryOutfitsFetch::done() +{ +	// Delay this until idle() routine, since it's a heavy operation and +	// we also can't have it run within notifyObservers. +	doOnIdle(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this)); +	gInventory.removeObserver(this); // Prevent doOnIdle from being added twice. +} + +void LLLibraryOutfitsFetch::doneIdle() +{ +	gInventory.addObserver(this); // Add this back in since it was taken out during ::done() +	 +	switch (mCurrFetchStep) +	{ +		case LOFS_FOLDER: +			folderDone(); +			mCurrFetchStep = LOFS_OUTFITS; +			break; +		case LOFS_OUTFITS: +			outfitsDone(); +			mCurrFetchStep = LOFS_LIBRARY; +			break; +		case LOFS_LIBRARY: +			libraryDone(); +			mCurrFetchStep = LOFS_IMPORTED; +			break; +		case LOFS_IMPORTED: +			importedFolderDone(); +			mCurrFetchStep = LOFS_CONTENTS; +			break; +		case LOFS_CONTENTS: +			contentsDone(); +			break; +		default: +			llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl; +			mOutfitsPopulated = TRUE; +			break; +	} + +	// We're completely done.  Cleanup. +	if (mOutfitsPopulated) +	{ +		gInventory.removeObserver(this); +		delete this; +		return; +	} +} + +void LLLibraryOutfitsFetch::folderDone(void) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,  +								  LLInventoryModel::EXCLUDE_TRASH); +	// Early out if we already have items in My Outfits. +	if (cat_array.count() > 0 || wearable_array.count() > 0) +	{ +		mOutfitsPopulated = true; +		return; +	} + +	mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING); +	mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true); + +	// If Library->Clothing->Initial Outfits exists, use that. +	LLNameCategoryCollector matchFolderFunctor("Initial Outfits"); +	gInventory.collectDescendentsIf(mLibraryClothingID, +									cat_array, wearable_array,  +									LLInventoryModel::EXCLUDE_TRASH, +									matchFolderFunctor); +	if (cat_array.count() > 0) +	{ +		const LLViewerInventoryCategory *cat = cat_array.get(0); +		mLibraryClothingID = cat->getUUID(); +	} + +	mCompleteFolders.clear(); +	 +	// Get the complete information on the items in the inventory. +	uuid_vec_t folders; +	folders.push_back(mClothingID); +	folders.push_back(mLibraryClothingID); +	fetchDescendents(folders); +	if (isEverythingComplete()) +	{ +		done(); +	} +} + +void LLLibraryOutfitsFetch::outfitsDone(void) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	uuid_vec_t folders; +	 +	// Collect the contents of the Library's Clothing folder +	gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,  +								  LLInventoryModel::EXCLUDE_TRASH); +	 +	llassert(cat_array.count() > 0); +	for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); +		 iter != cat_array.end(); +		 ++iter) +	{ +		const LLViewerInventoryCategory *cat = iter->get(); +		 +		// Get the names and id's of every outfit in the library, skip "Ruth" +		// because it's a low quality legacy outfit +		if (cat->getName() != "Ruth") +		{ +			// Get the name of every outfit in the library  +			folders.push_back(cat->getUUID()); +			mLibraryClothingFolders.push_back(cat->getUUID()); +		} +	} +	cat_array.clear(); +	wearable_array.clear(); + +	// Check if you already have an "Imported Library Clothing" folder +	LLNameCategoryCollector matchFolderFunctor(mImportedClothingName); +	gInventory.collectDescendentsIf(mClothingID,  +									cat_array, wearable_array,  +									LLInventoryModel::EXCLUDE_TRASH, +									matchFolderFunctor); +	if (cat_array.size() > 0) +	{ +		const LLViewerInventoryCategory *cat = cat_array.get(0); +		mImportedClothingID = cat->getUUID(); +	} +	 +	mCompleteFolders.clear(); +	 +	fetchDescendents(folders); +	if (isEverythingComplete()) +	{ +		done(); +	} +} + +class LLLibraryOutfitsCopyDone: public LLInventoryCallback +{ +public: +	LLLibraryOutfitsCopyDone(LLLibraryOutfitsFetch * fetcher): +	mFireCount(0), mLibraryOutfitsFetcher(fetcher) +	{ +	} +	 +	virtual ~LLLibraryOutfitsCopyDone() +	{ +		if (!LLApp::isExiting() && mLibraryOutfitsFetcher) +		{ +			gInventory.addObserver(mLibraryOutfitsFetcher); +			mLibraryOutfitsFetcher->done(); +		} +	} +	 +	/* virtual */ void fire(const LLUUID& inv_item) +	{ +		mFireCount++; +	} +private: +	U32 mFireCount; +	LLLibraryOutfitsFetch * mLibraryOutfitsFetcher; +}; + +// Copy the clothing folders from the library into the imported clothing folder +void LLLibraryOutfitsFetch::libraryDone(void) +{ +	if (mImportedClothingID != LLUUID::null) +	{ +		// Skip straight to fetching the contents of the imported folder +		importedFolderFetch(); +		return; +	} + +	// Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone. +	gInventory.removeObserver(this); +	 +	LLPointer<LLInventoryCallback> copy_waiter = new LLLibraryOutfitsCopyDone(this); +	mImportedClothingID = gInventory.createNewCategory(mClothingID, +													   LLFolderType::FT_NONE, +													   mImportedClothingName); +	// Copy each folder from library into clothing unless it already exists. +	for (uuid_vec_t::const_iterator iter = mLibraryClothingFolders.begin(); +		 iter != mLibraryClothingFolders.end(); +		 ++iter) +	{ +		const LLUUID& src_folder_id = (*iter); // Library clothing folder ID +		const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id); +		if (!cat) +		{ +			llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl; +			continue; +		} +		 +		if (!LLAppearanceMgr::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id)) +		{ +			llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl; +			continue; +		} +		 +		// Don't copy the category if it already exists. +		LLNameCategoryCollector matchFolderFunctor(cat->getName()); +		LLInventoryModel::cat_array_t cat_array; +		LLInventoryModel::item_array_t wearable_array; +		gInventory.collectDescendentsIf(mImportedClothingID,  +										cat_array, wearable_array,  +										LLInventoryModel::EXCLUDE_TRASH, +										matchFolderFunctor); +		if (cat_array.size() > 0) +		{ +			continue; +		} + +		LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID, +															LLFolderType::FT_NONE, +															cat->getName()); +		LLAppearanceMgr::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter); +	} +} + +void LLLibraryOutfitsFetch::importedFolderFetch(void) +{ +	// Fetch the contents of the Imported Clothing Folder +	uuid_vec_t folders; +	folders.push_back(mImportedClothingID); +	 +	mCompleteFolders.clear(); +	 +	fetchDescendents(folders); +	if (isEverythingComplete()) +	{ +		done(); +	} +} + +void LLLibraryOutfitsFetch::importedFolderDone(void) +{ +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	uuid_vec_t folders; +	 +	// Collect the contents of the Imported Clothing folder +	gInventory.collectDescendents(mImportedClothingID, cat_array, wearable_array,  +								  LLInventoryModel::EXCLUDE_TRASH); +	 +	for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin(); +		 iter != cat_array.end(); +		 ++iter) +	{ +		const LLViewerInventoryCategory *cat = iter->get(); +		 +		// Get the name of every imported outfit +		folders.push_back(cat->getUUID()); +		mImportedClothingFolders.push_back(cat->getUUID()); +	} +	 +	mCompleteFolders.clear(); +	fetchDescendents(folders); +	if (isEverythingComplete()) +	{ +		done(); +	} +} + +void LLLibraryOutfitsFetch::contentsDone(void) +{		 +	LLInventoryModel::cat_array_t cat_array; +	LLInventoryModel::item_array_t wearable_array; +	 +	for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin(); +		 folder_iter != mImportedClothingFolders.end(); +		 ++folder_iter) +	{ +		const LLUUID &folder_id = (*folder_iter); +		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); +		if (!cat) +		{ +			llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl; +			continue; +		} +		 +		// First, make a folder in the My Outfits directory. +		LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName()); +		 +		cat_array.clear(); +		wearable_array.clear(); +		// Collect the contents of each imported clothing folder, so we can create new outfit links for it +		gInventory.collectDescendents(folder_id, cat_array, wearable_array,  +									  LLInventoryModel::EXCLUDE_TRASH); +		 +		for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin(); +			 wearable_iter != wearable_array.end(); +			 ++wearable_iter) +		{ +			const LLViewerInventoryItem *item = wearable_iter->get(); +			link_inventory_item(gAgent.getID(), +								item->getLinkedUUID(), +								new_outfit_folder_id, +								item->getName(), +								LLAssetType::AT_LINK, +								NULL); +		} +	} + +	mOutfitsPopulated = true; +} + diff --git a/indra/newview/llagentwearablesfetch.h b/indra/newview/llagentwearablesfetch.h new file mode 100644 index 0000000000..72063114b8 --- /dev/null +++ b/indra/newview/llagentwearablesfetch.h @@ -0,0 +1,118 @@ +/**  + * @file llagentwearablesinitialfetch.h + * @brief LLAgentWearablesInitialFetch class header file + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + *  + * Copyright (c) 2000-2009, Linden Research, Inc. + *  + * 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 + *  + * 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 + *  + * 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. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAGENTWEARABLESINITIALFETCH_H +#define LL_LLAGENTWEARABLESINITIALFETCH_H + +#include "llinventoryobserver.h" +#include "llwearabledictionary.h" +#include "lluuid.h" + +//-------------------------------------------------------------------- +// InitialWearablesFetch +//  +// This grabs contents from the COF and processes them. +// The processing is handled in idle(), i.e. outside of done(), +// to avoid gInventory.notifyObservers recursion. +//-------------------------------------------------------------------- +class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver +{ +public: +	LLInitialWearablesFetch(); +	~LLInitialWearablesFetch(); +	virtual void done(); + +	struct InitialWearableData +	{ +		EWearableType mType; +		LLUUID mItemID; +		LLUUID mAssetID; +		InitialWearableData(EWearableType type, LLUUID& itemID, LLUUID& assetID) : +			mType(type), +			mItemID(itemID), +			mAssetID(assetID) +		{} +	}; + +	void add(InitialWearableData &data); + +protected: +	void processWearablesMessage(); +	void processContents(); + +private: +	typedef std::vector<InitialWearableData> initial_wearable_data_vec_t; +	initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg +}; + +//-------------------------------------------------------------------- +// InitialWearablesFetch +//  +// This grabs outfits from the Library and copies those over to the user's +// outfits folder, typically during first-ever login. +//-------------------------------------------------------------------- +class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver +{ +public: +	enum ELibraryOutfitFetchStep +	{ +		LOFS_FOLDER = 0, +		LOFS_OUTFITS, +		LOFS_LIBRARY, +		LOFS_IMPORTED, +		LOFS_CONTENTS +	}; + +	LLLibraryOutfitsFetch(); +	~LLLibraryOutfitsFetch(); + +	virtual void done(); +	void doneIdle(); +	LLUUID mMyOutfitsID; +	void importedFolderFetch(); +protected: +	void folderDone(void); +	void outfitsDone(void); +	void libraryDone(void); +	void importedFolderDone(void); +	void contentsDone(void); +	enum ELibraryOutfitFetchStep mCurrFetchStep; +	uuid_vec_t mLibraryClothingFolders; +	uuid_vec_t mImportedClothingFolders; +	bool mOutfitsPopulated; +	LLUUID mClothingID; +	LLUUID mLibraryClothingID; +	LLUUID mImportedClothingID; +	std::string mImportedClothingName; +}; + +#endif // LL_AGENTWEARABLESINITIALFETCH_H diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 8c7899af3e..18db60705b 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -31,15 +31,14 @@   */  #include "llviewerprecompiledheaders.h" -  #include "llfloateravatartextures.h" +#include "llagent.h" +#include "llagentwearables.h"  #include "lltexturectrl.h" -  #include "lluictrlfactory.h"  #include "llviewerobjectlist.h"  #include "llvoavatar.h" -#include "llagentwearables.h"  using namespace LLVOAvatarDefines; @@ -75,7 +74,6 @@ void LLFloaterAvatarTextures::draw()  	LLFloater::draw();  } -#if !LL_RELEASE_FOR_DOWNLOAD  static void update_texture_ctrl(LLVOAvatar* avatarp,  								 LLTextureCtrl* ctrl,  								 ETextureIndex te) @@ -132,72 +130,68 @@ static LLVOAvatar* find_avatar(const LLUUID& id)  void LLFloaterAvatarTextures::refresh()  { -	LLVOAvatar *avatarp = find_avatar(mID); -	if (avatarp) +	if (gAgent.isGodlike())  	{ -		std::string fullname; -		if (gCacheName->getFullName(avatarp->getID(), fullname)) +		LLVOAvatar *avatarp = find_avatar(mID); +		if (avatarp)  		{ -			setTitle(mTitle + ": " + fullname); +			std::string fullname; +			if (gCacheName->getFullName(avatarp->getID(), fullname)) +			{ +				setTitle(mTitle + ": " + fullname); +			} +			for (U32 i=0; i < TEX_NUM_INDICES; i++) +			{ +				update_texture_ctrl(avatarp, mTextures[i], ETextureIndex(i)); +			}  		} -		for (U32 i=0; i < TEX_NUM_INDICES; i++) +		else  		{ -			update_texture_ctrl(avatarp, mTextures[i], ETextureIndex(i)); +			setTitle(mTitle + ": " + getString("InvalidAvatar") + " (" + mID.asString() + ")");  		}  	} -	else -	{ -		setTitle(mTitle + ": " + getString("InvalidAvatar") + " (" + mID.asString() + ")"); -	}  } -#else - -void LLFloaterAvatarTextures::refresh() -{ -} - -#endif -  // static  void LLFloaterAvatarTextures::onClickDump(void* data)  { -#if !LL_RELEASE_FOR_DOWNLOAD -	LLFloaterAvatarTextures* self = (LLFloaterAvatarTextures*)data; -	LLVOAvatar* avatarp = find_avatar(self->mID); -	if (!avatarp) return; - -	for (S32 i = 0; i < avatarp->getNumTEs(); i++) +	if (gAgent.isGodlike())  	{ -		const LLTextureEntry* te = avatarp->getTE(i); -		if (!te) continue; +		LLFloaterAvatarTextures* self = (LLFloaterAvatarTextures*)data; +		LLVOAvatar* avatarp = find_avatar(self->mID); +		if (!avatarp) return; -		if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i)) +		for (S32 i = 0; i < avatarp->getNumTEs(); i++)  		{ -			LLUUID id = IMG_DEFAULT_AVATAR; -			EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i); -			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); -			if (wearable) +			const LLTextureEntry* te = avatarp->getTE(i); +			if (!te) continue; + +			if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))  			{ -				LLLocalTextureObject *lto = wearable->getLocalTextureObject(i); -				if (lto) +				LLUUID id = IMG_DEFAULT_AVATAR; +				EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i); +				LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0); +				if (wearable)  				{ -					id = lto->getID(); +					LLLocalTextureObject *lto = wearable->getLocalTextureObject(i); +					if (lto) +					{ +						id = lto->getID(); +					} +				} +				if (id != IMG_DEFAULT_AVATAR) +				{ +					llinfos << "Avatar TE " << i << " id " << id << llendl; +				} +				else +				{ +					llinfos << "Avatar TE " << i << " id " << "<DEFAULT>" << llendl;  				} -			} -			if (id != IMG_DEFAULT_AVATAR) -			{ -				llinfos << "Avatar TE " << i << " id " << id << llendl;  			}  			else  			{ -				llinfos << "Avatar TE " << i << " id " << "<DEFAULT>" << llendl; +				llinfos << "Avatar TE " << i << " id " << te->getID() << llendl;  			}  		} -		else -		{ -			llinfos << "Avatar TE " << i << " id " << te->getID() << llendl; -		}  	} -#endif  } diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index ecbaac5743..c916e4b98c 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -437,11 +437,8 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)  S32 LLFolderViewItem::getItemHeight()  { -	if (mHidden) return 0; +	if (getHidden()) return 0; -	//S32 icon_height = mIcon->getHeight(); -	//S32 label_height = llround(getLabelFontForStyle(mLabelStyle)->getLineHeight()); -	//return llmax( icon_height, label_height ) + ICON_PAD;  	return mItemHeight;  } @@ -824,32 +821,34 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	return handled;  } -  void LLFolderViewItem::draw()  { -	if (mHidden) return; +	if (getHidden()) +	{ +		return; +	}  	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);  	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);  	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); -	static LLUIColor sFocusOutlineColor = -		LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); +	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);  	static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);  	static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);  	static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE);  	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); -  	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();  	const S32 TOP_PAD = default_params.item_top_pad; +	const S32 FOCUS_LEFT = 1; +	const LLFontGL* font = getLabelFontForStyle(mLabelStyle); -	bool possibly_has_children = false; -	bool up_to_date = mListener && mListener->isUpToDate(); -	if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter... -		(!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter) -	{ -		possibly_has_children = true; -	} -	if(/*mControlLabel[0] != '\0' && */possibly_has_children) + +	//--------------------------------------------------------------------------------// +	// Draw open folder arrow +	// +	const bool up_to_date = mListener && mListener->isUpToDate(); +	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter... +										(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter) +	if (possibly_has_children)  	{  		LLUIImage* arrow_image = default_params.folder_arrow_image;  		gl_draw_scaled_rotated_image( @@ -857,22 +856,16 @@ void LLFolderViewItem::draw()  			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);  	} -	// See also LLFolderView::updateRenamerPosition() -	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); - -	LLFontGL* font = getLabelFontForStyle(mLabelStyle); - -	// If we have keyboard focus, draw selection filled -	BOOL show_context = getRoot()->getShowSelectionContext(); -	BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); -	const S32 FOCUS_LEFT = 1; -	S32 focus_top = getRect().getHeight(); -	S32 focus_bottom = getRect().getHeight() - mItemHeight; -	bool folder_open = (getRect().getHeight() > mItemHeight + 4); -	// always render "current" item, only render other selected items if -	// mShowSingleSelection is FALSE -	if( mIsSelected ) +	//--------------------------------------------------------------------------------// +	// Draw highlight for selected items +	// +	const BOOL show_context = getRoot()->getShowSelectionContext(); +	const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled +	const S32 focus_top = getRect().getHeight(); +	const S32 focus_bottom = getRect().getHeight() - mItemHeight; +	const bool folder_open = (getRect().getHeight() > mItemHeight + 4); +	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE  	{  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		LLColor4 bg_color = sHighlightBgColor; @@ -891,152 +884,169 @@ void LLFolderViewItem::draw()  				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);  			}  		} - -		gl_rect_2d( -			FOCUS_LEFT, -			focus_top,  -			getRect().getWidth() - 2, -			focus_bottom, -			bg_color, filled); +		gl_rect_2d(FOCUS_LEFT, +				   focus_top,  +				   getRect().getWidth() - 2, +				   focus_bottom, +				   bg_color, filled);  		if (mIsCurSelection)  		{ -			gl_rect_2d( -				FOCUS_LEFT,  -				focus_top,  -				getRect().getWidth() - 2, -				focus_bottom, -				sFocusOutlineColor, FALSE); +			gl_rect_2d(FOCUS_LEFT,  +					   focus_top,  +					   getRect().getWidth() - 2, +					   focus_bottom, +					   sFocusOutlineColor, FALSE);  		}  		if (folder_open)  		{ -			gl_rect_2d( -				FOCUS_LEFT, -				focus_bottom + 1, // overlap with bottom edge of above rect -				getRect().getWidth() - 2, -				0, -				sFocusOutlineColor, FALSE); +			gl_rect_2d(FOCUS_LEFT, +					   focus_bottom + 1, // overlap with bottom edge of above rect +					   getRect().getWidth() - 2, +					   0, +					   sFocusOutlineColor, FALSE);  			if (show_context)  			{ -				gl_rect_2d( -					FOCUS_LEFT, -					focus_bottom + 1, -					getRect().getWidth() - 2, -					0, -					sHighlightBgColor, TRUE); +				gl_rect_2d(FOCUS_LEFT, +						   focus_bottom + 1, +						   getRect().getWidth() - 2, +						   0, +						   sHighlightBgColor, TRUE);  			}  		}  	} + +	//--------------------------------------------------------------------------------// +	// Draw DragNDrop highlight +	//  	if (mDragAndDropTarget)  	{  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		gl_rect_2d( -			FOCUS_LEFT,  -			focus_top,  -			getRect().getWidth() - 2, -			focus_bottom, -			sHighlightBgColor, FALSE); +		gl_rect_2d(FOCUS_LEFT,  +				   focus_top,  +				   getRect().getWidth() - 2, +				   focus_bottom, +				   sHighlightBgColor, FALSE);  		if (folder_open)  		{ -			gl_rect_2d( -				FOCUS_LEFT, -				focus_bottom + 1, // overlap with bottom edge of above rect -				getRect().getWidth() - 2, -				0, -				sHighlightBgColor, FALSE); +			gl_rect_2d(FOCUS_LEFT, +					   focus_bottom + 1, // overlap with bottom edge of above rect +					   getRect().getWidth() - 2, +					   0, +					   sHighlightBgColor, FALSE);  		}  		mDragAndDropTarget = FALSE;  	} -	S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD; -	// First case is used for open folders -	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) +	 +	//--------------------------------------------------------------------------------// +	// Draw open icon +	// +	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD; +	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders   	{  		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);  	} -	else if(mIcon) +	else if (mIcon)  	{   		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);   	} -	if (!mLabel.empty()) + +	//--------------------------------------------------------------------------------// +	// Exit if no label to draw +	// +	if (mLabel.empty())  	{ -		// highlight filtered text -		BOOL debug_filters = getRoot()->getDebugFilters(); -		LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); -		F32 right_x; -		F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; +		return; +	} -		if (debug_filters) -		{ -			if (!getFiltered() && !possibly_has_children) -			{ -				color.mV[VALPHA] *= 0.5f; -			} +	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor; +	F32 right_x  = 0; +	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; +	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation); -			LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); -			LLFontGL::getFontMonospace()->renderUTF8( -				mStatusText, 0, text_left, y, filter_color, -				LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -				S32_MAX, S32_MAX, &right_x, FALSE ); -			text_left = right_x; +	//--------------------------------------------------------------------------------// +	// Highlight filtered text +	// +	if (getRoot()->getDebugFilters()) +	{ +		if (!getFiltered() && !possibly_has_children) +		{ +			color.mV[VALPHA] *= 0.5f;  		} +		LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ?  +			LLColor4(0.5f, 0.8f, 0.5f, 1.f) :  +			LLColor4(0.8f, 0.5f, 0.5f, 1.f); +		LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color, +												 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, +												 S32_MAX, S32_MAX, &right_x, FALSE ); +		text_left = right_x; +	} -		font->renderUTF8( mLabel, 0, text_left, y, color, -						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -						  S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE); +	//--------------------------------------------------------------------------------// +	// Draw the actual label text +	// +	font->renderUTF8(mLabel, 0, text_left, y, color, +					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, +					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE); -//		LLViewerInventoryCategory *item = 0; -//		if (getListener()) -//			item = gInventory.getCategory(getListener()->getUUID()); -		bool root_is_loading = false; -		if (getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(),gInventory.getRootFolderID())) -		{ -			// Descendent of my inventory. -			root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); -		} -		if (getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(),gInventory.getLibraryRootFolderID())) -		{ -			// Descendent of library -			root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); -		} -			 -		if ( (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) -			|| (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && mShowLoadStatus) ) -		{ -			std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) "; -			font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, -					  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE); -		} +	//--------------------------------------------------------------------------------// +	// Draw "Loading..." text +	// +	bool root_is_loading = false; +	if (getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(),  +														 gInventory.getRootFolderID())) // Descendent of my inventory +	{ +		root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();  +	} +	if (getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(),  +														 gInventory.getLibraryRootFolderID())) // Descendent of library +	{ +		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress(); +	} +	if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) || +		(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden))) +	{ +		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) "; +		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, +						 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  +						 S32_MAX, S32_MAX, &right_x, FALSE); +	} -		if (!mLabelSuffix.empty()) -		{ -			font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, -					   LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -				S32_MAX, S32_MAX, &right_x, FALSE ); -		} +	//--------------------------------------------------------------------------------// +	// Draw label suffix +	// +	if (!mLabelSuffix.empty()) +	{ +		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, +						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, +						  S32_MAX, S32_MAX, &right_x, FALSE ); +	} -		if (mStringMatchOffset != std::string::npos) +	//--------------------------------------------------------------------------------// +	// Highlight string match +	// +	if (mStringMatchOffset != std::string::npos) +	{ +		// don't draw backgrounds for zero-length strings +		S32 filter_string_length = getRoot()->getFilterSubString().size(); +		if (filter_string_length > 0)  		{ -			// don't draw backgrounds for zero-length strings -			S32 filter_string_length = getRoot()->getFilterSubString().size(); -			if (filter_string_length > 0) -			{ -				std::string combined_string = mLabel + mLabelSuffix; -				S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1; -				S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; -				S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); -				S32 top = getRect().getHeight() - TOP_PAD; +			std::string combined_string = mLabel + mLabelSuffix; +			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1; +			S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; +			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); +			S32 top = getRect().getHeight() - TOP_PAD; -				LLUIImage* box_image = default_params.selection_image; -				LLRect box_rect(left, top, right, bottom); -				box_image->draw(box_rect, sFilterBGColor); -				F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset); -				F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; -				font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy, -								  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -								  filter_string_length, S32_MAX, &right_x, FALSE ); -			} +			LLUIImage* box_image = default_params.selection_image; +			LLRect box_rect(left, top, right, bottom); +			box_image->draw(box_rect, sFilterBGColor); +			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset); +			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD; +			font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy, +							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, +							  filter_string_length, S32_MAX, &right_x, FALSE );  		}  	}  } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 604af3d074..0fbf3148ac 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -31,10 +31,12 @@   */  #include "llviewerprecompiledheaders.h" +#include "llinventorybridge.h" +  // external projects  #include "lltransfersourceasset.h" -#include "llinventorybridge.h" +  #include "llagent.h"  #include "llagentcamera.h" @@ -594,7 +596,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,  				LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);  				if (inv_item)  				{ -					is_asset_knowable = is_asset_id_knowable(inv_item->getType()); +					is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType());  				}  				if ( !is_asset_knowable // disable menu item for Inventory items with unknown asset. EXT-5308  					 || (! ( isItemPermissive() || gAgent.isGodlike() ) ) @@ -1923,50 +1925,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,  	return accept;  } -bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, -									 LLInventoryItem* item) -{ -	// Valid COF items are: -	// - links to wearables (body parts or clothing) -	// - links to attachments -	// - links to gestures -	// - links to ensemble folders -	LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); -	if (linked_item) -	{ -		LLAssetType::EType type = linked_item->getType(); -		return (type == LLAssetType::AT_CLOTHING || -				type == LLAssetType::AT_BODYPART || -				type == LLAssetType::AT_GESTURE || -				type == LLAssetType::AT_OBJECT); -	} -	else -	{ -		LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); -		// BAP remove AT_NONE support after ensembles are fully working? -		return (linked_category && -				((linked_category->getPreferredType() == LLFolderType::FT_NONE) || -				 (LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType())))); -	} -} - - -bool LLFindWearables::operator()(LLInventoryCategory* cat, -								 LLInventoryItem* item) -{ -	if(item) -	{ -		if((item->getType() == LLAssetType::AT_CLOTHING) -		   || (item->getType() == LLAssetType::AT_BODYPART)) -		{ -			return TRUE; -		} -	} -	return FALSE; -} - - -  //Used by LLFolderBridge as callback for directory recursion.  class LLRightClickInventoryFetchObserver : public LLInventoryFetchObserver  { diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ab2133d779..3e16dfea5f 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -239,6 +239,47 @@ bool LLNameCategoryCollector::operator()(  	return false;  } +bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, +									 LLInventoryItem* item) +{ +	// Valid COF items are: +	// - links to wearables (body parts or clothing) +	// - links to attachments +	// - links to gestures +	// - links to ensemble folders +	LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem(); +	if (linked_item) +	{ +		LLAssetType::EType type = linked_item->getType(); +		return (type == LLAssetType::AT_CLOTHING || +				type == LLAssetType::AT_BODYPART || +				type == LLAssetType::AT_GESTURE || +				type == LLAssetType::AT_OBJECT); +	} +	else +	{ +		LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory(); +		// BAP remove AT_NONE support after ensembles are fully working? +		return (linked_category && +				((linked_category->getPreferredType() == LLFolderType::FT_NONE) || +				 (LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType())))); +	} +} + +bool LLFindWearables::operator()(LLInventoryCategory* cat, +								 LLInventoryItem* item) +{ +	if(item) +	{ +		if((item->getType() == LLAssetType::AT_CLOTHING) +		   || (item->getType() == LLAssetType::AT_BODYPART)) +		{ +			return TRUE; +		} +	} +	return FALSE; +} +  ///----------------------------------------------------------------------------  /// LLAssetIDMatches   ///---------------------------------------------------------------------------- diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 1a1dffe85c..b5a73a3143 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3087,6 +3087,13 @@ bool process_login_success_response()  		}  	} +	// Start the process of fetching the OpenID session cookie for this user login +	std::string openid_url = response["openid_url"]; +	if(!openid_url.empty()) +	{ +		std::string openid_token = response["openid_token"]; +		LLViewerMedia::openIDSetup(openid_url, openid_token); +	}  	bool success = false;  	// JC: gesture loading done below, when we have an asset system diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6f0d9cdd95..d9fabc7d64 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -257,7 +257,43 @@ public:  		LLViewerMediaImpl *mMediaImpl;  		bool mInitialized;  }; + +class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder +{ +LOG_CLASS(LLViewerMediaOpenIDResponder); +public: +	LLViewerMediaOpenIDResponder( ) +	{ +	} + +	~LLViewerMediaOpenIDResponder() +	{ +	} + +	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) +	{ +		LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; +		LL_DEBUGS("MediaAuth") << content << LL_ENDL; +		std::string cookie = content["set-cookie"].asString(); +		 +		LLViewerMedia::openIDCookieResponse(cookie); +	} + +	/* virtual */ void completedRaw( +		U32 status, +		const std::string& reason, +		const LLChannelDescriptors& channels, +		const LLIOPipe::buffer_ptr_t& buffer) +	{ +		// This is just here to disable the default behavior (attempting to parse the response as llsd). +		// We don't care about the content of the response, only the set-cookie header. +	} + +}; +  LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL; +LLURL LLViewerMedia::sOpenIDURL; +std::string LLViewerMedia::sOpenIDCookie;  static LLViewerMedia::impl_list sViewerMediaImplList;  static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;  static LLTimer sMediaCreateTimer; @@ -1067,7 +1103,8 @@ void LLViewerMedia::clearAllCookies()  		}  	} -	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie();  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -1168,7 +1205,9 @@ void LLViewerMedia::loadCookieFile()  			pimpl->mMediaSource->clear_cookies();  		}  	} - +	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie();  } @@ -1241,6 +1280,62 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom  } +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setOpenIDCookie() +{ +	if(!sOpenIDCookie.empty()) +	{ +		getCookieStore()->setCookiesFromHost(sOpenIDCookie, sOpenIDURL.mAuthority); +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token) +{ +	LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL; + +	// post the token to the url  +	// the responder will need to extract the cookie(s). + +	// Save the OpenID URL for later -- we may need the host when adding the cookie. +	sOpenIDURL.init(openid_url.c_str()); +	 +	// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. +	sOpenIDCookie.clear(); + +	LLSD headers = LLSD::emptyMap(); +	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header +	headers["Accept"] = "*/*"; +	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream" +	headers["Content-Type"] = "application/x-www-form-urlencoded"; + +	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here. +	size_t size = openid_token.size(); +	U8 *data = new U8[size]; +	memcpy(data, openid_token.data(), size); + +	LLHTTPClient::postRaw(  +		openid_url,  +		data,  +		size,  +		new LLViewerMediaOpenIDResponder(), +		headers); +			 +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDCookieResponse(const std::string &cookie) +{ +	LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL; +	 +	sOpenIDCookie += cookie; + +	setOpenIDCookie(); +} +  bool LLViewerMedia::hasInWorldMedia()  {  	if (sInWorldMediaDisabled) return false; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 10dacf9532..e829d7a5b4 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -44,6 +44,8 @@  #include "llpluginclassmedia.h"  #include "v4color.h" +#include "llurl.h" +  class LLViewerMediaImpl;  class LLUUID;  class LLViewerMediaTexture; @@ -152,11 +154,17 @@ public:  	static void addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path = std::string("/"), bool secure = false );  	static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );  	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") ); + +	static void openIDSetup(const std::string &openid_url, const std::string &openid_token); +	static void openIDCookieResponse(const std::string &cookie);  private: +	static void setOpenIDCookie();  	static void onTeleportFinished();  	static LLPluginCookieStore *sCookieStore; +	static LLURL sOpenIDURL; +	static std::string sOpenIDCookie;  };  // Implementation functions not exported into header file diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3a6aed01ce..b54305f021 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1802,9 +1802,10 @@ class LLAdvancedDebugAvatarTextures : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -#ifndef LL_RELEASE_FOR_DOWNLOAD -		handle_debug_avatar_textures(NULL); -#endif +		if (gAgent.isGodlike()) +		{ +			handle_debug_avatar_textures(NULL); +		}  		return true;  	}  }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6dc0983f10..5f8c03b545 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4031,7 +4031,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)  	//clear animation flags  	avatarp = (LLVOAvatar *)gObjectList.findObject(uuid); -	if (!isAgentAvatarValid()) +	if (!avatarp)  	{  		// no agent by this ID...error?  		LL_WARNS("Messaging") << "Received animation state for unknown avatar" << uuid << LL_ENDL; diff --git a/indra/newview/res-sdl/toolbuy.BMP b/indra/newview/res-sdl/toolbuy.BMP Binary files differnew file mode 100644 index 0000000000..07e9273721 --- /dev/null +++ b/indra/newview/res-sdl/toolbuy.BMP diff --git a/indra/newview/res-sdl/toolopen.BMP b/indra/newview/res-sdl/toolopen.BMP Binary files differnew file mode 100644 index 0000000000..5b87979304 --- /dev/null +++ b/indra/newview/res-sdl/toolopen.BMP diff --git a/indra/newview/res-sdl/toolsit.BMP b/indra/newview/res-sdl/toolsit.BMP Binary files differnew file mode 100644 index 0000000000..8ce59ae97a --- /dev/null +++ b/indra/newview/res-sdl/toolsit.BMP diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 7a965cf57e..ecdcacec46 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -129,8 +129,8 @@ TOOLBUY                 CURSOR                  "toolbuy.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,3422 - PRODUCTVERSION 2,0,0,3422 + FILEVERSION 2,0,0,203110 + PRODUCTVERSION 2,0,0,203110   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -147,12 +147,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "2.0.0.200030" +            VALUE "FileVersion", "2.0.0.203110"              VALUE "InternalName", "Second Life"              VALUE "LegalCopyright", "Copyright © 2001-2008, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "2.0.0.200030" +            VALUE "ProductVersion", "2.0.0.203110"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml index 0e182fa417..803bd1b5ab 100644 --- a/indra/newview/skins/default/xui/de/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml @@ -22,7 +22,7 @@  		[AMT] L$  	</panel.string>  	<button label="" label_selected="" name="buycurrency" tool_tip="Mein Kontostand"/> -	<button label="Kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/> +	<button label=" " name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/>  	<text name="TimeText" tool_tip="Aktuelle Zeit (Pazifik)">  		24:00 H PST  	</text> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index fd046c3695..957ab240ee 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2842,7 +2842,7 @@ even though the user gets a free copy.           left_delta="0"           name="button about land"           top_pad="4" -         width="112" /> +         width="125" />          <check_box           control_name="ShowParcelOwners"           height="19" @@ -2863,7 +2863,7 @@ even though the user gets a free copy.           left="20"           name="label_parcel_modify"           top="152" -         width="150"> +         width="240">              Modify Parcel          </text>          <button @@ -2875,7 +2875,7 @@ even though the user gets a free copy.           left="30"           name="button subdivide land"           top="172" -         width="112" /> +         width="125" />          <button           follows="left|top"           height="23" @@ -2885,7 +2885,7 @@ even though the user gets a free copy.           left_delta="0"           name="button join land"           top_pad="4" -         width="112" /> +         width="125" />          <text           type="string"           length="1" @@ -2896,7 +2896,7 @@ even though the user gets a free copy.           left="20"           name="label_parcel_trans"           top="256" -         width="150"> +         width="240">              Land Transactions          </text>          <button @@ -2908,7 +2908,7 @@ even though the user gets a free copy.           left="30"           name="button buy land"           top="276" -         width="112" /> +         width="125" />          <button           follows="left|top"           height="23" @@ -2918,6 +2918,6 @@ even though the user gets a free copy.           left_delta="0"           name="button abandon land"           top_pad="4" -         width="112" /> +         width="125" />   </panel>  </floater> diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index ac3a949821..9c5fea9267 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -399,7 +399,7 @@ máximo" name="checkbox fullbright"/>  			<text name="tex gen">  				Detallado  			</text> -			<combo_box name="combobox texgen" width="86"> +			<combo_box name="combobox texgen">  				<combo_box.item label="Por defecto" name="Default"/>  				<combo_box.item label="Plano" name="Planar"/>  			</combo_box> @@ -442,9 +442,9 @@ máximo" name="checkbox fullbright"/>  			<check_box label="Voltear" name="checkbox flip s"/>  			<spinner label="Vertical (V)" name="TexScaleV"/>  			<check_box label="Voltear" name="checkbox flip t"/> -			<spinner label="Rotación" left="118" name="TexRot" width="62"/> -			<spinner label="Repeticiones / Metro" left="118" name="rptctrl" width="62"/> -			<button label="Aplicar" label_selected="Aplicar" left_delta="72" name="button apply"/> +			<spinner label="Rotación" name="TexRot"/> +			<spinner label="Repeticiones / Metro" name="rptctrl"/> +			<button label="Aplicar" label_selected="Aplicar" name="button apply"/>  			<text name="tex offset">  				Desplazar  			</text> @@ -487,8 +487,8 @@ Gris = Público"/>  		<text name="label_parcel_modify">  			Modificar la parcela  		</text> -		<button label="Dividir" label_selected="Dividir" name="button subdivide land" width="140"/> -		<button label="Inscribirse" label_selected="Inscribirse" name="button join land" width="140"/> +		<button label="Dividir" label_selected="Dividir" name="button subdivide land"/> +		<button label="Inscribirse" label_selected="Inscribirse" name="button join land"/>  		<text name="label_parcel_trans">  			Transacciones de terreno  		</text>  | 
