diff options
32 files changed, 686 insertions, 381 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e632cbaaf2..e7e89d9701 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -90,6 +90,7 @@ set(viewer_SOURCE_FILES      llbox.cpp      llbreadcrumbview.cpp      llcallbacklist.cpp +    llcallfloater.cpp      llcallingcard.cpp      llcapabilitylistener.cpp      llcaphttpsender.cpp @@ -588,6 +589,7 @@ set(viewer_HEADER_FILES      llbox.h      llbreadcrumbview.h      llcallbacklist.h +    llcallfloater.h      llcallingcard.h      llcapabilitylistener.h      llcapabilityprovider.h diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 327d80ba34..8f3eba98a6 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -234,6 +234,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)  			// Check if cache already contains image_id for that avatar  			if (!updateFromCache())  			{ +				LLIconCtrl::setValue(mDefaultIconName);  				app->addObserver(mAvatarId, this);  				app->sendAvatarPropertiesRequest(mAvatarId);  			} diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index bb03f47f46..7f3f869e5d 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -363,37 +363,6 @@ void LLAvatarList::computeDifference(  	vadded.erase(it, vadded.end());  } -static std::string format_secs(S32 secs) -{ -	// *TODO: reinventing the wheel? -	// *TODO: i18n -	static const int LL_AL_MIN		= 60; -	static const int LL_AL_HOUR		= LL_AL_MIN * 60; -	static const int LL_AL_DAY		= LL_AL_HOUR * 24; -	static const int LL_AL_WEEK		= LL_AL_DAY * 7; -	static const int LL_AL_MONTH	= LL_AL_DAY * 31; -	static const int LL_AL_YEAR		= LL_AL_DAY * 365; - -    std::string s; - -    if (secs >= LL_AL_YEAR) -        s = llformat("%dy", secs / LL_AL_YEAR); -    else if (secs >= LL_AL_MONTH) -        s = llformat("%dmon", secs / LL_AL_MONTH); -    else if (secs >= LL_AL_WEEK) -        s = llformat("%dw", secs / LL_AL_WEEK); -    else if (secs >= LL_AL_DAY) -        s = llformat("%dd", secs / LL_AL_DAY); -    else if (secs >= LL_AL_HOUR) -        s = llformat("%dh", secs / LL_AL_HOUR); -    else if (secs >= LL_AL_MIN) -        s = llformat("%dm", secs / LL_AL_MIN); -    else -        s = llformat("%ds", secs); - -    return s; -} -  // Refresh shown time of our last interaction with all listed avatars.  void LLAvatarList::updateLastInteractionTimes()  { @@ -407,7 +376,7 @@ void LLAvatarList::updateLastInteractionTimes()  		LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it);  		S32 secs_since = now - (S32) LLRecentPeople::instance().getDate(item->getAvatarId()).secondsSinceEpoch();  		if (secs_since >= 0) -			item->setLastInteractionTime(format_secs(secs_since)); +			item->setLastInteractionTime(secs_since);  	}  } diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index c670a65bcc..efc9538fa6 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -198,9 +198,9 @@ void LLAvatarListItem::showLastInteractionTime(bool show)  	mAvatarName->setRect(name_rect);  } -void LLAvatarListItem::setLastInteractionTime(const std::string& val) +void LLAvatarListItem::setLastInteractionTime(U32 secs_since)  { -	mLastInteractionTime->setValue(val); +	mLastInteractionTime->setValue(formatSeconds(secs_since));  }  void LLAvatarListItem::setShowInfoBtn(bool show) @@ -326,3 +326,51 @@ void LLAvatarListItem::reshapeAvatarName()  	mAvatarName->reshape(width, height);  } + +// Convert given number of seconds to a string like "23 minutes", "15 hours" or "3 years", +// taking i18n into account. The format string to use is taken from the panel XML. +std::string LLAvatarListItem::formatSeconds(U32 secs) +{ +	static const U32 LL_ALI_MIN		= 60; +	static const U32 LL_ALI_HOUR	= LL_ALI_MIN	* 60; +	static const U32 LL_ALI_DAY		= LL_ALI_HOUR	* 24; +	static const U32 LL_ALI_WEEK	= LL_ALI_DAY	* 7; +	static const U32 LL_ALI_MONTH	= LL_ALI_DAY	* 30; +	static const U32 LL_ALI_YEAR	= LL_ALI_DAY	* 365; + +	std::string fmt;  +	U32 count = 0; + +	if (secs >= LL_ALI_YEAR) +	{ +		fmt = "FormatYears"; count = secs / LL_ALI_YEAR; +	} +	else if (secs >= LL_ALI_MONTH) +	{ +		fmt = "FormatMonths"; count = secs / LL_ALI_MONTH; +	} +	else if (secs >= LL_ALI_WEEK) +	{ +		fmt = "FormatWeeks"; count = secs / LL_ALI_WEEK; +	} +	else if (secs >= LL_ALI_DAY) +	{ +		fmt = "FormatDays"; count = secs / LL_ALI_DAY; +	} +	else if (secs >= LL_ALI_HOUR) +	{ +		fmt = "FormatHours"; count = secs / LL_ALI_HOUR; +	} +	else if (secs >= LL_ALI_MIN) +	{ +		fmt = "FormatMinutes"; count = secs / LL_ALI_MIN; +	} +	else +	{ +		fmt = "FormatSeconds"; count = secs; +	} + +	LLStringUtil::format_map_t args; +	args["[COUNT]"] = llformat("%u", count); +	return getString(fmt, args); +} diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 9d48101a44..341f5a6bcf 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -63,7 +63,7 @@ public:  	void setOnline(bool online);  	void setName(const std::string& name);  	void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); -	void setLastInteractionTime(const std::string& val); +	void setLastInteractionTime(U32 secs_since);  	//Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly  	void setShowProfileBtn(bool show);  	void setShowInfoBtn(bool show); @@ -94,6 +94,8 @@ private:  	void onNameCache(const std::string& first_name, const std::string& last_name); +	std::string formatSeconds(U32 secs); +  	LLAvatarIconCtrl* mAvatarIcon;  	LLTextBox* mAvatarName;  	LLTextBox* mLastInteractionTime; diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp new file mode 100644 index 0000000000..f566806b29 --- /dev/null +++ b/indra/newview/llcallfloater.cpp @@ -0,0 +1,76 @@ +/**  + * @file llcallfloater.cpp + * @author Mike Antipov + * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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 "llcallfloater.h" + +#include "llavatarlist.h" +#include "llbottomtray.h" +#include "llparticipantlist.h" +#include "llspeakers.h" + + +LLCallFloater::LLCallFloater(const LLSD& key) +: LLDockableFloater(NULL, key) +, mSpeakerManager(NULL) +, mPaticipants(NULL) +, mAvatarList(NULL) +{ + +} + +LLCallFloater::~LLCallFloater() +{ +	delete mPaticipants; +	mPaticipants = NULL; +} + +// virtual +BOOL LLCallFloater::postBuild() +{ +	LLDockableFloater::postBuild(); +	mAvatarList = getChild<LLAvatarList>("speakers_list"); + +	mSpeakerManager = LLLocalSpeakerMgr::getInstance(); +	mPaticipants = new LLParticipantList(mSpeakerManager, mAvatarList, false); + +	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_panel"); + +	setDockControl(new LLDockControl( +		anchor_panel, this, +		getDockTongue(), LLDockControl::TOP)); + +	return TRUE; +} +//EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h new file mode 100644 index 0000000000..8c4a204943 --- /dev/null +++ b/indra/newview/llcallfloater.h @@ -0,0 +1,71 @@ +/**  + * @file llcallfloater.h + * @author Mike Antipov + * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...). + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 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_LLCALLFLOATER_H +#define LL_LLCALLFLOATER_H + +#include "lldockablefloater.h" + +class LLAvatarList; +class LLParticipantList; +class LLSpeakerMgr; + +/** + * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button. + * It can be torn-off and freely positioned onscreen. + * + * When the Resident is engaged in Nearby Voice Chat, the Voice Control Panel provides control over  + * the Resident's own microphone input volume, the audible volume of each of the other participants, + * the Resident's own Voice Morphing settings (if she has subscribed to enable the feature), and Voice Recording. + * + * When the Resident is engaged in Group Voice Chat, the Voice Control Panel also provides an  + * 'End Call' button to allow the Resident to leave that voice channel. + */ +class LLCallFloater : public LLDockableFloater +{ +public: +	LLCallFloater(const LLSD& key); +	~LLCallFloater(); + +	/*virtual*/ BOOL postBuild(); + + +private: +	LLSpeakerMgr* mSpeakerManager; +	LLParticipantList* mPaticipants; +	LLAvatarList* mAvatarList; +}; + + +#endif //LL_LLCALLFLOATER_H + diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 2c9b38b82a..caf9c08057 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -199,7 +199,7 @@ public:  			userName->setValue(SL);  		} -		setTimeField(chat.mTimeStr); +		setTimeField(chat);  		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon"); @@ -267,11 +267,29 @@ protected:  	}  private: -	void setTimeField(const std::string& time_value) +	std::string appendTime(const LLChat& chat)
 +	{
 +		time_t utc_time;
 +		utc_time = time_corrected();
 +		std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
 +			+LLTrans::getString("TimeMin")+"] ";
 +
 +		LLSD substitution;
 +
 +		substitution["datetime"] = (S32) utc_time;
 +		LLStringUtil::format (timeStr, substitution);
 +
 +		return timeStr;
 +	}
 + +	void setTimeField(const LLChat& chat)  	{  		LLTextBox* time_box = getChild<LLTextBox>("time_box");  		LLRect rect_before = time_box->getRect(); + +		std::string time_value = appendTime(chat); +  		time_box->setValue(time_value);  		// set necessary textbox width to fit all text @@ -386,7 +404,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_  		p.left_pad = mLeftWidgetPad;  		p.right_pad = mRightWidgetPad; -		if (mLastFromName == chat.mFromName) +		LLDate new_message_time = LLDate::now(); + +		if (mLastFromName == chat.mFromName &&  +			mLastMessageTime.notNull() && +			(new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 )  		{  			view = getSeparator();  			p.top_pad = mTopSeparatorPad; @@ -414,6 +436,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_  		appendWidget(p, header_text, false);  		mLastFromName = chat.mFromName; +		mLastMessageTime = new_message_time;  	}  	//Handle IRC styled /me messages.  	std::string prefix = chat.mText.substr(0, 4); diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index ef5839ff2f..d2cfa53d8b 100644 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -114,6 +114,7 @@ class LLChatHistory : public LLTextEditor  	private:  		std::string mLastFromName; +		LLDate mLastMessageTime;  		std::string mMessageHeaderFilename;  		std::string mMessageSeparatorFilename; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 8a6935b71b..4acb9fd480 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -44,27 +44,12 @@  #include "llviewercontrol.h"  #include "llagentdata.h" -/* -static const S32 BORDER_MARGIN = 2; -static const S32 PARENT_BORDER_MARGIN = 0; - -static const S32 HORIZONTAL_MULTIPLE = 8; -static const S32 VERTICAL_MULTIPLE = 16; -static const F32 MIN_AUTO_SCROLL_RATE = 120.f; -static const F32 MAX_AUTO_SCROLL_RATE = 500.f; -static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; - -#define MAX_CHAT_HISTORY 100 -*/ - -static const S32 msg_left_offset = 30; +static const S32 msg_left_offset = 10;  static const S32 msg_right_offset = 10; -static const S32 msg_height_pad = 2; - -//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl>	t2("chat_items_container"); +static const S32 msg_height_pad = 5;  //******************************************************************************************************************* -//LLChatItemCtrl +//LLNearbyChatToastPanel  //*******************************************************************************************************************  LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance() @@ -79,22 +64,22 @@ void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_p  {  	LLPanel::reshape(width, height,called_from_parent); -	// *NOTE: we must check if child items exist because reshape is called from the  -	// LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet -	LLPanel* caption = findChild<LLPanel>("msg_caption", false); -	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text" ,false); -	if(caption && msg_text) -	{ -		LLRect caption_rect = caption->getRect(); -		caption_rect.setLeftTopAndSize( 2, height, width - 4, caption_rect.getHeight()); -		caption->reshape( width - 4, caption_rect.getHeight(), 1); -		caption->setRect(caption_rect); - -		LLRect msg_text_rect = msg_text->getRect(); -		msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight()); -		msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1); -		msg_text->setRect(msg_text_rect); -	} +	LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false); +	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); + +	LLRect msg_text_rect = msg_text->getRect(); +	LLRect avatar_rect = icon->getRect(); +	 +	avatar_rect.setLeftTopAndSize(2,height-2,avatar_rect.getWidth(),avatar_rect.getHeight()); +	icon->setRect(avatar_rect); + + +	msg_text_rect.setLeftTopAndSize( avatar_rect.mRight + msg_left_offset,  +		height - msg_height_pad,  +		width - avatar_rect.mRight  - msg_left_offset - msg_right_offset,  +		height - 2*msg_height_pad); +	msg_text->reshape( msg_text_rect.getWidth(), msg_text_rect.getHeight(), 1); +	msg_text->setRect(msg_text_rect);  }  BOOL LLNearbyChatToastPanel::postBuild() @@ -102,37 +87,63 @@ BOOL LLNearbyChatToastPanel::postBuild()  	return LLPanel::postBuild();  } - -std::string LLNearbyChatToastPanel::appendTime() +void LLNearbyChatToastPanel::addMessage(LLSD& notification)  { -	time_t utc_time; -	utc_time = time_corrected(); -	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" -		+LLTrans::getString("TimeMin")+"] "; +	std::string		messageText = notification["message"].asString();		// UTF-8 line of text -	LLSD substitution; +	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); -	substitution["datetime"] = (S32) utc_time; -	LLStringUtil::format (timeStr, substitution); +	std::string color_name = notification["text_color"].asString(); +	 +	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name); +	textColor.mV[VALPHA] =notification["color_alpha"].asReal(); +	 +	S32 font_size = notification["font_size"].asInteger(); -	return timeStr; -} +	LLFontGL*       messageFont; +	switch(font_size) +	{ +		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break; +		default: +		case 1: messageFont = LLFontGL::getFontSansSerif();	    break; +		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break; +	} +	//append text +	{ +		LLStyle::Params style_params; +		style_params.color(textColor); +		std::string font_name = LLFontGL::nameFromFont(messageFont); +		std::string font_style_size = LLFontGL::sizeFromFont(messageFont); +		style_params.font.name(font_name); +		style_params.font.size(font_style_size); +		int chat_type = notification["chat_type"].asInteger(); + +		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) +		{ +			messageText = messageText.substr(3); +			style_params.font.style = "ITALIC"; +		} +		else if( chat_type == CHAT_TYPE_SHOUT) +		{ +			style_params.font.style = "BOLD"; +		} +		else if( chat_type == CHAT_TYPE_WHISPER) +		{ +			style_params.font.style = "ITALIC"; +		} +		msg_text->appendText(messageText, TRUE, style_params); +	} + +	snapToMessageHeight(); -void	LLNearbyChatToastPanel::addText	(const std::string& message , const LLStyle::Params& input_params) -{ -	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); -	msg_text->addText(message , input_params); -	mMessages.push_back(message);  }  void LLNearbyChatToastPanel::init(LLSD& notification)  { -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); - -	mText = notification["message"].asString();		// UTF-8 line of text -	mFromName = notification["from"].asString();	// agent or object name +	std::string		messageText = notification["message"].asString();		// UTF-8 line of text +	std::string		fromName = notification["from"].asString();	// agent or object name  	mFromID = notification["from_id"].asUUID();		// agent id or object id  	int sType = notification["source"].asInteger(); @@ -140,192 +151,121 @@ void LLNearbyChatToastPanel::init(LLSD& notification)  	std::string color_name = notification["text_color"].asString(); -	mTextColor = LLUIColorTable::instance().getColor(color_name); -	mTextColor.mV[VALPHA] =notification["color_alpha"].asReal(); +	LLColor4 textColor = LLUIColorTable::instance().getColor(color_name); +	textColor.mV[VALPHA] =notification["color_alpha"].asReal();  	S32 font_size = notification["font_size"].asInteger(); + +	LLFontGL*       messageFont;  	switch(font_size)  	{ -		case 0: -			mFont = LLFontGL::getFontSansSerifSmall(); -			break; +		case 0:	messageFont = LLFontGL::getFontSansSerifSmall(); break;  		default: -		case 1: -			mFont = LLFontGL::getFontSansSerif(); -			break; -		case 2: -			mFont = LLFontGL::getFontSansSerifBig(); -			break; +		case 1: messageFont = LLFontGL::getFontSansSerif();	    break; +		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;  	} -	LLStyle::Params style_params; -	style_params.color(mTextColor); -//	style_params.font(mFont); -	std::string font_name = LLFontGL::nameFromFont(mFont); -	std::string font_style_size = LLFontGL::sizeFromFont(mFont); -	style_params.font.name(font_name); -	style_params.font.size(font_style_size); +	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); + +	msg_text->setText(std::string(""));  	std::string str_sender;  	if(gAgentID != mFromID) -		str_sender = mFromName; +		str_sender = fromName;  	else -		str_sender = LLTrans::getString("You");; +		str_sender = LLTrans::getString("You"); -	caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender , style_params); -	 -	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); +	str_sender+=" "; +	//append user name +	{ +		LLStyle::Params style_params_name; + +		LLColor4 userNameColor = LLUIColorTable::instance().getColor("ChatToastAgentNameColor"); + +		style_params_name.color(userNameColor); +		 +		std::string font_name = LLFontGL::nameFromFont(messageFont); +		std::string font_style_size = LLFontGL::sizeFromFont(messageFont); +		style_params_name.font.name(font_name); +		style_params_name.font.size(font_style_size); +		 +		msg_text->appendText(str_sender, FALSE, style_params_name); +		 +	} -	if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC) +	//append text  	{ -		if (mFromName.size() > 0) +		LLStyle::Params style_params; +		style_params.color(textColor); +		std::string font_name = LLFontGL::nameFromFont(messageFont); +		std::string font_style_size = LLFontGL::sizeFromFont(messageFont); +		style_params.font.name(font_name); +		style_params.font.size(font_style_size); + +		int chat_type = notification["chat_type"].asInteger(); + +		if(notification["chat_style"].asInteger()== CHAT_STYLE_IRC)  		{ +			messageText = messageText.substr(3);  			style_params.font.style = "ITALIC"; -			 -			msg_text->setText(mFromName, style_params);  		} -		mText = mText.substr(3); -		style_params.font.style = "ITALIC"; -#define INFINITE_REFLOW_BUG 0 -#if INFINITE_REFLOW_BUG -		// This causes LLTextBase::reflow() to infinite loop until the viewer -		// runs out of memory, throws a bad_alloc exception from std::vector -		// in mLineInfoList, and the main loop catches it and continues. -		// It appears to be caused by addText() adding a line separator in the -		// middle of a line.  See EXT-2579, EXT-1949 -		msg_text->addText(mText,style_params); -#else -		msg_text->appendText(mText, FALSE, style_params); -#endif -	} -	else  -	{ -		msg_text->setText(mText, style_params); +		else if( chat_type == CHAT_TYPE_SHOUT) +		{ +			style_params.font.style = "BOLD"; +		} +		else if( chat_type == CHAT_TYPE_WHISPER) +		{ +			style_params.font.style = "ITALIC"; +		} +		msg_text->appendText(messageText, FALSE, style_params);  	} -	 -	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); -	if(mSourceType != CHAT_SOURCE_AGENT) -		msg_inspector->setVisible(false); - -	mMessages.clear(); - -	snapToMessageHeight	(); +	snapToMessageHeight();  	mIsDirty = true;//will set Avatar Icon in draw  } -void	LLNearbyChatToastPanel::setMessage	(const LLChat& chat_msg) -{ -	LLSD notification; -	notification["message"] = chat_msg.mText; -	notification["from"] = chat_msg.mFromName; -	notification["from_id"] = chat_msg.mFromID; -	notification["time"] = chat_msg.mTime; -	notification["source"] = (S32)chat_msg.mSourceType; -	notification["chat_type"] = (S32)chat_msg.mChatType; -	notification["chat_style"] = (S32)chat_msg.mChatStyle; -	 -	std::string r_color_name="White"; -	F32 r_color_alpha = 1.0f;  -	LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); -	 -	notification["text_color"] = r_color_name; -	notification["color_alpha"] = r_color_alpha; -	 -	notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; -	init(notification); - -} -  void	LLNearbyChatToastPanel::snapToMessageHeight	()  {  	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); -	S32 new_height = text_box->getTextPixelHeight() + msg_height_pad; +	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25); +	  	LLRect panel_rect = getRect(); -	S32 caption_height = 0; -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); -	caption_height = caption->getRect().getHeight(); - -	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), caption_height + new_height); +	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), new_height); -	reshape( getRect().getWidth(), caption_height + new_height, 1); +	reshape( getRect().getWidth(), getRect().getHeight(), 1);  	setRect(panel_rect);  } - -void	LLNearbyChatToastPanel::setWidth(S32 width) -{ -	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); -	text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/); - -	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); -	 -	LLStyle::Params style_params; -	style_params.color(mTextColor); -	style_params.font(mFont); -	 -	 -	if(mText.length()) -		msg_text->setText(mText, style_params); -	 -	for(size_t i=0;i<mMessages.size();++i) -		msg_text->addText(mMessages[i] , style_params); - -	setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width	, getRect().mBottom)); -	snapToMessageHeight	(); -} -  void LLNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)  { -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); -	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); -	msg_inspector->setVisible(false);  }  void LLNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)  {  	if(mSourceType != CHAT_SOURCE_AGENT)  		return; -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); -	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); -	msg_inspector->setVisible(true);  }  BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)  {  	if(mSourceType != CHAT_SOURCE_AGENT)  		return LLPanel::handleMouseDown(x,y,mask); -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); -	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector"); -	S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft; -	S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom; -	if(msg_inspector->pointInView(local_x, local_y)) -	{ -		LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mFromID)); -	} -	else -	{ -		LLFloaterReg::showInstance("nearby_chat",LLSD()); -	} +	LLFloaterReg::showInstance("nearby_chat",LLSD());  	return LLPanel::handleMouseDown(x,y,mask);  }  void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)  { -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); - -	LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon", false); -	LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name", false); - -	icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH); -	name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH); +	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false); +	if(icon) +		icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);  } @@ -339,11 +279,10 @@ bool	LLNearbyChatToastPanel::canAddText	()  BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)  { -	LLPanel* caption = getChild<LLPanel>("msg_caption", false); -	LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false); +	LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false); -	S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft; -	S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom; +	S32 local_x = x - avatar_icon->getRect().mLeft; +	S32 local_y = y - avatar_icon->getRect().mBottom;  	//eat message for avatar icon if msg was from object  	if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT) @@ -354,9 +293,7 @@ void LLNearbyChatToastPanel::draw()  {  	if(mIsDirty)  	{ -		LLPanel* caption = findChild<LLPanel>("msg_caption", false); -		if(caption) -			caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID); +		getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);  		mIsDirty = false;  	}  	LLToastPanelBase::draw(); diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index a65bfedd09..0a85c52401 100644 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -59,9 +59,8 @@ public:  	const LLUUID& getFromID() const { return mFromID;} -	void	addText		(const std::string& message ,  const LLStyle::Params& input_params = LLStyle::Params()); -	void	setMessage	(const LLChat& msg); -	void	setWidth		(S32 width); +	//void	addText		(const std::string& message ,  const LLStyle::Params& input_params = LLStyle::Params()); +	//void	setMessage	(const LLChat& msg);  	void	snapToMessageHeight	();  	bool	canAddText	(); @@ -78,22 +77,16 @@ public:  	BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);  	virtual void init(LLSD& data); +	virtual void addMessage(LLSD& data);  	virtual void draw(); -private: -	 -	std::string appendTime	(); +	const LLUUID&	messageID() const { return mFromID;}  private: -	std::string		mText;		// UTF-8 line of text -	std::string		mFromName;	// agent or object name  	LLUUID			mFromID;	// agent id or object id  	EChatSourceType	mSourceType; -	LLColor4        mTextColor; -	LLFontGL*       mFont; - +	 -	std::vector<std::string> mMessages;  	bool mIsDirty;  }; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index ee93a9349a..310eaaec27 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -529,7 +529,6 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void*  		//in disconnected state IM input editor should be disabled  		self->mInputEditor->setEnabled(!gDisconnected);  	} -	self->mChatHistory->setCursorAndScrollToEnd();  }  // static diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 74a75d0369..b0b6db682c 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -52,8 +52,6 @@ using namespace LLNotificationsUI;  LLToastPanelBase* createToastPanel()  {  	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance(); -	static S32 chat_item_width = 304; -	item->setWidth(chat_item_width);  	return item;  } @@ -169,6 +167,29 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)  	//look in pool. if there is any message  	if(mStopProcessing)  		return; + +	/* +    find last toast and check ID +	*/ + +	if(m_active_toasts.size()) +	{ +		LLUUID fromID = notification["from_id"].asUUID();		// agent id or object id +		LLToast* toast = m_active_toasts[0]; +		LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel()); + +		if(panel && panel->messageID() == fromID && panel->canAddText()) +		{ +			panel->addMessage(notification); +			toast->reshapeToPanel(); +			toast->resetTimer(); +	 +			arrangeToasts(); +			return; +		} +	} +	 +  	if(m_toast_pool.empty())  	{ diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index da7922d657..020c25c8ac 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1544,9 +1544,6 @@ void LLPanelGroupMembersSubTab::updateMembers()  	mPendingMemberUpdate = FALSE;  	// Rebuild the members list. -	mMembersList->deleteAllItems(); - -	lldebugs << "LLPanelGroupMembersSubTab::updateMembers()" << llendl;  	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);  	if (!gdatap)  @@ -1563,7 +1560,12 @@ void LLPanelGroupMembersSubTab::updateMembers()  	{  		return;  	} -		 + +	//cleanup list only for first iretation +	if(mMemberProgress == gdatap->mMembers.begin()) +		mMembersList->deleteAllItems(); + +  	LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();  	S32 i = 0; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index fa6d16cfb1..78b4d29b16 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -120,6 +120,7 @@ LLPanelIMControlPanel::LLPanelIMControlPanel()  LLPanelIMControlPanel::~LLPanelIMControlPanel()  { +	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);  }  BOOL LLPanelIMControlPanel::postBuild() @@ -169,7 +170,9 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)  	LLIMModel& im_model = LLIMModel::instance(); +	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);  	mAvatarID = im_model.getOtherParticipantID(session_id); +	LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);  	// Disable "Add friend" button for friends.  	childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(mAvatarID)); @@ -198,6 +201,12 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)  	}  } +//virtual +void LLPanelIMControlPanel::changed(U32 mask) +{ +	childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(mAvatarID)); +} +  void LLPanelIMControlPanel::nameUpdatedCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)  {  	if ( id == mAvatarID ) diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 7bfc432ef2..a590232a0b 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -35,6 +35,7 @@  #include "llpanel.h"  #include "llvoicechannel.h" +#include "llcallingcard.h"  class LLSpeakerMgr;  class LLAvatarList; @@ -66,7 +67,7 @@ private:  }; -class LLPanelIMControlPanel : public LLPanelChatControlPanel +class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver  {  public:  	LLPanelIMControlPanel(); @@ -76,6 +77,9 @@ public:  	void setSessionId(const LLUUID& session_id); +	// LLFriendObserver trigger +	virtual void changed(U32 mask); +  protected:  	void nameUpdatedCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index e6b6ec64bd..73d903ed36 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -73,6 +73,8 @@ static const std::string FRIENDS_TAB_NAME	= "friends_panel";  static const std::string GROUP_TAB_NAME		= "groups_panel";  static const std::string RECENT_TAB_NAME	= "recent_panel"; +static const std::string COLLAPSED_BY_USER  = "collapsed_by_user"; +  /** Comparator for comparing avatar items by last interaction date */  class LLAvatarItemRecentComparator : public LLAvatarItemComparator  { @@ -467,7 +469,7 @@ LLPanelPeople::~LLPanelPeople()  } -void LLPanelPeople::onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list) +void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)  {  	if(!avatar_list)  	{ @@ -477,6 +479,7 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAva  	bool expanded = param.asBoolean(); +	setAccordionCollapsedByUser(ctrl, !expanded);  	if(!expanded)  	{  		avatar_list->resetSelection(); @@ -550,11 +553,11 @@ BOOL LLPanelPeople::postBuild()  	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");  	accordion_tab->setDropDownStateChangedCallback( -		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mAllFriendList)); +		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList));  	accordion_tab = getChild<LLAccordionCtrlTab>("tab_online");  	accordion_tab->setDropDownStateChangedCallback( -		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _2, mOnlineFriendList)); +		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList));  	buttonSetAction("view_profile_btn",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this));  	buttonSetAction("group_info_btn",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this)); @@ -931,6 +934,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)  	mRecentList->setNameFilter(mFilterSubString);  	mGroupList->setNameFilter(mFilterSubString); +	setAccordionCollapsedByUser("tab_online", false); +	setAccordionCollapsedByUser("tab_all", false); +  	showFriendsAccordionsIfNeeded();  } @@ -1309,8 +1315,12 @@ void LLPanelPeople::showAccordion(const std::string name, bool show)  	tab->setVisible(show);  	if(show)  	{ -		// expand accordion -		tab->changeOpenClose(false); +		// don't expand accordion if it was collapsed by user +		if(!isAccordionCollapsedByUser(tab)) +		{ +			// expand accordion +			tab->changeOpenClose(false); +		}  	}  } @@ -1342,3 +1352,44 @@ void LLPanelPeople::onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param  	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");  	accordion->arrange();  } + +void LLPanelPeople::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed) +{ +	if(!acc_tab) +	{ +		llwarns << "Invalid parameter" << llendl; +		return; +	} + +	LLSD param = acc_tab->getValue(); +	param[COLLAPSED_BY_USER] = collapsed; +	acc_tab->setValue(param); +} + +void LLPanelPeople::setAccordionCollapsedByUser(const std::string& name, bool collapsed) +{ +	setAccordionCollapsedByUser(getChild<LLUICtrl>(name), collapsed); +} + +bool LLPanelPeople::isAccordionCollapsedByUser(LLUICtrl* acc_tab) +{ +	if(!acc_tab) +	{ +		llwarns << "Invalid parameter" << llendl; +		return false; +	} + +	LLSD param = acc_tab->getValue(); +	if(!param.has(COLLAPSED_BY_USER)) +	{ +		return false; +	} +	return param[COLLAPSED_BY_USER].asBoolean(); +} + +bool LLPanelPeople::isAccordionCollapsedByUser(const std::string& name) +{ +	return isAccordionCollapsedByUser(getChild<LLUICtrl>(name)); +} + +// EOF diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index d9dd76f3ac..5ac5bcc1d7 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -127,7 +127,7 @@ private:  								const std::vector<LLUUID>& ids,  								void*); -	void					onFriendsAccordionExpandedCollapsed(const LLSD& param, LLAvatarList* avatar_list); +	void					onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list);  	void					showAccordion(const std::string name, bool show); @@ -135,6 +135,11 @@ private:  	void					onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param); +	void					setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); +	void					setAccordionCollapsedByUser(const std::string& name, bool collapsed); +	bool					isAccordionCollapsedByUser(LLUICtrl* acc_tab); +	bool					isAccordionCollapsedByUser(const std::string& name); +  	LLFilterEditor*			mFilterEditor;  	LLTabContainer*			mTabContainer;  	LLAvatarList*			mOnlineFriendList; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index b82b994540..327048d4f3 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -52,6 +52,8 @@  // Used to limit time spent for items list update per frame.  static const U32 ADD_LIMIT = 50; +static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; +  class LLTeleportHistoryFlatItem : public LLPanel  {  public: @@ -254,6 +256,10 @@ BOOL LLTeleportHistoryPanel::postBuild()  				LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter;  				tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4));  				tab->setDisplayChildren(false); +				tab->setDropDownStateChangedCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionExpand, this, _1, _2)); + +				// All accordion tabs are collapsed initially +				setAccordionCollapsedByUser(tab, true);  				mItemContainers.put(tab); @@ -270,10 +276,18 @@ BOOL LLTeleportHistoryPanel::postBuild()  		// Open first 2 accordion tabs  		if (mItemContainers.size() > 1) -			mItemContainers.get(mItemContainers.size() - 1)->setDisplayChildren(true); +		{ +			LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1); +			tab->setDisplayChildren(true); +			setAccordionCollapsedByUser(tab, false); +		}  		if (mItemContainers.size() > 2) -			mItemContainers.get(mItemContainers.size() - 2)->setDisplayChildren(true); +		{ +			LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 2); +			tab->setDisplayChildren(true); +			setAccordionCollapsedByUser(tab, false); +		}  	}  	getChild<LLPanel>("bottom_panel")->childSetAction("gear_btn",boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); @@ -491,6 +505,18 @@ void LLTeleportHistoryPanel::refresh()  			LLAccordionCtrlTab* tab = mItemContainers.get(mItemContainers.size() - 1 - tab_idx);  			tab->setVisible(true); +			// Expand all accordion tabs when filtering +			if(!mFilterSubString.empty()) +			{ +				tab->setDisplayChildren(true); +			} +			// Restore each tab's expand state when not filtering +			else +			{ +				bool collapsed = isAccordionCollapsedByUser(tab); +				tab->setDisplayChildren(!collapsed); +			} +  			curr_flat_view = getFlatListViewFromTab(tab);  		} @@ -775,3 +801,26 @@ void LLTeleportHistoryPanel::onGearButtonClicked()  	LLMenuGL::showPopup(this, menu, menu_x, menu_y);  } +void LLTeleportHistoryPanel::setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed) +{ +	LLSD param = acc_tab->getValue(); +	param[COLLAPSED_BY_USER] = collapsed; +	acc_tab->setValue(param); +} + +bool LLTeleportHistoryPanel::isAccordionCollapsedByUser(LLUICtrl* acc_tab) +{ +	LLSD param = acc_tab->getValue(); +	if(!param.has("acc_collapsed")) +	{ +		return false; +	} +	return param[COLLAPSED_BY_USER].asBoolean(); +} + +void LLTeleportHistoryPanel::onAccordionExpand(LLUICtrl* ctrl, const LLSD& param) +{ +	bool expanded = param.asBoolean(); +	// Save accordion tab state to restore it in refresh() +	setAccordionCollapsedByUser(ctrl, !expanded); +} diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index a31ff34cb6..f646fea355 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -98,6 +98,10 @@ private:  	LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);  	void onGearButtonClicked(); +	void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); +	bool isAccordionCollapsedByUser(LLUICtrl* acc_tab); +	void onAccordionExpand(LLUICtrl* ctrl, const LLSD& param); +  	LLTeleportHistoryStorage*	mTeleportHistory;  	LLAccordionCtrl*		mHistoryAccordion; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 4ee9cba69c..a5440c3687 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -47,10 +47,11 @@  #if LL_MSVC  #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally  #endif -LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list): +LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list,  bool use_context_menu/* = true*/):  	mSpeakerMgr(data_source),  	mAvatarList(avatar_list),  	mSortOrder(E_SORT_BY_NAME) +,	mParticipantListMenu(NULL)  {  	mSpeakerAddListener = new SpeakerAddListener(*this);  	mSpeakerRemoveListener = new SpeakerRemoveListener(*this); @@ -68,8 +69,11 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av      // Set onAvatarListDoubleClicked as default on_return action.  	mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList)); -	mParticipantListMenu = new LLParticipantListMenu(*this); -	mAvatarList->setContextMenu(mParticipantListMenu); +	if (use_context_menu) +	{ +		mParticipantListMenu = new LLParticipantListMenu(*this); +		mAvatarList->setContextMenu(mParticipantListMenu); +	}  	//Lets fill avatarList with existing speakers  	LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 5e26c39fc8..ce61dd9b96 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -43,7 +43,7 @@ class LLParticipantList  {  	LOG_CLASS(LLParticipantList);  	public: -		LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list); +		LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu = true);  		~LLParticipantList();  		void setSpeakingIndicatorsVisible(BOOL visible); diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp index 54f776ca6a..5edc4804ca 100644 --- a/indra/newview/llspeakbutton.cpp +++ b/indra/newview/llspeakbutton.cpp @@ -32,19 +32,14 @@  #include "llviewerprecompiledheaders.h" // must be first include -#include "llagent.h" -#include "llbottomtray.h" +#include "llbutton.h"  #include "llfloaterreg.h" -#include "llvoiceclient.h" -#include "llvoicecontrolpanel.h" -#include "lltransientfloatermgr.h" -#include "llavatariconctrl.h" -#include "llbutton.h" -#include "llpanel.h" -#include "lltextbox.h" +#include "llagent.h" +#include "llbottomtray.h" +#include "llcallfloater.h"  #include "lloutputmonitorctrl.h" -#include "llgroupmgr.h" +#include "lltransientfloatermgr.h"  #include "llspeakbutton.h" @@ -72,7 +67,6 @@ void LLSpeakButton::draw()  LLSpeakButton::LLSpeakButton(const Params& p)  : LLUICtrl(p) -, mPrivateCallPanel(NULL)  , mOutputMonitor(NULL)  , mSpeakBtn(NULL)  , mShowBtn(NULL) @@ -102,8 +96,8 @@ LLSpeakButton::LLSpeakButton(const Params& p)  	addChild(mShowBtn);  	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn); -	mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this)); -	mShowBtn->setToggleState(FALSE); +// 	mShowBtn->setClickedCallback(boost::bind(&LLSpeakButton::onClick_ShowBtn, this)); +// 	mShowBtn->setToggleState(FALSE);  	static const S32 MONITOR_RIGHT_PAD = 2; @@ -175,42 +169,3 @@ void LLSpeakButton::onMouseUp_SpeakBtn()  	gVoiceClient->inputUserControlState(down);  } -void LLSpeakButton::onClick_ShowBtn() -{ -	if(!mShowBtn->getToggleState()) -	{ -		mPrivateCallPanel->onClickClose(mPrivateCallPanel); -		delete mPrivateCallPanel; -		mPrivateCallPanel = NULL; -		mShowBtn->setToggleState(FALSE); -		return; -	} - -	S32 x = mSpeakBtn->getRect().mLeft; -	S32 y = 0; - -	localPointToScreen(x, y, &x, &y); - -	mPrivateCallPanel = new LLVoiceControlPanel; -	getRootView()->addChild(mPrivateCallPanel); - -	y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); - -	LLRect rect; -	rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); -	mPrivateCallPanel->setRect(rect); - - -	LLAvatarListItem* item = new LLAvatarListItem(); -	item->showLastInteractionTime(false); -	item->showInfoBtn(true); -	item->showSpeakingIndicator(true); -	item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE); - -	mPrivateCallPanel->addItem(item); -	mPrivateCallPanel->setVisible(TRUE); -	mPrivateCallPanel->setFrontmost(TRUE); - -	mShowBtn->setToggleState(TRUE); -} - diff --git a/indra/newview/llspeakbutton.h b/indra/newview/llspeakbutton.h index 424ee5357a..6660b50240 100644 --- a/indra/newview/llspeakbutton.h +++ b/indra/newview/llspeakbutton.h @@ -36,7 +36,7 @@  #include "llinitparam.h"  #include "lluictrl.h" -class LLVoiceControlPanel; +class LLCallFloater;  class LLButton;  class LLOutputMonitorCtrl; @@ -86,12 +86,10 @@ protected:  	void onMouseDown_SpeakBtn();  	void onMouseUp_SpeakBtn(); -	void onClick_ShowBtn(); -  private:  	LLButton*	mSpeakBtn;  	LLButton*	mShowBtn; -	LLVoiceControlPanel* mPrivateCallPanel; +	LLHandle<LLFloater> mPrivateCallPanel;  	LLOutputMonitorCtrl* mOutputMonitor;  }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 642df92379..227f6c4971 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -38,6 +38,7 @@  #include "llviewerfloaterreg.h"  #include "llcompilequeue.h" +#include "llcallfloater.h"  #include "llfloaterabout.h"  #include "llfloateractivespeakers.h"  #include "llfloateranimpreview.h" @@ -174,7 +175,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);  	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>); -	LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>);  	LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);  	LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);  	LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); @@ -234,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>);  	LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>); +	LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLScriptFloater>);  	LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);  	LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);  	LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>); @@ -248,6 +249,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");  	LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>); +	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);  	LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);	  	LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);	 diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 639585de55..a3495b9588 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -52,7 +52,7 @@ public:  		STATE_CONNECTED  	} EState; -	typedef boost::function<void(const EState& old_state, const EState& new_state)> state_changed_callback_t; +	typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state)> state_changed_signal_t;  	// on current channel changed signal  	typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t; @@ -78,7 +78,8 @@ public:  	virtual BOOL callStarted();  	const std::string& getSessionName() const { return mSessionName; } -	void setStateChangedCallback(state_changed_callback_t callback) { mStateChangedCallback = callback; } +	boost::signals2::connection setStateChangedCallback(const state_changed_signal_t::slot_type& callback) +	{ return mStateChangedCallback.connect(callback); }  	const LLUUID getSessionID() { return mSessionID; }  	EState getState() { return mState; } @@ -124,7 +125,7 @@ protected:  	static BOOL sSuspended;  private: -	state_changed_callback_t mStateChangedCallback; +	state_changed_signal_t mStateChangedCallback;  };  class LLVoiceChannelGroup : public LLVoiceChannel diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index eb8ec00bb9..295f4259fd 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -81,7 +81,7 @@  	<color       name="AgentChatColor" -     reference="LtGray" /> +     reference="White" />      <color       name="AlertBoxColor"       value="0.24 0.24 0.24 1" /> @@ -669,7 +669,7 @@       reference="LtGray" />      <color       name="UserChatColor" -     reference="LtGray" /> +     reference="White" />      <color       name="llOwnerSayChatColor"       reference="LtGray" /> @@ -684,5 +684,8 @@      <color       name="SysWellItemSelected"       value="0.3 0.3 0.3 1.0" /> +	<color +     name="ChatToastAgentNameColor" +     value="1.0 0.3 1.0 1.0" />  </colors> diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml new file mode 100644 index 0000000000..2f13b51a9f --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + height="300" + layout="topleft" + name="floater_voice_controls" + title="Voice Controls" + save_visibility="true" + single_instance="true" + width="282"> +    <panel +     bevel_style="in" +     follows="left|right|top" +     height="73" +     layout="topleft" +     left="0" +     name="control_panel" +     width="285"> +        <panel +         height="20" +         layout="topleft" +         left="10" +         name="my_panel" +         width="262"> +            <avatar_icon +             enabled="false" +             follows="left|top" +             height="20" +             image_name="icon_avatar_online.tga" +             layout="topleft" +             left="0" +             name="user_icon" +             top="0" +             width="20" /> +            <text +             follows="top|left" +             font="SansSerifSmallBold" +             height="16" +             layout="topleft" +             left_pad="10" +             name="user_text" +             text_color="white" +             top="4" +             value="Mya Avatar:" +             width="80" /> +        </panel> +        <layout_stack +         bottom="10" +         clip="false" +         follows="left|right|top" +         height="24" +         layout="bottomleft" +         orientation="horizontal" +         width="262"> +            <layout_panel +             follows="left" +             layout="topleft" +             min_width="24" +             top="0" +             user_resize="false" +             width="24"> +                <icon +                 height="24" +                 image_name="Microphone_On" +                 layout="topleft" +                 name="Microphone_On" +                 top="0" +                 width="24" /> +            </layout_panel> +            <layout_panel +             layout="topleft" +             top="0" +             user_resize="false" +             width="258"> +                <slider_bar +                 control_name="AudioLevelMic" +                 follows="left|right|top" +                 height="24" +                 increment="0.05" +                 layout="topleft" +                 left="0" +                 max_val="2" +                 name="volume_slider_bar" +                 tool_tip="Master Volume" +                 top="0" +                 value="0.75" +                 width="258" /> +            </layout_panel> +        </layout_stack> +    </panel> +    <avatar_list +     follows="all" +     height="197" +     ignore_online_status="true" +     layout="topleft" +     left="0" +     multi_select="true" +     name="speakers_list" +     width="282" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index 2eaa3a94ee..45f9d9c7b6 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -7,6 +7,18 @@   name="avatar_list_item"   top="0"   width="320"> +    <!--  +    Strings used to localize last interaction time. +    See last_interaction textbox below. +    --> +    <string name="FormatSeconds">[COUNT]s</string> +    <string name="FormatMinutes">[COUNT]m</string> +    <string name="FormatHours">[COUNT]h</string> +    <string name="FormatDays">[COUNT]d</string> +    <string name="FormatWeeks">[COUNT]w</string> +    <string name="FormatMonths">[COUNT]mon</string> +    <string name="FormatYears">[COUNT]y</string> +       <icon       follows="top|right|left"       height="24" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index da8006d545..ec3f7ea7c5 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -72,7 +72,13 @@             left="0"             name="talk"             top="4" -          width="100" /> +          width="100"> +              <show_button> +                  <show_button.init_callback +                   function="Button.SetDockableFloaterToggle" +                   parameter="voice_controls" /> +              </show_button> +          </talk_button>          </layout_panel>          <icon              auto_resize="false" diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml index 2b29796f0a..34c6e02684 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -2,70 +2,26 @@  <!-- All our XML is utf-8 encoded. -->  <panel    name="instant_message" -  width="300" +  width="315"    height="180"    follows="all"> -	<panel -	width="290" -	height="24" -	background_visible="true" -	background_opaque="false" -	bg_alpha_color="Black" -	left="5" -	name="msg_caption"> -             <avatar_icon -         follows="left" -         height="18" -         image_name="Generic_Person" -         layout="topleft" -         left="3" -         mouse_opaque="true" -         name="avatar_icon" -         top="3" -         width="18" /> -    	<text -                font.style="BOLD" -                height="12" -	    layout="topleft" -	    left_pad="5" -	    top="7" -		text_color="white" -		word_wrap="false" -		use_ellipses="true" -        	mouse_opaque="true" -		name="sender_name" -        	width="150"> -	      Jerry Knight -    	</text> -   <!-- 	<icon top="22" left="215" width="15" height="15" follows="top|right" -      		image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector" />--> -    	<!--<icon top="22" left="215" width="10" height="10" follows="top|right" -      		image_name="speaking_indicator.tga"	name="msg_icon"/>--> -	 <text -            font="SansSerifSmall" -         follows="right|top" -	 halign="right" -         height="13" -         layout="topleft" -         right="-10" -	 left="205" -	 mouse_opaque="true" -      name="msg_time" -        top="8" -         value="23:30" -         width="50" -	 word_wrap="true" /> -	</panel> +     <avatar_icon +        follows="left|top" +        height="18" +        image_name="Generic_Person" +        layout="topleft" +        left="3" +        mouse_opaque="true" +        name="avatar_icon" +        top="3" +        width="18" />  	<text_chat -      top="-35" -      left="10" -      right="-10" +      top="5" +      left="30"        height="120" -      follows="left|right|bottom"        text_color="white"        word_wrap="true"        mouse_opaque="true"        name="msg_text"> -      To be or not to be, that is the question. Tis a far far better thing I do than I have ever done. Tis a far far better place I go, than I have ever been.  	</text_chat>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index ca84c9147b..4f0d155876 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -27,6 +27,7 @@     There are no picks/classifieds here   </text>   <accordion +  fit_parent="true"     follows="all"    height="465"    layout="topleft"  | 
