diff options
Diffstat (limited to 'indra/newview')
33 files changed, 651 insertions, 117 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4c0d47ced3..c5602d1bcc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5596,6 +5596,19 @@        <key>Value</key>        <integer>8</integer>      </map> + +   <key>PluginUseReadThread</key> +    <map> +      <key>Comment</key> +      <string>Use a separate thread to read incoming messages from plugins</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +      <key>PrecachingDelay</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7bfe6a46c9..8f14b8d782 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1548,6 +1548,9 @@ bool LLAppViewer::cleanup()  	LLViewerMedia::saveCookieFile(); +	// Stop the plugin read thread if it's running. +	LLPluginProcessParent::setUseReadThread(false); +  	llinfos << "Shutting down Threads" << llendflush;  	// Let threads finish diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 4f9434030f..fafa315a59 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -243,3 +243,19 @@ void LLChannelManager::killToastsFromChannel(const LLUUID& channel_id, const LLS  	}  } +// static +LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChannel() +{ +	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> +	(LLNotificationsUI::LLChannelManager::getInstance()-> +										findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + +	if (channel == NULL) +	{ +		llwarns << "Can't find screen channel by NotificationChannelUUID" << llendl; +		llassert(!"Can't find screen channel by NotificationChannelUUID"); +	} + +	return channel; +} + diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index c2be39122f..8c725f2660 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -114,6 +114,11 @@ public:  	 */  	void killToastsFromChannel(const LLUUID& channel_id, const LLScreenChannel::Matcher& matcher); +	/** +	 * Returns notification screen channel. +	 */ +	static LLNotificationsUI::LLScreenChannel* getNotificationScreenChannel(); +  private:  	LLScreenChannel* createChannel(LLChannelManager::Params& p); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index a2a1dd504a..b8222ebb18 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -204,10 +204,10 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by  		U32 size = clothing_by_type[type].size();  		if (size) continue; -		//*TODO create dummy item panel -		 -		//*TODO add dummy item panel -> mClothing->addItem(dummy_item_panel, item->getUUID(), ADD_BOTTOM, false); - +		EWearableType w_type = static_cast<EWearableType>(type); +		LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type); +		if(!item_panel) continue; +		mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false);  		addWearableTypeSeparator(mClothing);  	}  } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 19dbc564d1..c0cc3f1985 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -53,6 +53,7 @@  #include "llsyswellwindow.h"  #include "lltrans.h"  #include "llchathistory.h" +#include "llnotifications.h"  #include "llviewerwindow.h"  #include "llvoicechannel.h"  #include "lltransientfloatermgr.h" @@ -371,6 +372,8 @@ void LLIMFloater::onSlide()  //static  LLIMFloater* LLIMFloater::show(const LLUUID& session_id)  { +	closeHiddenIMToasts(); +  	if (!gIMMgr->hasSession(session_id)) return NULL;  	if(!isChatMultiTab()) @@ -1084,6 +1087,26 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)  }  // static +void LLIMFloater::closeHiddenIMToasts() +{ +	class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher +	{ +	public: +		bool matches(const LLNotificationPtr notification) const +		{ +			// "notifytoast" type of notifications is reserved for IM notifications +			return "notifytoast" == notification->getType(); +		} +	}; + +	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel(); +	if (channel != NULL) +	{ +		channel->closeHiddenToasts(IMToastMatcher()); +	} +} + +// static  bool LLIMFloater::isChatMultiTab()  {  	// Restart is required in order to change chat window type. diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 763dd5655b..f9dd8b9b85 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -148,6 +148,8 @@ private:  	// Remove the "User is typing..." indicator.  	void removeTypingIndicator(const LLIMInfo* im_info = NULL); +	static void closeHiddenIMToasts(); +  	LLPanelChatControlPanel* mControlPanel;  	LLUUID mSessionID;  	S32 mLastMessageIndex; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 04556acf67..ea43670da0 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -854,21 +854,7 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model,  									 const LLUUID& new_parent_id,  									 BOOL restamp)  { -	if (item->getParentUUID() != new_parent_id) -	{ -		LLInventoryModel::update_list_t update; -		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); -		update.push_back(old_folder); -		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); -		update.push_back(new_folder); -		gInventory.accountForUpdate(update); - -		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); -		new_item->setParent(new_parent_id); -		new_item->updateParentOnServer(restamp); -		model->updateItem(new_item); -		model->notifyObservers(); -	} +	change_item_parent(model, item, new_parent_id, restamp);  }  // static diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 449b1b5b4d..6c7251579d 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -585,3 +585,26 @@ BOOL get_is_item_worn(const LLUUID& id)  	}  	return FALSE;  } + + +void change_item_parent(LLInventoryModel* model, +									 LLViewerInventoryItem* item, +									 const LLUUID& new_parent_id, +									 BOOL restamp) +{ +	if (item->getParentUUID() != new_parent_id) +	{ +		LLInventoryModel::update_list_t update; +		LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); +		update.push_back(old_folder); +		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); +		update.push_back(new_folder); +		gInventory.accountForUpdate(update); + +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +		new_item->setParent(new_parent_id); +		new_item->updateParentOnServer(restamp); +		model->updateItem(new_item); +		model->notifyObservers(); +	} +} diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index e3cd988e39..6f373f7392 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -310,6 +310,12 @@ LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,  // Is this item or its baseitem is worn, attached, etc...  BOOL get_is_item_worn(const LLUUID& id); + +void change_item_parent(LLInventoryModel* model, +									 LLViewerInventoryItem* item, +									 const LLUUID& new_parent_id, +									 BOOL restamp); +  #endif // LL_LLINVENTORYFUNCTIONS_H diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 3d8cb6dfe8..8dfdb0788a 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -65,14 +65,8 @@ LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInven  void LLPanelInventoryListItemBase::updateItem()  { -	if (mItemIcon.notNull()) -		mIcon->setImage(mItemIcon); - -	LLTextUtil::textboxSetHighlightedVal( -		mTitle, -		LLStyle::Params(), -		mItem->getName(), -		mHighlightedText); +	setIconImage(mIconImage); +	setTitle(mItem->getName(), mHighlightedText);  }  void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) @@ -122,9 +116,10 @@ void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)  BOOL LLPanelInventoryListItemBase::postBuild()  { -	// Inheritors need to call base implementation -	mIcon = getChild<LLIconCtrl>("item_icon"); -	mTitle = getChild<LLTextBox>("item_name"); +	setIconCtrl(getChild<LLIconCtrl>("item_icon")); +	setTitleCtrl(getChild<LLTextBox>("item_name")); + +	mIconImage = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);  	updateItem(); @@ -156,13 +151,12 @@ void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)  LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)  : LLPanel()  , mItem(item) -, mIcon(NULL) -, mTitle(NULL) +, mIconCtrl(NULL) +, mTitleCtrl(NULL)  , mWidgetSpacing(WIDGET_SPACING)  , mLeftWidgetsWidth(0)  , mRightWidgetsWidth(0)  { -	mItemIcon = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);  }  void LLPanelInventoryListItemBase::init() @@ -197,6 +191,24 @@ void LLPanelInventoryListItemBase::reshapeWidgets()  	reshapeMiddleWidgets();  } +void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image) +{ +	if(image) +	{ +		mIconImage = image;  +		mIconCtrl->setImage(mIconImage); +	} +} + +void LLPanelInventoryListItemBase::setTitle(const std::string& title, const std::string& highlit_text) +{ +	LLTextUtil::textboxSetHighlightedVal( +		mTitleCtrl, +		LLStyle::Params(), +		title, +		highlit_text); +} +  void LLPanelInventoryListItemBase::reshapeLeftWidgets()  {  	S32 widget_left = 0; @@ -246,16 +258,16 @@ void LLPanelInventoryListItemBase::reshapeRightWidgets()  void LLPanelInventoryListItemBase::reshapeMiddleWidgets()  { -	LLRect icon_rect(mIcon->getRect()); +	LLRect icon_rect(mIconCtrl->getRect());  	icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop,   		icon_rect.getWidth(), icon_rect.getHeight()); -	mIcon->setShape(icon_rect); +	mIconCtrl->setShape(icon_rect);  	S32 name_left = icon_rect.mRight + getWidgetSpacing();  	S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing(); -	LLRect name_rect(mTitle->getRect()); +	LLRect name_rect(mTitleCtrl->getRect());  	name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom); -	mTitle->setShape(name_rect); +	mTitleCtrl->setShape(name_rect);  }  //////////////////////////////////////////////////////////////////////////////// @@ -356,17 +368,18 @@ void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)  	if (!item)  	{  		llwarns << "No inventory item. Couldn't create flat list item." << llendl; -		llassert(!"No inventory item. Couldn't create flat list item."); +		llassert(item != NULL);  	}  	LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);  	if (!list_item)  		return; -	if (!addItem(list_item, item->getUUID())) +	bool is_item_added = addItem(list_item, item->getUUID()); +	if (!is_item_added)  	{  		llwarns << "Couldn't add flat list item." << llendl; -		llassert(!"Couldn't add flat list item."); +		llassert(is_item_added);  	}  } diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 15f04c79a9..152aafbd7e 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -125,6 +125,11 @@ protected:  	 */  	virtual void init(); +	/** setter for mIconCtrl */ +	void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; } +	/** setter for MTitleCtrl */ +	void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; } +  	void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }  	void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; } @@ -139,6 +144,12 @@ protected:  	 */  	virtual void reshapeWidgets(); +	/** set wearable type icon image */ +	void setIconImage(const LLUIImagePtr& image); + +	/** Set item title - inventory item name usually */ +	void setTitle(const std::string& title, const std::string& highlit_text); +  private:  	/** reshape left side widgets @@ -155,10 +166,10 @@ private:  	LLViewerInventoryItem* mItem; -	LLIconCtrl*		mIcon; -	LLTextBox*		mTitle; +	LLIconCtrl*		mIconCtrl; +	LLTextBox*		mTitleCtrl; -	LLUIImagePtr	mItemIcon; +	LLUIImagePtr	mIconImage;  	std::string		mHighlightedText;  	widget_array_t	mLeftSideWidgets; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 214b5d317a..86147d65e6 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -215,7 +215,7 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)  void fetch_items_from_llsd(const LLSD& items_llsd)  { -	if (!items_llsd.size()) return; +	if (!items_llsd.size() || gDisconnected) return;  	LLSD body;  	body[0]["cap_name"] = "FetchInventory";  	body[1]["cap_name"] = "FetchLib"; @@ -235,6 +235,11 @@ void fetch_items_from_llsd(const LLSD& items_llsd)  	for (S32 i=0; i<body.size(); i++)  	{ +		if(!gAgent.getRegion()) +		{ +			llwarns<<"Agent's region is null"<<llendl; +			break; +		}  		if (0 >= body[i].size()) continue;  		std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString()); @@ -664,36 +669,87 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		if (!category)  			continue; -		S32 version = category->getVersion(); -		if (version != (*iter).second.mVersion) +		const S32 version = category->getVersion(); +		const S32 expected_num_descendents = category->getDescendentCount(); +		if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) || +			(expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN))  		{ -			// Update category version in map. -			(*iter).second.mVersion = version; -			(*iter).second.mCallback(); +			continue; +		} + +		// Check number of known descendents to find out whether it has changed. +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		gInventory.getDirectDescendentsOf((*iter).first, cats, items); +		if (!cats || !items) +		{ +			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; +			// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean +			// that the cat just doesn't have any items or subfolders). +			// Unrecoverable, so just skip this category. + +			llassert(cats != NULL && items != NULL); +		} +		const S32 current_num_known_descendents = cats->count() + items->count(); + +		LLCategoryData cat_data = (*iter).second; + +		// If category version or descendents count has changed +		// update category data in mCategoryMap and fire a callback. +		if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount) +		{ +			cat_data.mVersion = version; +			cat_data.mDescendentsCount = current_num_known_descendents; + +			cat_data.mCallback();  		}  	}  } -void LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) +bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)  {  	S32 version; +	S32 current_num_known_descendents; +	bool can_be_added = true; +  	LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);  	if (category)  	{  		// Inventory category version is used to find out if some changes  		// to a category have been made.  		version = category->getVersion(); + +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		gInventory.getDirectDescendentsOf(cat_id, cats, items); +		if (!cats || !items) +		{ +			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; +			// NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean +			// that the cat just doesn't have any items or subfolders). +			// Unrecoverable, so just return "false" meaning that the category can't be observed. +			can_be_added = false; + +			llassert(cats != NULL && items != NULL); +		} +		current_num_known_descendents = cats->count() + items->count();  	}  	else  	{  		// If category could not be retrieved it might mean that  		// inventory is unusable at the moment so the category is -		// stored with VERSION_UNKNOWN and it may be updated later. +		// stored with VERSION_UNKNOWN and DESCENDENT_COUNT_UNKNOWN, +		// it may be updated later.  		version = LLViewerInventoryCategory::VERSION_UNKNOWN; +		current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN; +	} + +	if (can_be_added) +	{ +		mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version, current_num_known_descendents)));  	} -	version = category->getVersion(); -	mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version))); +	return can_be_added;  }  void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id) diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index e63b67d2ad..036e6ca40d 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -276,19 +276,28 @@ public:  	LLInventoryCategoriesObserver() {};  	virtual void changed(U32 mask); -	void addCategory(const LLUUID& cat_id, callback_t cb); +	/** +	 * Add cat_id to the list of observed categories with a +	 * callback fired on category being changed. +	 * +	 * @return "true" if category was added, "false" if it could +	 * not be found. +	 */ +	bool addCategory(const LLUUID& cat_id, callback_t cb);  	void removeCategory(const LLUUID& cat_id);  protected:  	struct LLCategoryData  	{ -		LLCategoryData(callback_t cb, S32 version) +		LLCategoryData(callback_t cb, S32 version, S32 num_descendents)  		: mCallback(cb)  		, mVersion(version) +		, mDescendentsCount(num_descendents)  		{}  		callback_t	mCallback;  		S32			mVersion; +		S32			mDescendentsCount;  	};  	typedef	std::map<LLUUID, LLCategoryData>	category_map_t; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 1215272685..b103ec45d0 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -41,6 +41,7 @@  #include "llaccordionctrl.h"  #include "llaccordionctrltab.h" +#include "llappearancemgr.h"  #include "llinventoryfunctions.h"  #include "llinventorymodel.h"  #include "llwearableitemslist.h" @@ -51,6 +52,7 @@ LLOutfitsList::LLOutfitsList()  	:	LLPanel()  	,	mAccordion(NULL)  	,	mListCommands(NULL) +	,	mSelectedList(NULL)  {  	mCategoriesObserver = new LLInventoryCategoriesObserver();  	gInventory.addObserver(mCategoriesObserver); @@ -135,30 +137,37 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  	{  		const LLUUID cat_id = (*iter);  		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); -		if (!cat) -			continue; +		if (!cat) continue;  		std::string name = cat->getName();  		static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); - -		accordionXmlNode->setAttributeString("name", name); -		accordionXmlNode->setAttributeString("title", name);  		LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); +		tab->setName(name); +		tab->setTitle(name); +  		// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.  		tab->setDisplayChildren(false);  		mAccordion->addCollapsibleCtrl(tab); +		// Start observing the new outfit category. +		LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list"); +		if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id))) +		{ +			// Remove accordion tab if category could not be added to observer. +			mAccordion->removeCollapsibleCtrl(tab); +			continue; +		} +  		// Map the new tab with outfit category UUID.  		mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); -		// Start observing the new outfit category. -		LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list"); -		mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)); +		// Setting tab focus callback to monitor currently selected outfit. +		tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id)); -		// Setting drop down callback to monitor currently selected outfit. -		tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::onTabExpandedCollapsed, this, list)); +		// Setting list commit callback to monitor currently selected wearable item. +		list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));  		// Fetch the new outfit contents.  		cat->fetch(); @@ -178,10 +187,18 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  			// 1. Remove outfit accordion tab from accordion.  			mAccordion->removeCollapsibleCtrl(outfits_iter->second); +			const LLUUID& outfit_id = outfits_iter->first; +  			// 2. Remove outfit category from observer to stop monitoring its changes. -			mCategoriesObserver->removeCategory(outfits_iter->first); +			mCategoriesObserver->removeCategory(outfit_id); -			// 3. Remove category UUID to accordion tab mapping. +			// 3. Reset selection if selected outfit is being removed. +			if (mSelectedOutfitUUID == outfit_id) +			{ +				changeOutfitSelection(NULL, LLUUID()); +			} + +			// 4. Remove category UUID to accordion tab mapping.  			mOutfitsMap.erase(outfits_iter);  		}  	} @@ -199,40 +216,30 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  	mAccordion->arrange();  } -void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) +void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)  { -	outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id); -	if (outfits_iter != mOutfitsMap.end()) -	{ -		LLViewerInventoryCategory *cat = gInventory.getCategory(category_id); -		if (!cat) -			return; +	LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); +	if (!list) return; -		std::string name = cat->getName(); +	LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID()); +	if (!item) return; -		// Update tab name with the new category name. -		LLAccordionCtrlTab* tab = outfits_iter->second; -		if (tab) -		{ -			tab->setName(name); -		} - -		// Update tab title with the new category name using textbox -		// in accordion tab header. -		LLTextBox* tab_title = tab->findChild<LLTextBox>("dd_textbox"); -		if (tab_title) -		{ -			tab_title->setText(name); -		} -	} +	changeOutfitSelection(list, item->getParentUUID());  } -void LLOutfitsList::onTabExpandedCollapsed(LLWearableItemsList* list) +void LLOutfitsList::performAction(std::string action)  { -	if (!list) -		return; +	LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID); +	if (!cat) return; -	// TODO: Add outfit selection handling. +	if ("replaceoutfit" == action) +	{ +		LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE ); +	} +	else if ("addtooutfit" == action) +	{ +		LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); +	}  }  void LLOutfitsList::setFilterSubString(const std::string& string) @@ -240,7 +247,6 @@ void LLOutfitsList::setFilterSubString(const std::string& string)  	mFilterSubString = string;  } -  //////////////////////////////////////////////////////////////////////////  // Private methods  ////////////////////////////////////////////////////////////////////////// @@ -283,4 +289,37 @@ void LLOutfitsList::computeDifference(  	LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);  } +void LLOutfitsList::updateOutfitTab(const LLUUID& category_id) +{ +	outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id); +	if (outfits_iter != mOutfitsMap.end()) +	{ +		LLViewerInventoryCategory *cat = gInventory.getCategory(category_id); +		if (!cat) return; + +		std::string name = cat->getName(); + +		// Update tab name with the new category name. +		LLAccordionCtrlTab* tab = outfits_iter->second; +		if (tab) +		{ +			tab->setName(name); +			tab->setTitle(name); +		} +	} +} + +void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) +{ +	// Reset selection in previously selected tab +	// if a new one is selected. +	if (list && mSelectedList && mSelectedList != list) +	{ +		mSelectedList->resetSelection(); +	} + +	mSelectedList = list; +	mSelectedOutfitUUID = category_id; +} +  // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 2d103ea356..d86cf5a703 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -65,10 +65,9 @@ public:  	void refreshList(const LLUUID& category_id); -	// Update tab displaying outfit identified by category_id. -	void updateOutfitTab(const LLUUID& category_id); +	void onSelectionChange(LLUICtrl* ctrl); -	void onTabExpandedCollapsed(LLWearableItemsList* list); +	void performAction(std::string action);  	void setFilterSubString(const std::string& string); @@ -85,12 +84,24 @@ private:  	 */  	void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved); +	/** +	 * Updates tab displaying outfit identified by category_id. +	 */ +	void updateOutfitTab(const LLUUID& category_id); + +	/** +	 * Resets previous selection and stores newly selected list and outfit id. +	 */ +	void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);  	LLInventoryCategoriesObserver* 	mCategoriesObserver;  	LLAccordionCtrl*				mAccordion;  	LLPanel*						mListCommands; +	LLWearableItemsList*			mSelectedList; +	LLUUID							mSelectedOutfitUUID; +  	std::string 					mFilterSubString;  	typedef	std::map<LLUUID, LLAccordionCtrlTab*>		outfits_map_t; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 789e85b46f..80964938f5 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -188,19 +188,37 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)  void LLPanelOutfitsInventory::onWearButtonClick()  { -	LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); -	if (listenerp) +	// TODO: Remove if/else, add common interface +	// for "My Outfits" and "Wearing" tabs. +	if (!isCOFPanelActive()) +	{ +		mMyOutfitsPanel->performAction("replaceoutfit"); +	} +	else  	{ -		listenerp->performAction(NULL, "replaceoutfit"); +		LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); +		if (listenerp) +		{ +			listenerp->performAction(NULL, "replaceoutfit"); +		}  	}  }  void LLPanelOutfitsInventory::onAdd()  { -	LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); -	if (listenerp) +	// TODO: Remove if/else, add common interface +	// for "My Outfits" and "Wearing" tabs. +	if (!isCOFPanelActive()) +	{ +		mMyOutfitsPanel->performAction("addtooutfit"); +	} +	else  	{ -		listenerp->performAction(NULL, "addtooutfit"); +		LLFolderViewEventListener* listenerp = getCorrectListenerForAction(); +		if (listenerp) +		{ +			listenerp->performAction(NULL, "addtooutfit"); +		}  	}  } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 75702dc8e5..fb7ac0d86b 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -35,6 +35,7 @@  #include "llpreviewnotecard.h"  #include "llinventory.h" +#include "llinventoryfunctions.h" // for change_item_parent()  #include "llagent.h"  #include "llassetuploadresponders.h" @@ -92,11 +93,17 @@ BOOL LLPreviewNotecard::postBuild()  	childSetAction("Save", onClickSave, this);  	childSetVisible("lock", FALSE);	 +	childSetAction("Delete", onClickDelete, this); +	childSetEnabled("Delete", false); +  	const LLInventoryItem* item = getItem();  	childSetCommitCallback("desc", LLPreview::onText, this);  	if (item) +	{  		childSetText("desc", item->getDescription()); +		childSetEnabled("Delete", true); +	}  	childSetPrevalidate("desc", &LLTextValidate::validateASCIIPrintableNoPipe);  	return LLPreview::postBuild(); @@ -374,6 +381,17 @@ void LLPreviewNotecard::onClickSave(void* user_data)  	}  } + +// static +void LLPreviewNotecard::onClickDelete(void* user_data) +{ +	LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data; +	if(preview) +	{ +		preview->deleteNotecard(); +	} +} +  struct LLSaveNotecardInfo  {  	LLPreviewNotecard* mSelf; @@ -466,6 +484,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)  	return true;  } +void LLPreviewNotecard::deleteNotecard() +{ +	LLViewerInventoryItem* item = gInventory.getItem(mItemUUID); +	if (item != NULL) +	{ +		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); +		change_item_parent(&gInventory, item, trash_id, FALSE); +	} + +	closeFloater(); +} +  // static  void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)  { diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index e0363eef54..98de99aa33 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -83,6 +83,8 @@ protected:  	virtual void loadAsset();  	bool saveIfNeeded(LLInventoryItem* copyitem = NULL); +	void deleteNotecard(); +  	static void onLoadComplete(LLVFS *vfs,  							   const LLUUID& asset_uuid,  							   LLAssetType::EType type, @@ -90,6 +92,8 @@ protected:  	static void onClickSave(void* data); +	static void onClickDelete(void* data); +  	static void onSaveComplete(const LLUUID& asset_uuid,  							   void* user_data,  							   S32 status, LLExtStat ext_status); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index af440a3689..de1da248c1 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -706,6 +706,31 @@ void LLScreenChannel::hideToast(const LLUUID& notification_id)  	}  } +void LLScreenChannel::closeHiddenToasts(const Matcher& matcher) +{ +	// since we can't guarantee that close toast operation doesn't change mToastList +	// we collect matched toasts that should be closed into separate list +	std::list<ToastElem> toasts; +	for (std::vector<ToastElem>::iterator it = mToastList.begin(); it +			!= mToastList.end(); it++) +	{ +		LLToast * toast = it->toast; +		// add to list valid toast that match to provided matcher criteria +		if (toast != NULL && !toast->isDead() && toast->getNotification() != NULL +				&& !toast->getVisible() && matcher.matches(toast->getNotification())) +		{ +			toasts.push_back(*it); +		} +	} + +	// close collected toasts +	for (std::list<ToastElem>::iterator it = toasts.begin(); it +			!= toasts.end(); it++) +	{ +		it->toast->closeFloater(); +	} +} +  //--------------------------------------------------------------------------  void LLScreenChannel::removeToastsFromChannel()  { diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 88053d87d9..46c5fed7b6 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -173,6 +173,12 @@ public:  	void		hideToastsFromScreen();  	// hide toast by notification id  	void		hideToast(const LLUUID& notification_id); + +	/** +	 * Closes hidden matched toasts from channel. +	 */ +	void closeHiddenToasts(const Matcher& matcher); +  	// removes all toasts from a channel  	void		removeToastsFromChannel();  	// show all toasts in a channel diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index fd2bb0fdf9..a4d8dddfe4 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -732,10 +732,17 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi  	}  } +static LLFastTimer::DeclareTimer FTM_MEDIA_UPDATE("Update Media"); +  //////////////////////////////////////////////////////////////////////////////////////////  // static  void LLViewerMedia::updateMedia(void *dummy_arg)  { +	LLFastTimer t1(FTM_MEDIA_UPDATE); +	 +	// Enable/disable the plugin read thread +	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread")); +	  	sAnyMediaShowing = false;  	sUpdatedCookies = getCookieStore()->getChangedCookies();  	if(!sUpdatedCookies.empty()) diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index b8fab63be9..56b2791993 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -33,8 +33,11 @@  #include "llwearableitemslist.h" +#include "lliconctrl.h" +  #include "llinventoryfunctions.h"  #include "llinventorymodel.h" +#include "lltransutil.h"  class LLFindOutfitItems : public LLInventoryCollectFunctor  { @@ -212,6 +215,87 @@ void LLPanelBodyPartsListItem::setShowEditButton(bool show)  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLPanelDummyClothingListItem* LLPanelDummyClothingListItem::create(EWearableType w_type) +{ +	LLPanelDummyClothingListItem* list_item = new LLPanelDummyClothingListItem(w_type); +	list_item->init(); +	return list_item; +} + +void LLPanelDummyClothingListItem::updateItem() +{ +	std::string title = wearableTypeToString(mWearableType); +	setTitle(title, LLStringUtil::null); +} + +BOOL LLPanelDummyClothingListItem::postBuild() +{ +	LLIconCtrl* icon = getChild<LLIconCtrl>("item_icon"); +	setIconCtrl(icon); +	setTitleCtrl(getChild<LLTextBox>("item_name")); + +	addWidgetToRightSide("btn_add"); + +	setIconImage(get_item_icon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE)); +	updateItem(); + +	// Make it look loke clothing item - reserve space for 'delete' button +	setLeftWidgetsWidth(icon->getRect().mLeft); + +	setWidgetsVisible(false); +	reshapeWidgets(); + +	return TRUE; +} + +LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(EWearableType w_type) + : LLPanelWearableListItem(NULL) + , mWearableType(w_type) +{ +} + +void LLPanelDummyClothingListItem::init() +{ +	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_dummy_clothing_list_item.xml"); +} + +typedef std::map<EWearableType, std::string> clothing_to_string_map_t; + +clothing_to_string_map_t init_clothing_string_map() +{ +	clothing_to_string_map_t w_map; +	w_map.insert(std::make_pair(WT_SHIRT, "shirt_not_worn")); +	w_map.insert(std::make_pair(WT_PANTS, "pants_not_worn")); +	w_map.insert(std::make_pair(WT_SHOES, "shoes_not_worn")); +	w_map.insert(std::make_pair(WT_SOCKS, "socks_not_worn")); +	w_map.insert(std::make_pair(WT_JACKET, "jacket_not_worn")); +	w_map.insert(std::make_pair(WT_GLOVES, "gloves_not_worn")); +	w_map.insert(std::make_pair(WT_UNDERSHIRT, "undershirt_not_worn")); +	w_map.insert(std::make_pair(WT_UNDERPANTS, "underpants_not_worn")); +	w_map.insert(std::make_pair(WT_SKIRT, "skirt_not_worn")); +	w_map.insert(std::make_pair(WT_ALPHA, "alpha_not_worn")); +	w_map.insert(std::make_pair(WT_TATTOO, "tattoo_not_worn")); +	return w_map; +} + +std::string LLPanelDummyClothingListItem::wearableTypeToString(EWearableType w_type) +{ +	static const clothing_to_string_map_t w_map = init_clothing_string_map(); +	static const std::string invalid_str = LLTrans::getString("invalid_not_worn"); +	 +	std::string type_str = invalid_str; +	clothing_to_string_map_t::const_iterator it = w_map.find(w_type); +	if(w_map.end() != it) +	{ +		type_str = LLTrans::getString(it->second); +	} +	return type_str; +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +  static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");  LLWearableItemsList::Params::Params() diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index ae43b3f673..c4a415dfbf 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -81,7 +81,6 @@ public:  	virtual ~LLPanelClothingListItem(); -	/*virtual*/ void init();  	/*virtual*/ BOOL postBuild();  	/** @@ -96,6 +95,8 @@ public:  protected:  	LLPanelClothingListItem(LLViewerInventoryItem* item); +	 +	/*virtual*/ void init();  };  class LLPanelBodyPartsListItem : public LLPanelWearableListItem @@ -107,7 +108,6 @@ public:  	virtual ~LLPanelBodyPartsListItem(); -	/*virtual*/ void init();  	/*virtual*/ BOOL postBuild();  	/** @@ -118,6 +118,32 @@ public:  protected:  	LLPanelBodyPartsListItem(LLViewerInventoryItem* item); + +	/*virtual*/ void init(); +}; + +/** + * @class LLPanelDummyClothingListItem + * + * A dummy item panel - displays grayed clothing icon, grayed title '<clothing> not worn' and 'add' button + */ +class LLPanelDummyClothingListItem : public LLPanelWearableListItem +{ +public: +	static LLPanelDummyClothingListItem* create(EWearableType w_type); + +	/*virtual*/ void updateItem(); +	/*virtual*/ BOOL postBuild(); + +protected: +	LLPanelDummyClothingListItem(EWearableType w_type); + +	/*virtual*/ void init(); + +	static std::string wearableTypeToString(EWearableType w_type); + +private: +	EWearableType mWearableType;  };  /** diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml index 14c0081c0d..0e8eef2a21 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -84,8 +84,18 @@       label="Save"       label_selected="Save"       layout="topleft" -     left="288" +     left="178"       name="Save"       top="332"       width="100" /> +    <button +     follows="right|bottom" +     height="22" +     label="Delete" +     label_selected="Delete" +     layout="topleft" +     left="288" +     name="Delete" +     top="332" +     width="100" />  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 6a5f9ed8f8..19b6b1b22e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1339,6 +1339,16 @@               function="ToggleControl"               parameter="RunMultipleThreads" />          </menu_item_check> +        <menu_item_check +         label="Use Plugin Read Thread" +         name="Use Plugin Read Thread"> +            <menu_item_check.on_check +             function="CheckControl" +             parameter="PluginUseReadThread" /> +            <menu_item_check.on_click +             function="ToggleControl" +             parameter="PluginUseReadThread" /> +        </menu_item_check>          <menu_item_call           label="Clear Group Cache"           name="ClearGroupCache"> diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml index 445f677c94..4313d450fb 100644 --- a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml @@ -48,14 +48,13 @@       top="4"       value="..."       width="359" /> -    <button  +    <icon        name="btn_lock"       layout="topleft"       follows="top|right" -     image_unselected="Lock2" -     image_selected="Lock2" +     image_name="Lock2"       top="0" -     left_pad="3" +     left="0"       height="20"       width="20"       tab_stop="false" /> diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml index 386b3b2c4f..8dc67de06f 100644 --- a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml @@ -81,17 +81,15 @@       height="20"       width="20"       tab_stop="false" /> -    <button  +    <icon       name="btn_lock"       layout="topleft"       follows="top|right" -     image_unselected="Lock2" -     image_selected="Lock2" +     image_name="Lock2"       top="0"       left_pad="3"       height="20" -     width="20" -     tab_stop="false" /> +     width="20" />      <button        name="btn_edit"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..dbbfa8f2e2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="top|right|left" + height="20" + layout="topleft" + left="0" + name="dummy_clothing_item" + top="0" + width="380"> +    <icon +     follows="top|right|left" +     height="20" +     image_name="ListItem_Over" +     layout="topleft" +     left="0" +     name="hovered_icon" +     top="0" +     visible="false" +     width="380" /> +    <icon +     height="20" +     follows="top|right|left" +     image_name="ListItem_Select" +     layout="topleft" +     left="0" +     name="selected_icon" +     top="0" +     visible="false" +     width="380" /> +    <icon +     height="16" +     color="0.75 0.75 0.75 1" +     follows="top|left" +     image_name="Inv_Object" +     layout="topleft" +     left="20" +     name="item_icon" +     top="2" +     width="16" /> +    <text +     follows="left|right" +     height="16" +     layout="topleft" +     left_pad="5" +     allow_html="false" +     use_ellipses="true" +     name="item_name" +     text_color="LtGray_50" +     top="4" +     value="..." +     width="359" /> +    <button  +     name="btn_add" +     layout="topleft" +     follows="top|right" +     label="+" +     top="0" +     left="0" +     height="20" +     width="20" +     tab_stop="false" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 73181392c9..a9f588698a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -234,6 +234,14 @@                   name="move_further_btn"                   top="1"                   width="31" /> +                <icon +                 follows="bottom|left" +                 height="25" +                 image_name="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="1" +                 name="dummy_icon" +                 width="105" />                  <button                   follows="bottom|right"                   height="25" @@ -440,6 +448,22 @@                   name="add_to_outfit_btn"                   top="1"                   width="31" /> +                <icon +                 follows="bottom|left" +                 height="25" +                 image_name="Toolbar_Middle_Off" +                 layout="topleft" +                 left_pad="1" +                 name="dummy_middle_icon" +                 width="140" /> +                <icon +                 follows="bottom|left" +                 height="25" +                 image_name="Toolbar_Right_Off" +                 layout="topleft" +                 left_pad="1" +                 name="dummy_right_icon" +                 width="31" />              </panel>          </layout_panel>      </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 066ea3be6e..7e212c9383 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -490,6 +490,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M           label="Share"           layout="topleft"           name="share_btn" +         tool_tip="Share an inventory item"           width="62" />          <button           follows="bottom|left" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 3ef16d2dec..ba967d3e2c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -330,7 +330,7 @@      <check_box       enabled="false"       height="16" -     label="Enable plain text chat history" +     label="Enable plain text IM and chat history"       layout="topleft"       left_delta="0"       name="plain_text_chat_history" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f9459bcee2..73df41b776 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1802,6 +1802,20 @@ Clears (deletes) the media and all params from the given face.  	<string name="alpha">Alpha</string>  	<string name="tattoo">Tattoo</string>  	<string name="invalid">invalid</string> +   +  <!-- Not Worn Wearable Types --> +	<string name="shirt_not_worn">Shirt not worn</string> +	<string name="pants_not_worn">Pants not worn</string> +	<string name="shoes_not_worn">Shoes not worn</string> +	<string name="socks_not_worn">Socks not worn</string> +	<string name="jacket_not_worn">Jacket not worn</string> +	<string name="gloves_not_worn">Gloves not worn</string> +	<string name="undershirt_not_worn">Undershirt not worn</string> +	<string name="underpants_not_worn">Underpants not worn</string> +	<string name="skirt_not_worn">Skirt not worn</string> +	<string name="alpha_not_worn">Alpha not worn</string> +	<string name="tattoo_not_worn">Tattoo not worn</string> +	<string name="invalid_not_worn">invalid</string>    <!-- Wearable List-->    <string name="NewWearable">New [WEARABLE_ITEM]</string>  | 
