diff options
29 files changed, 1037 insertions, 1566 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 86d30c239f..509f9581d6 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -332,7 +332,6 @@ set(viewer_SOURCE_FILES      llnamelistctrl.cpp      llnavigationbar.cpp      llnearbychat.cpp -    llnearbychatbar.cpp      llnearbychathandler.cpp      llnearbychatbarlistener.cpp      llnetmap.cpp @@ -364,7 +363,6 @@ set(viewer_SOURCE_FILES      llpanelgroupnotices.cpp      llpanelgrouproles.cpp      llpanelhome.cpp -    llpanelimcontrolpanel.cpp      llpanelland.cpp      llpanellandaudio.cpp      llpanellandmarkinfo.cpp @@ -890,7 +888,6 @@ set(viewer_HEADER_FILES      llnamelistctrl.h      llnavigationbar.h      llnearbychat.h -    llnearbychatbar.h      llnearbychathandler.h      llnearbychatbarlistener.h      llnetmap.h @@ -916,7 +913,6 @@ set(viewer_HEADER_FILES      llpanelgroupnotices.h      llpanelgrouproles.h      llpanelhome.h -    llpanelimcontrolpanel.h      llpanelland.h      llpanellandaudio.h      llpanellandmarkinfo.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3870a3be2e..0db03289d8 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -54,7 +54,7 @@  #include "llmorphview.h"  #include "llmoveview.h"  #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llnotificationsutil.h"  #include "llpaneltopinfobar.h"  #include "llparcel.h" @@ -1778,7 +1778,7 @@ void LLAgent::startTyping()  	{  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);  	} -	LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); +	LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);  }  //----------------------------------------------------------------------------- @@ -1790,7 +1790,7 @@ void LLAgent::stopTyping()  	{  		clearRenderState(AGENT_STATE_TYPING);  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); -		LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); +		LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);  	}  } diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 7477fbd656..477bdb3967 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -35,7 +35,7 @@  #include "llfloaterreg.h"  #include "lllocalcliprect.h"  #include "lltrans.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llviewercontrol.h"  #include "llagentdata.h" @@ -316,12 +316,12 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)  			return TRUE;  		else  		{ -			LLNearbyChatBar::getInstance()->showHistory(); +			LLNearbyChat::getInstance()->showHistory();  			return FALSE;  		}  	} -	LLNearbyChatBar::getInstance()->showHistory(); +	LLNearbyChat::getInstance()->showHistory();  	return LLPanel::handleMouseUp(x,y,mask);  } diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index 1a17183efd..bb01ce5a7e 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -29,7 +29,7 @@  #include "llfloatertranslationsettings.h"  // Viewer includes -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "lltranslate.h"  #include "llviewercontrol.h" // for gSavedSettings @@ -293,6 +293,6 @@ void LLFloaterTranslationSettings::onBtnOK()  	gSavedSettings.setString("TranslationService", getSelectedService());  	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());  	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); -	LLNearbyChatBar::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured()); +	LLNearbyChat::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());  	closeFloater(false);  } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 66ca76bfb0..26b63bdacb 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -51,7 +51,7 @@  #include "llviewermessage.h"  #include "llvoavatarself.h"  #include "llviewerstats.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llappearancemgr.h"  #include "llgesturelistener.h" @@ -997,7 +997,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)  			const BOOL animate = FALSE; -			LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); +			LLNearbyChat::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);  			gesture->mCurrentStep++;  			break; diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp index f5d84e80c1..893d8dc83f 100644 --- a/indra/newview/llimconversation.cpp +++ b/indra/newview/llimconversation.cpp @@ -27,25 +27,27 @@  #include "llviewerprecompiledheaders.h" -#include "llpanelimcontrolpanel.h" +#include "llimconversation.h"  #include "lldraghandle.h"  #include "llfloaterreg.h" -#include "llimconversation.h"  #include "llimfloater.h"  #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container  #include "lllayoutstack.h"  #include "llnearbychat.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h" + +const F32 REFRESH_INTERVAL = 0.2;  LLIMConversation::LLIMConversation(const LLUUID& session_id)    : LLTransientDockableFloater(NULL, true, session_id) -  ,  mControlPanel(NULL) +  ,	LLEventTimer(REFRESH_INTERVAL)    ,  mIsP2PChat(false)    ,  mExpandCollapseBtn(NULL)    ,  mTearOffBtn(NULL)    ,  mCloseBtn(NULL)    ,  mSessionID(session_id) +  , mParticipantList(NULL)  {  	mCommitCallbackRegistrar.add("IMSession.Menu.Action",  			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2)); @@ -63,6 +65,15 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)  			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));  } +LLIMConversation::~LLIMConversation() +{ +	if (mParticipantList) +	{ +		delete mParticipantList; +		mParticipantList = NULL; +	} +} +  BOOL LLIMConversation::postBuild()  {  	mCloseBtn = getChild<LLButton>("close_btn"); @@ -71,19 +82,12 @@ BOOL LLIMConversation::postBuild()  	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");  	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this)); -	if (mControlPanel) -	{ -	    mControlPanel->setSessionId(mSessionID); -	    mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")); - -		mExpandCollapseBtn->setImageOverlay( -				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon")); -	} -	else -	{ -		mExpandCollapseBtn->setEnabled(false); -		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false); -	} +	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel"); +	mParticipantListPanel->setVisible( +			mIsNearbyChat? false : gSavedSettings.getBOOL("IMShowControlPanel")); +	mExpandCollapseBtn->setImageOverlay( +				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon")); +	mExpandCollapseBtn->setEnabled(!mIsP2PChat);  	mTearOffBtn = getChild<LLButton>("tear_off_btn");  	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this)); @@ -93,6 +97,8 @@ BOOL LLIMConversation::postBuild()  		setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);  	} +	buildParticipantList(); +  	if (isChatMultiTab())  	{  		return LLFloater::postBuild(); @@ -104,6 +110,47 @@ BOOL LLIMConversation::postBuild()  } +BOOL LLIMConversation::tick() +{ +	// Need to resort the participant list if it's in sort by recent speaker order. +	if (mParticipantList) +	{ +		mParticipantList->update(); +	} + +	return false; +} + +void LLIMConversation::buildParticipantList() +{	if (mIsNearbyChat) +	{ +	} +	else +	{ +		// for group and Ad-hoc chat we need to include agent into list +		if(!mIsP2PChat && !mParticipantList && mSessionID.notNull()) +		{ +			LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID); +			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false); +		} +	} +} + +void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata) +{ +	// TODO: Check this code when when sort order menu will be added. (EM) +	if (true || !mParticipantList) +		return; + +	std::string chosen_item = userdata.asString(); + +	if (chosen_item == "sort_name") +	{ +		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME); +	} + +} +  void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)  {  	std::string item = userdata.asString(); @@ -162,11 +209,11 @@ void LLIMConversation::updateHeaderAndToolbar()  	}  	bool is_control_panel_visible = false; -	if (mControlPanel) +	if (!mIsP2PChat)  	{  		// Control panel should be visible only in torn off floaters.  		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel"); -		mControlPanel->getParent()->setVisible(is_control_panel_visible); +		mParticipantListPanel->setVisible(is_control_panel_visible);  	}  	// Display collapse image (<<) if the floater is hosted @@ -215,10 +262,10 @@ void LLIMConversation::processChatHistoryStyleUpdate()  		}  	} -	LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance(); -	if (nearby_chat_bar) +	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); +	if (nearby_chat)  	{ -		nearby_chat_bar->reloadMessages(); +		nearby_chat->reloadMessages();  	}  } @@ -240,12 +287,12 @@ void LLIMConversation::onSlide(LLIMConversation* self)  	}  	else ///< floater is torn off  	{ -		if (self->mControlPanel) +		if (!self->mIsP2PChat)  		{ -			bool expand = !self->mControlPanel->getParent()->getVisible(); +			bool expand = !self->mParticipantListPanel->getVisible();  			// Expand/collapse the IM control panel -			self->mControlPanel->getParent()->setVisible(expand); +			self->mParticipantListPanel->setVisible(expand);  			gSavedSettings.setBOOL("IMShowControlPanel", expand); diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h index 501977e061..d31ae0808a 100644 --- a/indra/newview/llimconversation.h +++ b/indra/newview/llimconversation.h @@ -28,19 +28,24 @@  #ifndef LL_IMCONVERSATION_H  #define LL_IMCONVERSATION_H +#include "lllayoutstack.h" +#include "llparticipantlist.h"  #include "lltransientdockablefloater.h"  #include "llviewercontrol.h" +#include "lleventtimer.h"  class LLPanelChatControlPanel;  class LLIMConversation  	: public LLTransientDockableFloater +	, public LLEventTimer  {  public:  	LOG_CLASS(LLIMConversation);  	LLIMConversation(const LLUUID& session_id); +	~LLIMConversation();  	// reload all message with new settings of visual modes  	static void processChatHistoryStyleUpdate(); @@ -75,13 +80,16 @@ protected:  	// set the enable/disable state for the Call button  	virtual void enableDisableCallBtn() = 0; -//	/* virtual */ void updateTitleButtons(); +	void buildParticipantList(); +	void onSortMenuItemClicked(const LLSD& userdata); +	/*virtual*/ BOOL tick(); -	LLPanelChatControlPanel* mControlPanel;  	bool mIsNearbyChat;  	bool mIsP2PChat; +	LLLayoutPanel* mParticipantListPanel; +	LLParticipantList* mParticipantList;  	LLUUID mSessionID;  	LLButton* mExpandCollapseBtn; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 5339bcb936..c99da9e9c1 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -44,7 +44,6 @@  //#include "lllayoutstack.h"  #include "lllineeditor.h"  #include "lllogchat.h" -#include "llpanelimcontrolpanel.h"  #include "llscreenchannel.h"  #include "llsyswellwindow.h"  #include "lltrans.h" @@ -82,29 +81,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)  	{  		mIsP2PChat = mSession->isP2PSessionType();  		mSessionInitialized = mSession->mSessionInitialized; -		  		mDialog = mSession->mType; -		switch (mDialog) -		{ -		case IM_SESSION_CONFERENCE_START: -			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); -			break; -		case IM_SESSION_GROUP_START: -			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); -			break; -		case IM_SESSION_INVITE: -			if (gAgent.isInGroup(mSessionID)) -			{ -				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this); -			} -			else -			{ -				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this); -			} -			break; -		default: -			break; -		}  	}  	setOverlapsScreenChannel(true); @@ -113,24 +90,6 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)  	setDocked(true);  } -// static -void* LLIMFloater::createPanelGroupControl(void* userdata) -{ -	LLIMFloater *self = (LLIMFloater*) userdata; -	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID); -	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml"); -	return self->mControlPanel; -} - -// static -void* LLIMFloater::createPanelAdHocControl(void* userdata) -{ -	LLIMFloater *self = (LLIMFloater*) userdata; -	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID); -	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml"); -	return self->mControlPanel; -} -  void LLIMFloater::onFocusLost()  {  	LLIMModel::getInstance()->resetActiveSessionID(); @@ -409,8 +368,10 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,  }  // virtual -void LLIMFloater::draw() +BOOL LLIMFloater::tick()  { +	BOOL parents_retcode = LLIMConversation::tick(); +  	if ( mMeTyping )  	{  		// Time out if user hasn't typed for a while. @@ -420,7 +381,7 @@ void LLIMFloater::draw()  		}  	} -	LLTransientDockableFloater::draw(); +	return parents_retcode;  }  //static @@ -643,16 +604,14 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)  	if (mSessionID != im_session_id)  	{  		mSessionID = im_session_id; -  		setKey(im_session_id); -		if (mControlPanel) -		{ -		mControlPanel->setSessionId(im_session_id); -	} +  		boundVoiceChannel();  		mSession = LLIMModel::getInstance()->findIMSession(mSessionID);  		mIsP2PChat = mSession && mSession->isP2PSessionType(); + +		buildParticipantList();  	}  	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) @@ -841,10 +800,14 @@ void LLIMFloater::setTyping(bool typing)  		}  	} -	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); -	if (speaker_mgr) -		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); - +	if (!mIsNearbyChat) +	{ +		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); +		if (speaker_mgr) +		{ +			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); +		} +	}  }  void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing) diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index c7793f73eb..24f28c8aee 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -61,15 +61,15 @@ public:  	/*virtual*/ void setVisible(BOOL visible);  	/*virtual*/ BOOL getVisible();  	// Check typing timeout timer. -	/*virtual*/ void draw(); - -	static void* createPanelGroupControl(void* userdata); -	static void* createPanelAdHocControl(void* userdata); +	/*virtual*/ BOOL tick();  	static LLIMFloater* findInstance(const LLUUID& session_id);  	static LLIMFloater* getInstance(const LLUUID& session_id);  	static void addToHost(const LLUUID& session_id); +	static void* createPanelGroupControl(void* userdata); +	static void* createPanelAdHocControl(void* userdata); +  	// LLFloater overrides  	/*virtual*/ void onClose(bool app_quitting);  	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); @@ -147,7 +147,6 @@ private:  	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);  	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);  	void setTyping(bool typing); -  	void onCallButtonClicked();  	// set the enable/disable state for the Call button diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index f72ddef412..3b6240de44 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -31,7 +31,7 @@  #include "llfloaterreg.h"  #include "lllayoutstack.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llagent.h"  #include "llavatariconctrl.h" diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index c3ac1d32cb..46b1cb5f18 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -907,7 +907,7 @@ const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const  	LLIMSession* session = findIMSession(session_id);  	if (!session)  	{ -		llwarns << "session " << session_id << "does not exist " << llendl; +		llwarns << "session " << session_id << " does not exist " << llendl;  		return LLUUID::null;  	} @@ -2483,8 +2483,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess  		LLChat chat(message);  		chat.mSourceType = CHAT_SOURCE_SYSTEM; -		LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); -		LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); +		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();  		if(nearby_chat)  		{ diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 497690d656..2d7095957e 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -1,8 +1,8 @@  /**    * @file LLNearbyChat.cpp - * @brief Nearby chat history scrolling panel implementation + * @brief LLNearbyChat class implementation   * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc.   *  @@ -25,34 +25,50 @@   */  #include "llviewerprecompiledheaders.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llrootview.h" -//#include "llchatitemscontainerctrl.h" + +#include "message.h" +  #include "lliconctrl.h" +#include "llappviewer.h" +#include "llfloaterreg.h" +#include "lltrans.h" +#include "llimfloatercontainer.h"  #include "llfloatersidepanelcontainer.h"  #include "llfocusmgr.h"  #include "lllogchat.h"  #include "llresizebar.h"  #include "llresizehandle.h" +#include "lldraghandle.h"  #include "llmenugl.h" -#include "llviewermenu.h"//for gMenuHolder - +#include "llviewermenu.h" // for gMenuHolder  #include "llnearbychathandler.h"  #include "llchannelmanager.h" - -#include "llagent.h" 			// gAgent  #include "llchathistory.h"  #include "llstylemap.h" -  #include "llavatarnamecache.h" - -#include "lldraghandle.h" - -#include "llnearbychatbar.h"  #include "llfloaterreg.h"  #include "lltrans.h" +#include "llfirstuse.h" +#include "llnearbychat.h" +#include "llagent.h" // gAgent +#include "llgesturemgr.h" +#include "llmultigesture.h" +#include "llkeyboard.h" +#include "llanimationstates.h" +#include "llviewerstats.h" +#include "llcommandhandler.h" +#include "llviewercontrol.h" +#include "llnavigationbar.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llrootview.h" +#include "llviewerchat.h" +#include "lltranslate.h" + +S32 LLNearbyChat::sLastSpecialChatChannel = 0; + +  // --- 2 functions in the global namespace :( ---  bool isWordsName(const std::string& name)  { @@ -88,90 +104,83 @@ std::string appendTime()  	return timeStr;  } -static const S32 RESIZE_BAR_THICKNESS = 3; -static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat"); +const S32 EXPANDED_HEIGHT = 266; +const S32 COLLAPSED_HEIGHT = 60; +const S32 EXPANDED_MIN_HEIGHT = 150; -LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) -	: LLPanel(p), -	  mChatHistory(NULL) -{ -} +// legacy callback glue +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); -BOOL LLNearbyChat::postBuild() -{ -	//menu -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; +struct LLChatTypeTrigger { +	std::string name; +	EChatType type; +}; -	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); -	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); +static LLChatTypeTrigger sChatTypeTriggers[] = { +	{ "/whisper"	, CHAT_TYPE_WHISPER}, +	{ "/shout"	, CHAT_TYPE_SHOUT} +}; -	 -	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if(menu) -		mPopupMenuHandle = menu->getHandle(); -	gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); +LLNearbyChat::LLNearbyChat(const LLSD& key) +:	LLIMConversation(key), +	mChatBox(NULL), +	mChatHistory(NULL), +	mOutputMonitor(NULL), +	mSpeakerMgr(NULL), +	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT) +{ +	mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); +} -	mChatHistory = getChild<LLChatHistory>("chat_history"); +//virtual +BOOL LLNearbyChat::postBuild() +{ +	mChatBox = getChild<LLLineEditor>("chat_editor"); -    return LLPanel::postBuild(); -} +	mChatBox->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this)); +	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); +	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); +	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this)); +	mChatBox->setIgnoreArrowKeys( FALSE );  +	mChatBox->setCommitOnFocusLost( FALSE ); +	mChatBox->setRevertOnEsc( FALSE ); +	mChatBox->setIgnoreTab(TRUE); +	mChatBox->setPassDelete(TRUE); +	mChatBox->setReplaceNewlinesWithSpaces(FALSE); +	mChatBox->setEnableLineHistory(TRUE); +	mChatBox->setFont(LLViewerChat::getChatFont()); +	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); +	mOutputMonitor->setVisible(FALSE); -void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args) -{ -	LLChat& tmp_chat = const_cast<LLChat&>(chat); +	// Register for font change notifications +	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1)); -	if(tmp_chat.mTimeStr.empty()) -		tmp_chat.mTimeStr = appendTime(); +	enableResizeCtrls(true, true, false); -	if (!chat.mMuted) -	{ -		tmp_chat.mFromName = chat.mFromName; -		LLSD chat_args; -		if (args) chat_args = args; -		chat_args["use_plain_text_chat_history"] = -				gSavedSettings.getBOOL("PlainTextChatHistory"); -		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); -		chat_args["show_names_for_p2p_conv"] = true; +	addToHost(); -		mChatHistory->appendMessage(chat, chat_args); -	} -} +	//for menu +	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; -void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) -{ -	appendMessage(chat, args); +	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2)); +	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2)); -	if(archive) +	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	if(menu)  	{ -		mMessageArchive.push_back(chat); -		if(mMessageArchive.size()>200) -			mMessageArchive.erase(mMessageArchive.begin()); +		mPopupMenuHandle = menu->getHandle();  	} -	// logging -	if (!args["do_not_log"].asBoolean() -			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat")) -	{ -		std::string from_name = chat.mFromName; - -		if (chat.mSourceType == CHAT_SOURCE_AGENT) -		{ -			// if the chat is coming from an agent, log the complete name -			LLAvatarName av_name; -			LLAvatarNameCache::get(chat.mFromID, &av_name); +	// obsolete, but may be needed for backward compatibility? +	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true); -			if (!av_name.mIsDisplayNameDefault) -			{ -				from_name = av_name.getCompleteName(); -			} -		} +	mChatHistory = getChild<LLChatHistory>("chat_history"); -		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText); -	} +	return LLIMConversation::postBuild();;  }  void LLNearbyChat::onNearbySpeakers() @@ -189,33 +198,40 @@ bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)  {  	std::string str = userdata.asString();  	if(str == "nearby_people") -		onNearbySpeakers();	 +		onNearbySpeakers();  	return false;  } -void LLNearbyChat::removeScreenChat() +void LLNearbyChat::getAllowedRect(LLRect& rect)  { -	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); -	if(chat_channel) -	{ -		chat_channel->removeToastsFromChannel(); -	} +	rect = gViewerWindow->getWorldViewRectScaled();  } - -void	LLNearbyChat::setVisible(BOOL visible) +//////////////////////////////////////////////////////////////////////////////// +// +void LLNearbyChat::onFocusReceived()  { -	if(visible) -	{ -		removeScreenChat(); -	} - -	LLPanel::setVisible(visible); +	setBackgroundOpaque(true); +	LLIMConversation::onFocusReceived();  } +//////////////////////////////////////////////////////////////////////////////// +// +void LLNearbyChat::onFocusLost() +{ +	setBackgroundOpaque(false); +	LLIMConversation::onFocusLost(); +} -void LLNearbyChat::getAllowedRect(LLRect& rect) +BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)  { -	rect = gViewerWindow->getWorldViewRectScaled(); +	//fix for EXT-6625 +	//highlight NearbyChat history whenever mouseclick happen in NearbyChat +	//setting focus to eidtor will force onFocusLost() call that in its turn will change +	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change. + +	if(mChatHistory) +		mChatHistory->setFocus(TRUE); +	return LLPanel::handleMouseDown(x, y, mask);  }  void LLNearbyChat::reloadMessages() @@ -265,9 +281,9 @@ void LLNearbyChat::loadHistory()  		chat.mSourceType = CHAT_SOURCE_AGENT;  		if (from_id.isNull() && SYSTEM_FROM == from) -		{	 +		{  			chat.mSourceType = CHAT_SOURCE_SYSTEM; -			 +  		}  		else if (from_id.isNull())  		{ @@ -280,43 +296,117 @@ void LLNearbyChat::loadHistory()  	}  } -//static -LLNearbyChat* LLNearbyChat::getInstance() +void LLNearbyChat::removeScreenChat()  { -	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); -	return chat_bar->findChild<LLNearbyChat>("nearby_chat"); +	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); +	if(chat_channel) +	{ +		chat_channel->removeToastsFromChannel(); +	}  } -//////////////////////////////////////////////////////////////////////////////// -// -void LLNearbyChat::onFocusReceived() +void	LLNearbyChat::setVisible(BOOL visible)  { -	setBackgroundOpaque(true); -	LLPanel::onFocusReceived(); +	if(visible) +	{ +		removeScreenChat(); +	} + +	LLIMConversation::setVisible(visible);  } -//////////////////////////////////////////////////////////////////////////////// -// -void LLNearbyChat::onFocusLost() +void LLNearbyChat::onCallButtonClicked()  { -	setBackgroundOpaque(false); -	LLPanel::onFocusLost(); +	LLAgent::toggleMicrophone(NULL);  } -BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask) +void LLNearbyChat::enableDisableCallBtn()  { -	//fix for EXT-6625 -	//highlight NearbyChat history whenever mouseclick happen in NearbyChat -	//setting focus to eidtor will force onFocusLost() call that in its turn will change  -	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change. +	// bool btn_enabled = LLAgent::isActionAllowed("speak"); + +	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/); +} + +void LLNearbyChat::addToHost() +{ +	if (LLIMConversation::isChatMultiTab()) +	{ +		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); + +		if (im_box) +		{ +			im_box->addFloater(this, FALSE, LLTabContainer::END); +		} +	} +} + +// virtual +void LLNearbyChat::onOpen(const LLSD& key) +{ +	LLIMConversation::onOpen(key); +	showTranslationCheckbox(LLTranslate::isTranslationConfigured()); +} + +bool LLNearbyChat::applyRectControl() +{ +	bool rect_controlled = LLFloater::applyRectControl(); + +/*	if (!mNearbyChat->getVisible()) +	{ +		reshape(getRect().getWidth(), getMinHeight()); +		enableResizeCtrls(true, true, false); +	} +	else +	{*/ +		enableResizeCtrls(true); +		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); +//	} -	if(mChatHistory) -		mChatHistory->setFocus(TRUE); -	return LLPanel::handleMouseDown(x, y, mask); +	return rect_controlled; +} + +void LLNearbyChat::onChatFontChange(LLFontGL* fontp) +{ +	// Update things with the new font whohoo +	if (mChatBox) +	{ +		mChatBox->setFont(fontp); +	} +} + +//static +LLNearbyChat* LLNearbyChat::getInstance() +{ +	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar"); +} + +//static +//LLNearbyChat* LLNearbyChat::findInstance() +//{ +//	return LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar"); +//} + +void LLNearbyChat::showHistory() +{ +	openFloater(); +	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); +	reshape(getRect().getWidth(), mExpandedHeight); +	enableResizeCtrls(true); +	storeRectControl();  } -void LLNearbyChat::draw() +void LLNearbyChat::showTranslationCheckbox(BOOL show)  { +	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show); +} + +BOOL LLNearbyChat::tick() +{ +	BOOL parents_retcode = LLIMConversation::tick(); + +	displaySpeakingIndicator(); +	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState()); +  	// *HACK: Update transparency type depending on whether our children have focus.  	// This is needed because this floater is chrome and thus cannot accept focus, so  	// the transparency type setting code from LLFloater::setFocus() isn't reached. @@ -325,5 +415,511 @@ void LLNearbyChat::draw()  		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);  	} -	LLPanel::draw(); +	return parents_retcode;  } + +std::string LLNearbyChat::getCurrentChat() +{ +	return mChatBox ? mChatBox->getText() : LLStringUtil::null; +} + +// virtual +BOOL LLNearbyChat::handleKeyHere( KEY key, MASK mask ) +{ +	BOOL handled = FALSE; + +	if( KEY_RETURN == key && mask == MASK_CONTROL) +	{ +		// shout +		sendChat(CHAT_TYPE_SHOUT); +		handled = TRUE; +	} + +	return handled; +} + +BOOL LLNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) +{ +	U32 in_len = in_str.length(); +	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); +	 +	bool string_was_found = false; + +	for (S32 n = 0; n < cnt && !string_was_found; n++) +	{ +		if (in_len <= sChatTypeTriggers[n].name.length()) +		{ +			std::string trigger_trunc = sChatTypeTriggers[n].name; +			LLStringUtil::truncate(trigger_trunc, in_len); + +			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) +			{ +				*out_str = sChatTypeTriggers[n].name; +				string_was_found = true; +			} +		} +	} + +	return string_was_found; +} + +void LLNearbyChat::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) +{ +	LLFirstUse::otherAvatarChatFirst(false); + +	LLNearbyChat* self = (LLNearbyChat *)userdata; + +	LLWString raw_text = self->mChatBox->getWText(); + +	// Can't trim the end, because that will cause autocompletion +	// to eat trailing spaces that might be part of a gesture. +	LLWStringUtil::trimHead(raw_text); + +	S32 length = raw_text.length(); + +	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences +	{ +		gAgent.startTyping(); +	} +	else +	{ +		gAgent.stopTyping(); +	} + +	/* Doesn't work -- can't tell the difference between a backspace +	   that killed the selection vs. backspace at the end of line. +	if (length > 1  +		&& text[0] == '/' +		&& key == KEY_BACKSPACE) +	{ +		// the selection will already be deleted, but we need to trim +		// off the character before +		std::string new_text = raw_text.substr(0, length-1); +		self->mInputEditor->setText( new_text ); +		self->mInputEditor->setCursorToEnd(); +		length = length - 1; +	} +	*/ + +	KEY key = gKeyboard->currentKey(); + +	// Ignore "special" keys, like backspace, arrows, etc. +	if (length > 1  +		&& raw_text[0] == '/' +		&& key < KEY_SPECIAL) +	{ +		// we're starting a gesture, attempt to autocomplete + +		std::string utf8_trigger = wstring_to_utf8str(raw_text); +		std::string utf8_out_str(utf8_trigger); + +		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str)) +		{ +			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); +			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part +			S32 outlength = self->mChatBox->getLength(); // in characters + +			// Select to end of line, starting from the character +			// after the last one the user typed. +			self->mChatBox->setSelection(length, outlength); +		} +		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) +		{ +			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); +			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part +			self->mChatBox->setCursorToEnd(); +		} + +		//llinfos << "GESTUREDEBUG " << trigger  +		//	<< " len " << length +		//	<< " outlen " << out_str.getLength() +		//	<< llendl; +	} +} + +// static +void LLNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) +{ +	// stop typing animation +	gAgent.stopTyping(); +} + +void LLNearbyChat::onChatBoxFocusReceived() +{ +	mChatBox->setEnabled(!gDisconnected); +} + +EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str) +{ +	U32 length = str.length(); +	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); +	 +	for (S32 n = 0; n < cnt; n++) +	{ +		if (length >= sChatTypeTriggers[n].name.length()) +		{ +			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); + +			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) +			{ +				U32 trigger_length = sChatTypeTriggers[n].name.length(); + +				// It's to remove space after trigger name +				if (length > trigger_length && str[trigger_length] == ' ') +					trigger_length++; + +				str = str.substr(trigger_length, length); + +				if (CHAT_TYPE_NORMAL == type) +					return sChatTypeTriggers[n].type; +				else +					break; +			} +		} +	} + +	return type; +} + +void LLNearbyChat::sendChat( EChatType type ) +{ +	if (mChatBox) +	{ +		LLWString text = mChatBox->getConvertedText(); +		if (!text.empty()) +		{ +			// store sent line in history, duplicates will get filtered +			mChatBox->updateHistory(); +			// Check if this is destined for another channel +			S32 channel = 0; +			stripChannelNumber(text, &channel); +			 +			std::string utf8text = wstring_to_utf8str(text); +			// Try to trigger a gesture, if not chat to a script. +			std::string utf8_revised_text; +			if (0 == channel) +			{ +				// discard returned "found" boolean +				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); +			} +			else +			{ +				utf8_revised_text = utf8text; +			} + +			utf8_revised_text = utf8str_trim(utf8_revised_text); + +			type = processChatTypeTriggers(type, utf8_revised_text); + +			if (!utf8_revised_text.empty()) +			{ +				// Chat with animation +				sendChatFromViewer(utf8_revised_text, type, TRUE); +			} +		} + +		mChatBox->setText(LLStringExplicit("")); +	} + +	gAgent.stopTyping(); + +	// If the user wants to stop chatting on hitting return, lose focus +	// and go out of chat mode. +	if (gSavedSettings.getBOOL("CloseChatOnReturn")) +	{ +		stopChat(); +	} +} + + +void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args) +{ +	LLChat& tmp_chat = const_cast<LLChat&>(chat); + +	if(tmp_chat.mTimeStr.empty()) +		tmp_chat.mTimeStr = appendTime(); + +	if (!chat.mMuted) +	{ +		tmp_chat.mFromName = chat.mFromName; +		LLSD chat_args; +		if (args) chat_args = args; +		chat_args["use_plain_text_chat_history"] = +				gSavedSettings.getBOOL("PlainTextChatHistory"); +		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); +		chat_args["show_names_for_p2p_conv"] = true; + +		mChatHistory->appendMessage(chat, chat_args); +	} +} + +void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) +{ +	appendMessage(chat, args); + +	if(archive) +	{ +		mMessageArchive.push_back(chat); +		if(mMessageArchive.size()>200) +			mMessageArchive.erase(mMessageArchive.begin()); +	} + +	// logging +	if (!args["do_not_log"].asBoolean() +			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat")) +	{ +		std::string from_name = chat.mFromName; + +		if (chat.mSourceType == CHAT_SOURCE_AGENT) +		{ +			// if the chat is coming from an agent, log the complete name +			LLAvatarName av_name; +			LLAvatarNameCache::get(chat.mFromID, &av_name); + +			if (!av_name.mIsDisplayNameDefault) +			{ +				from_name = av_name.getCompleteName(); +			} +		} + +		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText); +	} +} + + +void LLNearbyChat::onChatBoxCommit() +{ +	if (mChatBox->getText().length() > 0) +	{ +		sendChat(CHAT_TYPE_NORMAL); +	} + +	gAgent.stopTyping(); +} + +void LLNearbyChat::displaySpeakingIndicator() +{ +	LLSpeakerMgr::speaker_list_t speaker_list; +	LLUUID id; + +	id.setNull(); +	mSpeakerMgr->update(TRUE); +	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE); + +	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) +	{ +		LLPointer<LLSpeaker> s = *i; +		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) +		{ +			id = s->mID; +			break; +		} +	} + +	if (!id.isNull()) +	{ +		mOutputMonitor->setVisible(TRUE); +		mOutputMonitor->setSpeakerId(id); +	} +	else +	{ +		mOutputMonitor->setVisible(FALSE); +	} +} + +void LLNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) +{ +	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); +} + +void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) +{ +	// Look for "/20 foo" channel chats. +	S32 channel = 0; +	LLWString out_text = stripChannelNumber(wtext, &channel); +	std::string utf8_out_text = wstring_to_utf8str(out_text); +	std::string utf8_text = wstring_to_utf8str(wtext); + +	utf8_text = utf8str_trim(utf8_text); +	if (!utf8_text.empty()) +	{ +		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); +	} + +	// Don't animate for chats people can't hear (chat to scripts) +	if (animate && (channel == 0)) +	{ +		if (type == CHAT_TYPE_WHISPER) +		{ +			lldebugs << "You whisper " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); +		} +		else if (type == CHAT_TYPE_NORMAL) +		{ +			lldebugs << "You say " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); +		} +		else if (type == CHAT_TYPE_SHOUT) +		{ +			lldebugs << "You shout " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); +		} +		else +		{ +			llinfos << "send_chat_from_viewer() - invalid volume" << llendl; +			return; +		} +	} +	else +	{ +		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) +		{ +			lldebugs << "Channel chat: " << utf8_text << llendl; +		} +	} + +	send_chat_from_viewer(utf8_out_text, type, channel); +} + +// static  +void LLNearbyChat::startChat(const char* line) +{ +	LLNearbyChat* cb = LLNearbyChat::getInstance(); + +	if (cb ) +	{ +		cb->setVisible(TRUE); +		cb->setFocus(TRUE); +		cb->mChatBox->setFocus(TRUE); + +		if (line) +		{ +			std::string line_string(line); +			cb->mChatBox->setText(line_string); +		} + +		cb->mChatBox->setCursorToEnd(); +	} +} + +// Exit "chat mode" and do the appropriate focus changes +// static +void LLNearbyChat::stopChat() +{ +	LLNearbyChat* cb = LLNearbyChat::getInstance(); + +	if (cb) +	{ +		cb->mChatBox->setFocus(FALSE); + +		// stop typing animation +		gAgent.stopTyping(); +	} +} + +// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. +// Otherwise returns input and channel 0. +LLWString LLNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel) +{ +	if (mesg[0] == '/' +		&& mesg[1] == '/') +	{ +		// This is a "repeat channel send" +		*channel = sLastSpecialChatChannel; +		return mesg.substr(2, mesg.length() - 2); +	} +	else if (mesg[0] == '/' +			 && mesg[1] +			 && LLStringOps::isDigit(mesg[1])) +	{ +		// This a special "/20" speak on a channel +		S32 pos = 0; + +		// Copy the channel number into a string +		LLWString channel_string; +		llwchar c; +		do +		{ +			c = mesg[pos+1]; +			channel_string.push_back(c); +			pos++; +		} +		while(c && pos < 64 && LLStringOps::isDigit(c)); +		 +		// Move the pointer forward to the first non-whitespace char +		// Check isspace before looping, so we can handle "/33foo" +		// as well as "/33 foo" +		while(c && iswspace(c)) +		{ +			c = mesg[pos+1]; +			pos++; +		} +		 +		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); +		*channel = sLastSpecialChatChannel; +		return mesg.substr(pos, mesg.length() - pos); +	} +	else +	{ +		// This is normal chat. +		*channel = 0; +		return mesg; +	} +} + +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) +{ +	LLMessageSystem* msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_ChatFromViewer); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast(_PREHASH_ChatData); +	msg->addStringFast(_PREHASH_Message, utf8_out_text); +	msg->addU8Fast(_PREHASH_Type, type); +	msg->addS32("Channel", channel); + +	gAgent.sendReliableMessage(); + +	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +} + +class LLChatCommandHandler : public LLCommandHandler +{ +public: +	// not allowed from outside the app +	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } + +    // Your code here +	bool handle(const LLSD& tokens, const LLSD& query_map, +				LLMediaCtrl* web) +	{ +		bool retval = false; +		// Need at least 2 tokens to have a valid message. +		if (tokens.size() < 2) +		{ +			retval = false; +		} +		else +		{ +		S32 channel = tokens[0].asInteger(); +			// VWR-19499 Restrict function to chat channels greater than 0. +			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) +			{ +				retval = true; +		// Send unescaped message, see EXT-6353. +		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); +		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); +			} +			else +			{ +				retval = false; +				// Tell us this is an unsupported SLurl. +			} +		} +		return retval; +	} +}; + +// Creating the object registers with the dispatcher. +LLChatCommandHandler gChatHandler; diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 62a41c17cb..b38111defa 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -1,8 +1,8 @@ - /**  +/**    * @file llnearbychat.h - * @brief nearby chat history scrolling panel implementation + * @brief LLNearbyChat class definition   * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * $LicenseInfo:firstyear=2002&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc.   *  @@ -24,9 +24,16 @@   * $/LicenseInfo$   */ -#ifndef LL_LLNEARBYCHAT_H_ -#define LL_LLNEARBYCHAT_H_ +#ifndef LL_LLNEARBYCHAT_H +#define LL_LLNEARBYCHAT_H +#include "llimconversation.h" +#include "llcombobox.h" +#include "llgesturemgr.h" +#include "llchat.h" +#include "llvoiceclient.h" +#include "lloutputmonitorctrl.h" +#include "llspeakers.h"  #include "llscrollbar.h"  #include "llviewerchat.h"  #include "llpanel.h" @@ -35,32 +42,88 @@ class LLResizeBar;  class LLChatHistory;  class LLNearbyChat -	: public LLPanel +	:	public LLIMConversation  {  public: -	LLNearbyChat(const Params& p = LLPanel::getDefaultParams()); +	// constructor for inline chat-bars (e.g. hosted in chat history window) +	LLNearbyChat(const LLSD& key); +	~LLNearbyChat() {} -	BOOL	postBuild			(); - -	/** @param archive true - to save a message to the chat history log */ -	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());	 -	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata); -	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata); - -	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask); -	virtual void	draw(); +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key);  	// focus overrides  	/*virtual*/ void	onFocusLost();  	/*virtual*/ void	onFocusReceived(); -	 +  	/*virtual*/ void	setVisible(BOOL visible); -	 +  	void loadHistory();      void reloadMessages(); -	static LLNearbyChat* getInstance();  	void removeScreenChat(); +	static LLNearbyChat* getInstance(); + +	void addToHost(); + +	/** @param archive true - to save a message to the chat history log */ +	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD()); +	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata); +	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata); + +	LLLineEditor* getChatBox() { return mChatBox; } + +	//virtual void draw(); + +	std::string getCurrentChat(); + +	virtual BOOL handleKeyHere( KEY key, MASK mask ); +	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask); + +	static void startChat(const char* line); +	static void stopChat(); + +	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); +	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + +	void showHistory(); +	void showTranslationCheckbox(BOOL show); + +protected: +	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); +	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); +	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); +	void onChatBoxFocusReceived(); + +	void sendChat( EChatType type ); +	void onChatBoxCommit(); +	void onChatFontChange(LLFontGL* fontp); + +	/* virtual */ bool applyRectControl(); + +	void onToggleNearbyChatPanel(); + +	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); +	EChatType processChatTypeTriggers(EChatType type, std::string &str); + +	void displaySpeakingIndicator(); + +	void onCallButtonClicked(); + +	// set the enable/disable state for the Call button +	virtual void enableDisableCallBtn(); + +	// Which non-zero channel did we last chat on? +	static S32 sLastSpecialChatChannel; + +	LLLineEditor*			mChatBox; +	LLOutputMonitorCtrl*	mOutputMonitor; +	LLLocalSpeakerMgr*		mSpeakerMgr; + +	S32 mExpandedHeight; + +	/*virtual*/ BOOL tick(); +  private:  	void	getAllowedRect		(LLRect& rect); @@ -68,14 +131,10 @@ private:  	void appendMessage(const LLChat& chat, const LLSD &args = 0);  	void	onNearbySpeakers	(); - -private:  	LLHandle<LLView>	mPopupMenuHandle; +	std::vector<LLChat> mMessageArchive;  	LLChatHistory*		mChatHistory; -	std::vector<LLChat> mMessageArchive;  };  #endif - - diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp deleted file mode 100644 index 68934be11a..0000000000 --- a/indra/newview/llnearbychatbar.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/**  - * @file llnearbychatbar.cpp - * @brief LLNearbyChatBar class implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "message.h" - -#include "llappviewer.h" -#include "llfloaterreg.h" -#include "lltrans.h" -#include "llimfloatercontainer.h" -#include "llfirstuse.h" -#include "llnearbychatbar.h" -#include "llagent.h" -#include "llgesturemgr.h" -#include "llmultigesture.h" -#include "llkeyboard.h" -#include "llanimationstates.h" -#include "llviewerstats.h" -#include "llcommandhandler.h" -#include "llviewercontrol.h" -#include "llnavigationbar.h" -#include "llwindow.h" -#include "llviewerwindow.h" -#include "llrootview.h" -#include "llviewerchat.h" -#include "llnearbychat.h" -#include "lltranslate.h" - -#include "llresizehandle.h" - -S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; - -const S32 EXPANDED_HEIGHT = 266; -const S32 COLLAPSED_HEIGHT = 60; -const S32 EXPANDED_MIN_HEIGHT = 150; - -// legacy callback glue -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); - -struct LLChatTypeTrigger { -	std::string name; -	EChatType type; -}; - -static LLChatTypeTrigger sChatTypeTriggers[] = { -	{ "/whisper"	, CHAT_TYPE_WHISPER}, -	{ "/shout"	, CHAT_TYPE_SHOUT} -}; - -LLNearbyChatBar::LLNearbyChatBar(const LLSD& key) -:	LLIMConversation(key), -	mChatBox(NULL), -	mNearbyChat(NULL), -	mOutputMonitor(NULL), -	mSpeakerMgr(NULL), -	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT) -{ -	mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); -} - -//virtual -BOOL LLNearbyChatBar::postBuild() -{ -	mChatBox = getChild<LLLineEditor>("chat_box"); - -	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); -	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); -	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); -	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this)); - -	mChatBox->setIgnoreArrowKeys( FALSE );  -	mChatBox->setCommitOnFocusLost( FALSE ); -	mChatBox->setRevertOnEsc( FALSE ); -	mChatBox->setIgnoreTab(TRUE); -	mChatBox->setPassDelete(TRUE); -	mChatBox->setReplaceNewlinesWithSpaces(FALSE); -	mChatBox->setEnableLineHistory(TRUE); -	mChatBox->setFont(LLViewerChat::getChatFont()); - -	mNearbyChat = getChildView("nearby_chat"); - -	LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat"); -	show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this)); - -	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); -	mOutputMonitor->setVisible(FALSE); - -	gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE); - -	mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility")); - -	// Register for font change notifications -	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1)); - -	enableResizeCtrls(true, true, false); - -	addToHost(); - -	return LLIMConversation::postBuild();; -} - -void LLNearbyChatBar::enableDisableCallBtn() -{ -	// bool btn_enabled = LLAgent::isActionAllowed("speak"); - -	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/); -} - -void LLNearbyChatBar::addToHost() -{ -	if (LLIMConversation::isChatMultiTab()) -	{ -		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance(); - -		if (im_box) -		{ -			im_box->addFloater(this, FALSE, LLTabContainer::END); -		} -	} -} - -// virtual -void LLNearbyChatBar::onOpen(const LLSD& key) -{ -	LLIMConversation::onOpen(key); -	showTranslationCheckbox(LLTranslate::isTranslationConfigured()); -} - -bool LLNearbyChatBar::applyRectControl() -{ -	bool rect_controlled = LLFloater::applyRectControl(); - -	if (!mNearbyChat->getVisible()) -	{ -		reshape(getRect().getWidth(), getMinHeight()); -		enableResizeCtrls(true, true, false); -	} -	else -	{ -		enableResizeCtrls(true); -		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); -	} -	 -	return rect_controlled; -} - -void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp) -{ -	// Update things with the new font whohoo -	if (mChatBox) -	{ -		mChatBox->setFont(fontp); -	} -} - -//static -LLNearbyChatBar* LLNearbyChatBar::getInstance() -{ -	return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar"); -} - -//static -//LLNearbyChatBar* LLNearbyChatBar::findInstance() -//{ -//	return LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar"); -//} - -void LLNearbyChatBar::showHistory() -{ -	openFloater(); - -	if (!getChildView("nearby_chat")->getVisible()) -	{ -		onToggleNearbyChatPanel(); -	} -} - -void LLNearbyChatBar::showTranslationCheckbox(BOOL show) -{ -	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show); -} - -void LLNearbyChatBar::draw() -{ -	displaySpeakingIndicator(); -	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState()); -	LLIMConversation::draw(); -} - -std::string LLNearbyChatBar::getCurrentChat() -{ -	return mChatBox ? mChatBox->getText() : LLStringUtil::null; -} - -// virtual -BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) -{ -	BOOL handled = FALSE; - -	if( KEY_RETURN == key && mask == MASK_CONTROL) -	{ -		// shout -		sendChat(CHAT_TYPE_SHOUT); -		handled = TRUE; -	} - -	return handled; -} - -BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str) -{ -	U32 in_len = in_str.length(); -	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); -	 -	bool string_was_found = false; - -	for (S32 n = 0; n < cnt && !string_was_found; n++) -	{ -		if (in_len <= sChatTypeTriggers[n].name.length()) -		{ -			std::string trigger_trunc = sChatTypeTriggers[n].name; -			LLStringUtil::truncate(trigger_trunc, in_len); - -			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc)) -			{ -				*out_str = sChatTypeTriggers[n].name; -				string_was_found = true; -			} -		} -	} - -	return string_was_found; -} - -void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) -{ -	LLFirstUse::otherAvatarChatFirst(false); - -	LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; - -	LLWString raw_text = self->mChatBox->getWText(); - -	// Can't trim the end, because that will cause autocompletion -	// to eat trailing spaces that might be part of a gesture. -	LLWStringUtil::trimHead(raw_text); - -	S32 length = raw_text.length(); - -	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences -	{ -		gAgent.startTyping(); -	} -	else -	{ -		gAgent.stopTyping(); -	} - -	/* Doesn't work -- can't tell the difference between a backspace -	   that killed the selection vs. backspace at the end of line. -	if (length > 1  -		&& text[0] == '/' -		&& key == KEY_BACKSPACE) -	{ -		// the selection will already be deleted, but we need to trim -		// off the character before -		std::string new_text = raw_text.substr(0, length-1); -		self->mInputEditor->setText( new_text ); -		self->mInputEditor->setCursorToEnd(); -		length = length - 1; -	} -	*/ - -	KEY key = gKeyboard->currentKey(); - -	// Ignore "special" keys, like backspace, arrows, etc. -	if (length > 1  -		&& raw_text[0] == '/' -		&& key < KEY_SPECIAL) -	{ -		// we're starting a gesture, attempt to autocomplete - -		std::string utf8_trigger = wstring_to_utf8str(raw_text); -		std::string utf8_out_str(utf8_trigger); - -		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str)) -		{ -			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part -			S32 outlength = self->mChatBox->getLength(); // in characters - -			// Select to end of line, starting from the character -			// after the last one the user typed. -			self->mChatBox->setSelection(length, outlength); -		} -		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str)) -		{ -			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part -			self->mChatBox->setCursorToEnd(); -		} - -		//llinfos << "GESTUREDEBUG " << trigger  -		//	<< " len " << length -		//	<< " outlen " << out_str.getLength() -		//	<< llendl; -	} -} - -// static -void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) -{ -	// stop typing animation -	gAgent.stopTyping(); -} - -void LLNearbyChatBar::onChatBoxFocusReceived() -{ -	mChatBox->setEnabled(!gDisconnected); -} - -EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str) -{ -	U32 length = str.length(); -	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers); -	 -	for (S32 n = 0; n < cnt; n++) -	{ -		if (length >= sChatTypeTriggers[n].name.length()) -		{ -			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length()); - -			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name)) -			{ -				U32 trigger_length = sChatTypeTriggers[n].name.length(); - -				// It's to remove space after trigger name -				if (length > trigger_length && str[trigger_length] == ' ') -					trigger_length++; - -				str = str.substr(trigger_length, length); - -				if (CHAT_TYPE_NORMAL == type) -					return sChatTypeTriggers[n].type; -				else -					break; -			} -		} -	} - -	return type; -} - -void LLNearbyChatBar::sendChat( EChatType type ) -{ -	if (mChatBox) -	{ -		LLWString text = mChatBox->getConvertedText(); -		if (!text.empty()) -		{ -			// store sent line in history, duplicates will get filtered -			mChatBox->updateHistory(); -			// Check if this is destined for another channel -			S32 channel = 0; -			stripChannelNumber(text, &channel); -			 -			std::string utf8text = wstring_to_utf8str(text); -			// Try to trigger a gesture, if not chat to a script. -			std::string utf8_revised_text; -			if (0 == channel) -			{ -				// discard returned "found" boolean -				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); -			} -			else -			{ -				utf8_revised_text = utf8text; -			} - -			utf8_revised_text = utf8str_trim(utf8_revised_text); - -			type = processChatTypeTriggers(type, utf8_revised_text); - -			if (!utf8_revised_text.empty()) -			{ -				// Chat with animation -				sendChatFromViewer(utf8_revised_text, type, TRUE); -			} -		} - -		mChatBox->setText(LLStringExplicit("")); -	} - -	gAgent.stopTyping(); - -	// If the user wants to stop chatting on hitting return, lose focus -	// and go out of chat mode. -	if (gSavedSettings.getBOOL("CloseChatOnReturn")) -	{ -		stopChat(); -	} -} - - -void LLNearbyChatBar::onToggleNearbyChatPanel() -{ -	LLView* nearby_chat = getChildView("nearby_chat"); - -	if (nearby_chat->getVisible()) -	{ -		if (!isMinimized()) -		{ -			mExpandedHeight = getRect().getHeight(); -		} -		setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT); -		nearby_chat->setVisible(FALSE); -		reshape(getRect().getWidth(), COLLAPSED_HEIGHT); -		enableResizeCtrls(true, true, false); -		storeRectControl(); -	} -	else -	{ -		nearby_chat->setVisible(TRUE); -		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT); -		reshape(getRect().getWidth(), mExpandedHeight); -		enableResizeCtrls(true); -		storeRectControl(); -	} - -	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible()); -} - -void LLNearbyChatBar::reloadMessages() -{ -	LLNearbyChat::getInstance()->reloadMessages(); -} - -void LLNearbyChatBar::setMinimized(BOOL b) -{ -	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat"); -	// when unminimizing with nearby chat visible, go ahead and kill off screen chats -	if (!b && nearby_chat->getVisible()) -	{ -		nearby_chat->removeScreenChat(); -	} -		LLFloater::setMinimized(b); -} - -void LLNearbyChatBar::onChatBoxCommit() -{ -	if (mChatBox->getText().length() > 0) -	{ -		sendChat(CHAT_TYPE_NORMAL); -	} - -	gAgent.stopTyping(); -} - -void LLNearbyChatBar::displaySpeakingIndicator() -{ -	LLSpeakerMgr::speaker_list_t speaker_list; -	LLUUID id; - -	id.setNull(); -	mSpeakerMgr->update(TRUE); -	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE); - -	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) -	{ -		LLPointer<LLSpeaker> s = *i; -		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) -		{ -			id = s->mID; -			break; -		} -	} - -	if (!id.isNull()) -	{ -		mOutputMonitor->setVisible(TRUE); -		mOutputMonitor->setSpeakerId(id); -	} -	else -	{ -		mOutputMonitor->setVisible(FALSE); -	} -} - -void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) -{ -	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); -} - -void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) -{ -	// Look for "/20 foo" channel chats. -	S32 channel = 0; -	LLWString out_text = stripChannelNumber(wtext, &channel); -	std::string utf8_out_text = wstring_to_utf8str(out_text); -	std::string utf8_text = wstring_to_utf8str(wtext); - -	utf8_text = utf8str_trim(utf8_text); -	if (!utf8_text.empty()) -	{ -		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); -	} - -	// Don't animate for chats people can't hear (chat to scripts) -	if (animate && (channel == 0)) -	{ -		if (type == CHAT_TYPE_WHISPER) -		{ -			lldebugs << "You whisper " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_NORMAL) -		{ -			lldebugs << "You say " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_SHOUT) -		{ -			lldebugs << "You shout " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); -		} -		else -		{ -			llinfos << "send_chat_from_viewer() - invalid volume" << llendl; -			return; -		} -	} -	else -	{ -		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) -		{ -			lldebugs << "Channel chat: " << utf8_text << llendl; -		} -	} - -	send_chat_from_viewer(utf8_out_text, type, channel); -} - -// static  -void LLNearbyChatBar::startChat(const char* line) -{ -	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance(); - -	if (cb ) -	{ -		cb->setVisible(TRUE); -		cb->setFocus(TRUE); -		cb->mChatBox->setFocus(TRUE); - -		if (line) -		{ -			std::string line_string(line); -			cb->mChatBox->setText(line_string); -		} - -		cb->mChatBox->setCursorToEnd(); -	} -} - -// Exit "chat mode" and do the appropriate focus changes -// static -void LLNearbyChatBar::stopChat() -{ -	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance(); - -	if (cb) -	{ -		cb->mChatBox->setFocus(FALSE); - -		// stop typing animation -		gAgent.stopTyping(); -	} -} - -// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -// Otherwise returns input and channel 0. -LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) -{ -	if (mesg[0] == '/' -		&& mesg[1] == '/') -	{ -		// This is a "repeat channel send" -		*channel = sLastSpecialChatChannel; -		return mesg.substr(2, mesg.length() - 2); -	} -	else if (mesg[0] == '/' -			 && mesg[1] -			 && LLStringOps::isDigit(mesg[1])) -	{ -		// This a special "/20" speak on a channel -		S32 pos = 0; - -		// Copy the channel number into a string -		LLWString channel_string; -		llwchar c; -		do -		{ -			c = mesg[pos+1]; -			channel_string.push_back(c); -			pos++; -		} -		while(c && pos < 64 && LLStringOps::isDigit(c)); -		 -		// Move the pointer forward to the first non-whitespace char -		// Check isspace before looping, so we can handle "/33foo" -		// as well as "/33 foo" -		while(c && iswspace(c)) -		{ -			c = mesg[pos+1]; -			pos++; -		} -		 -		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); -		*channel = sLastSpecialChatChannel; -		return mesg.substr(pos, mesg.length() - pos); -	} -	else -	{ -		// This is normal chat. -		*channel = 0; -		return mesg; -	} -} - -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ChatFromViewer); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ChatData); -	msg->addStringFast(_PREHASH_Message, utf8_out_text); -	msg->addU8Fast(_PREHASH_Type, type); -	msg->addS32("Channel", channel); - -	gAgent.sendReliableMessage(); - -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} - -class LLChatCommandHandler : public LLCommandHandler -{ -public: -	// not allowed from outside the app -	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } - -    // Your code here -	bool handle(const LLSD& tokens, const LLSD& query_map, -				LLMediaCtrl* web) -	{ -		bool retval = false; -		// Need at least 2 tokens to have a valid message. -		if (tokens.size() < 2) -		{ -			retval = false; -		} -		else -		{ -		S32 channel = tokens[0].asInteger(); -			// VWR-19499 Restrict function to chat channels greater than 0. -			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG)) -			{ -				retval = true; -		// Send unescaped message, see EXT-6353. -		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString())); -		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel); -			} -			else -			{ -				retval = false; -				// Tell us this is an unsupported SLurl. -			} -		} -		return retval; -	} -}; - -// Creating the object registers with the dispatcher. -LLChatCommandHandler gChatHandler; - - diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h deleted file mode 100644 index b7c4c993c6..0000000000 --- a/indra/newview/llnearbychatbar.h +++ /dev/null @@ -1,105 +0,0 @@ -/**  - * @file llnearbychatbar.h - * @brief LLNearbyChatBar class definition - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLNEARBYCHATBAR_H -#define LL_LLNEARBYCHATBAR_H - -#include "llimconversation.h" -#include "llcombobox.h" -#include "llgesturemgr.h" -#include "llchat.h" -#include "llnearbychat.h" -#include "llvoiceclient.h" -#include "lloutputmonitorctrl.h" -#include "llspeakers.h" - -class LLNearbyChatBar :	public LLIMConversation -{ -public: -	// constructor for inline chat-bars (e.g. hosted in chat history window) -	LLNearbyChatBar(const LLSD& key); -	~LLNearbyChatBar() {} - -	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key); - -	static LLNearbyChatBar* getInstance(); -//	static LLNearbyChatBar* findInstance(); - -	void addToHost(); - -	void reloadMessages(); -	LLLineEditor* getChatBox() { return mChatBox; } - -	virtual void draw(); - -	std::string getCurrentChat(); -	virtual BOOL handleKeyHere( KEY key, MASK mask ); - -	static void startChat(const char* line); -	static void stopChat(); - -	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); -	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); - -	void showHistory(); -	void showTranslationCheckbox(BOOL show); -	/*virtual*/void setMinimized(BOOL b); - -protected: -	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str); -	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); -	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); -	void onChatBoxFocusReceived(); - -	void sendChat( EChatType type ); -	void onChatBoxCommit(); -	void onChatFontChange(LLFontGL* fontp); - -	/* virtual */ bool applyRectControl(); - -	void onToggleNearbyChatPanel(); - -	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); -	EChatType processChatTypeTriggers(EChatType type, std::string &str); - -	void displaySpeakingIndicator(); - -	// set the enable/disable state for the Call button -	virtual void enableDisableCallBtn(); - -	// Which non-zero channel did we last chat on? -	static S32 sLastSpecialChatChannel; - -	LLLineEditor*			mChatBox; -	LLView*					mNearbyChat; -	LLOutputMonitorCtrl*	mOutputMonitor; -	LLLocalSpeakerMgr*		mSpeakerMgr; - -	S32 mExpandedHeight; -}; - -#endif diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp index a63e1fb76e..61815d1864 100644 --- a/indra/newview/llnearbychatbarlistener.cpp +++ b/indra/newview/llnearbychatbarlistener.cpp @@ -29,14 +29,14 @@  #include "llviewerprecompiledheaders.h"  #include "llnearbychatbarlistener.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llagent.h"  #include "llchat.h" -LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar) +LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChat & chatbar)    : LLEventAPI("LLChatBar",                 "LLChatBar listener to (e.g.) sendChat, etc."),  	mChatbar(chatbar) diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h index 9af9bc1f7b..0537275424 100644 --- a/indra/newview/llnearbychatbarlistener.h +++ b/indra/newview/llnearbychatbarlistener.h @@ -33,17 +33,17 @@  #include "lleventapi.h"  class LLSD; -class LLNearbyChatBar; +class LLNearbyChat;  class LLNearbyChatBarListener : public LLEventAPI  {  public: -	LLNearbyChatBarListener(LLNearbyChatBar & chatbar); +	LLNearbyChatBarListener(LLNearbyChat & chatbar);  private:      void sendChat(LLSD const & chat_data) const; -	LLNearbyChatBar & mChatbar; +	LLNearbyChat & mChatbar;  };  #endif // LL_LLNEARBYCHATBARLISTENER_H diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index f26cc85019..e91a3fc334 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -40,7 +40,7 @@  #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance  #include "llviewerwindow.h"//for screen channel position -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llrootview.h"  #include "lllayoutstack.h" @@ -487,9 +487,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,  	if(chat_msg.mText.empty())  		return;//don't process empty messages -	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar"); - -	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat"); +	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();  	// Build notification data   	LLSD chat; @@ -558,8 +556,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,  	sChatWatcher->post(chat); -	if( !chat_bar->isMinimized() -		&& nearby_chat->isInVisibleChain()  +	if( nearby_chat->isInVisibleChain()  		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT  			&& gSavedSettings.getBOOL("UseChatBubbles") )  		|| mChannel.isDead() diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index a1d5db2e27..507c6686fd 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -29,7 +29,7 @@  #include "llfloaterreg.h"  #include "llnearbychat.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llnotificationhandler.h"  #include "llnotifications.h"  #include "lltoastnotifypanel.h" @@ -86,8 +86,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)  		// don't show toast if Nearby Chat is opened  		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance(); -		LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance(); -		if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible()) +		if (!nearby_chat->isMinimized() && nearby_chat->getVisible())  		{  			return false;  		} diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index bc4097cd93..389baa86cd 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -41,85 +41,4 @@  #include "llspeakers.h"  #include "lltrans.h" -LLPanelChatControlPanel::~LLPanelChatControlPanel() -{ -} -BOOL LLPanelChatControlPanel::postBuild() -{ -	return TRUE; -} - -void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id) -{ -	//Method is called twice for AdHoc and Group chat. Second time when server init reply received -	mSessionId = session_id; -} - - -LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id): -mParticipantList(NULL) -{ -} - -BOOL LLPanelGroupControlPanel::postBuild() -{ - -	return LLPanelChatControlPanel::postBuild(); -} - -LLPanelGroupControlPanel::~LLPanelGroupControlPanel() -{ -	delete mParticipantList; -	mParticipantList = NULL; -} - -// virtual -void LLPanelGroupControlPanel::draw() -{ -	// Need to resort the participant list if it's in sort by recent speaker order. -	if (mParticipantList) -		mParticipantList->update(); -	LLPanelChatControlPanel::draw(); -} - - -void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata) -{ -	// TODO: Check this code when when sort order menu will be added. (EM) -	if (false && !mParticipantList) -		return; - -	std::string chosen_item = userdata.asString(); - -	if (chosen_item == "sort_name") -	{ -		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME); -	} - -} - -void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id) -{ -	LLPanelChatControlPanel::setSessionId(session_id); - -	mGroupID = session_id; - -	// for group and Ad-hoc chat we need to include agent into list -	if(!mParticipantList) -	{ -		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id); -		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false); -	} -} - - -LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id) -{ -} - -BOOL LLPanelAdHocControlPanel::postBuild() -{ -	//We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat -	return LLPanelChatControlPanel::postBuild(); -} diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 5ced32a9ab..df1962f5fe 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -134,7 +134,6 @@  #include "llscriptfloater.h"  #include "llfloatermodelpreview.h"  #include "llcommandhandler.h" -#include "llnearbychatbar.h"  // *NOTE: Please add files in alphabetical order to keep merges easy. @@ -187,8 +186,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);  	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>); -	LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatBar>); -  	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);  	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>); @@ -211,6 +208,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	  	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>); +	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);  	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("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>); diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index a32a78cbf9..c7d37e102e 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -40,7 +40,7 @@  #include "llviewermessage.h" // send_guid_sound_trigger  #include "llviewernetwork.h"  #include "llagent.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  // Globals  LLViewerGestureList gGestureList; @@ -130,7 +130,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )  	{  		// Don't play nodding animation, since that might not blend  		// with the gesture animation. -		LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); +		LLNearbyChat::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);  	}  } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1aa9fd8a45..385d3cd29a 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -31,7 +31,7 @@  #include "llmath.h"  #include "llagent.h"  #include "llagentcamera.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llviewercontrol.h"  #include "llfocusmgr.h"  #include "llmorphview.h" @@ -534,7 +534,7 @@ void stop_moving( EKeystate s )  void start_chat( EKeystate s )  {  	// start chat -	LLNearbyChatBar::startChat(NULL); +	LLNearbyChat::startChat(NULL);  }  void start_gesture( EKeystate s ) @@ -543,15 +543,15 @@ void start_gesture( EKeystate s )  	if (KEYSTATE_UP == s &&  		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))  	{ - 		if (LLNearbyChatBar::getInstance()->getCurrentChat().empty()) + 		if (LLNearbyChat::getInstance()->getCurrentChat().empty())   		{   			// No existing chat in chat editor, insert '/' - 			LLNearbyChatBar::startChat("/"); + 			LLNearbyChat::startChat("/");   		}   		else   		{   			// Don't overwrite existing text in chat editor - 			LLNearbyChatBar::startChat(NULL); + 			LLNearbyChat::startChat(NULL);   		}  	}  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 32f693b009..5b8cf52298 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -185,7 +185,7 @@  #include "llviewerjoystick.h"  #include "llviewernetwork.h"  #include "llpostprocess.h" -#include "llnearbychatbar.h" +#include "llnearbychat.h"  #include "llagentui.h"  #include "llwearablelist.h" @@ -2482,7 +2482,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	// Traverses up the hierarchy  	if( keyboard_focus )  	{ -		LLNearbyChatBar* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar"); +		LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");  		if (nearby_chat)  		{ @@ -2549,11 +2549,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&   		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )  	{ -		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar")->getChatBox(); +		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar")->getChatBox();  		if (chat_editor)  		{  			// passing NULL here, character will be added later when it is handled by character handler. -			LLNearbyChatBar::getInstance()->startChat(NULL); +			LLNearbyChat::getInstance()->startChat(NULL);  			return TRUE;  		}  	} diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml deleted file mode 100644 index 7688525e13..0000000000 --- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml +++ /dev/null @@ -1,202 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - open_positioning="specified" - specified_left="10" - specified_bottom="10" - background_visible="true" - default_tab_group="1" - height="355" - help_topic="chat_bar" - layout="topleft" - name="chat_bar" - can_dock="false" - can_minimize="true" - can_close="true" - visible="false" - width="394" - can_resize="true" - can_tear_off="false" - min_width="250" - min_height="80" - single_instance="true" - title="Nearby chat"> -    <floater.string name="call_btn_start">VoicePTT_Off</floater.string> -    <floater.string name="call_btn_stop">VoicePTT_On</floater.string> -    <floater.string -     name="collapse_icon" -     value="TabIcon_Open_Off"/> -    <floater.string -     name="expand_icon" -     value="TabIcon_Close_Off"/> -    <floater.string -     name="tear_off_icon" -     value="tearoffbox.tga"/> -    <floater.string -     name="return_icon" -     value="Icon_Dock_Foreground"/> -     <view -        follows="all" -        layout="topleft" -        name="contents_view" -        top="0" -        left="0" -        height="355" -        width="394"> -      <panel -         follows="left|top|right" -         layout="topleft" -         name="toolbar_panel" -         top="0" -         left="0" -         height="35" -         width="394">          -             <menu_button -                 menu_filename="menu_im_session_showmodes.xml" -                 follows="top|left" -                 height="25" -                 image_hover_unselected="Toolbar_Left_Over" -                 image_overlay="OptionsMenu_Off" -                 image_selected="Toolbar_Left_Selected" -                 image_unselected="Toolbar_Left_Off" -                 layout="topleft" -                 left="5" -                 name="view_options_btn" -                 top="5" -                 width="31" /> -             <button -                 follows="top|left" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="AddItem_Off" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 top="5" -                 left_pad="4" -                 name="add_btn" -                 width="31"> -                 <commit_callback -                    function="Chats.add" /> -             </button>    -             <button -                 follows="top|left" -                 height="25" -                 image_hover_unselected="Toolbar_Right_Over" -                 image_overlay="VoicePTT_Off" -                 image_selected="Toolbar_Right_Selected" -                 image_unselected="Toolbar_Right_Off" -                 layout="topleft" -                 top="5" -                 left_pad="4" -                 name="voice_call_btn" -                 width="31"> -                 <commit_callback -                    function="Chats.add" /> -             </button> -             <button -                 follows="right|top" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="Icon_Close_Foreground" -                 image_selected="Toolbar_Middle_Selected" -                 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 top="5" -                 left="283" -                 name="close_btn" -                 width="31"> -             </button> -             <button -                 follows="right|top" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="TabIcon_Open_Off" -                 image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 top="5" -                 left_pad="5" -                 name="expand_collapse_btn" -                 width="31"> -             </button> -             <button -                 follows="right|top" -                 height="25" -                 image_hover_unselected="Toolbar_Middle_Over" -                 image_overlay="tearoffbox.tga" -                 image_selected="Toolbar_Middle_Selected" -             	 image_unselected="Toolbar_Middle_Off" -                 layout="topleft" -                 top="5" -                 left_pad="5" -                 name="tear_off_btn" -                 width="31"> -             </button> -     </panel> -    <panel -        top="35" -        left="0" -        class="panel_nearby_chat" -        follow="all" -        width="390" -        height="0" -        visible="false" -        filename="panel_nearby_chat.xml" -        name="nearby_chat" /> -    <panel -    	width="390" -    	height="10" -    	visible="true" /> -    <panel width="394"  -           height="31"  -           left="0"  -           name="bottom_panel" -           bottom="-1"  -           follows="left|right|bottom"  -           tab_group="1"> -      <line_editor -        border_style="line" -        border_thickness="1" -        follows="left|right" -        height="20" -        label="Click here to chat." -        layout="topleft" -        left="1" -        max_length_bytes="1023" -        name="chat_box" -        tool_tip="Press Enter to say, Ctrl+Enter to shout" -        top="2" -        width="384" /> -      <output_monitor -        auto_update="true" -        follows="right" -        draw_border="false" -        height="16" -        layout="topleft" -        left_pad="-24" -        mouse_opaque="true" -        name="chat_zone_indicator" -        top="6" -        visible="true" -        width="20" /> -      <button -        follows="right" -        visible="false" -        is_toggle="true" -        width="20" -        top="2" -        layout="topleft" -        left_pad="12" -        image_disabled="ComboButton_UpOff" -        image_unselected="ComboButton_UpOff" -        image_selected="ComboButton_On" -        image_pressed="ComboButton_UpSelected" -        image_pressed_selected="ComboButton_Selected" -        height="23" -        chrome="true" -        name="show_nearby_chat" -        tool_tip="Shows/hides nearby chat log"> -      </button> -    </panel> -  </view> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index a332bb5b12..c5cacab9f4 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -138,18 +138,24 @@    top_pad="0"    left="0">      <layout_panel -      name="im_control_panel_holder" +      name="speakers_list_panel"        min_width="115"        width="150"         height="310"         auto_resize="false"> -      <panel -        name="panel_im_control_panel" -        layout="topleft" -        height="310" -        width="150"  -        follows="all"/> -      </layout_panel> +            <avatar_list +             color="DkGray2" +             follows="all" +             height="100" +             ignore_online_status="true" +             layout="topleft" +             name="speakers_list" +             opaque="false" +             show_info_btn="true" +             show_profile_btn="false" +             show_speaking_indicator="false" +             width="145" /> +    </layout_panel>      <layout_panel         default_tab_group="3"         left="0" @@ -158,27 +164,82 @@         height="200"  	    width="254"         user_resize="true"> -        <chat_history -	     font="SansSerifSmall" -         follows="all" -         height="170" -         name="chat_history" -         parse_highlights="true" -         parse_urls="true" -         left="1" -         width="249"> -        </chat_history> -        <line_editor -         bottom="0" -         follows="left|right|bottom" -	     font="SansSerifSmall" -         height="20" -         label="To" -         layout="bottomleft" -         name="chat_editor" -         tab_group="3" -         width="249"> -        </line_editor> +         <layout_stack +          animate="true"  +          default_tab_group="2" +          follows="all" +          height="200" +          width="254" +          layout="topleft" +          orientation="vertical" +          name="chat_area" +          tab_group="1" +          left_pad="0" +          top="0"> +            <layout_panel +             auto_resize="false" +             height="26" +             layout="topleft" +             left_delta="0" +             name="translate_chat_checkbox_lp" +             top_delta="0" +             visible="true" +             width="230"> +                <check_box +                 top="10" +                 control_name="TranslateChat" +                 enabled="true" +                 height="16" +                 label="Translate chat" +                 layout="topleft" +                 left="5" +                 name="translate_chat_checkbox" +                 width="230" /> +            </layout_panel> +            <layout_panel +             auto_resize="false" +             height="170" +             layout="topleft" +             left_delta="0" +             name="translate_chat_checkbox_lp" +             top_delta="0" +             visible="true" +             width="230">       +           		<chat_history +    	     		font="SansSerifSmall" +             		follows="all" +             		height="170" +            	 	name="chat_history" +             		parse_highlights="true" +             		parse_urls="true" +             		left="1" +             		width="229"> +            	</chat_history> +            	<line_editor +             		bottom="0" +             		follows="left|right|bottom" +	         		font="SansSerifSmall" +             		height="20" +             		label="To" +             		layout="bottomleft" +             		name="chat_editor" +             		tab_group="3" +             		width="230"> +            	</line_editor> +            	<output_monitor +                 auto_update="true" +                 follows="right" +                 draw_border="false" +                 height="16" +                 layout="topleft" +                 left_pad="-24" +                 mouse_opaque="true" +                 name="chat_zone_indicator" +                 top="6" +                 visible="true" +                 width="20" />           	 +            </layout_panel> +        </layout_stack>      </layout_panel>    </layout_stack>      </view> diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml deleted file mode 100644 index d68fa6ca6c..0000000000 --- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="215" - name="panel_im_control_panel" - width="150"> -    <layout_stack -     mouse_opaque="false" -     border_size="0" -     clip="false" -     follows="all" -     height="215" -     layout="topleft" -     left="3" -     name="vertical_stack" -     orientation="vertical" -     top="0" -     width="147"> -        <layout_panel -         auto_resize="true" -         follows="top|left" -         height="130" -         layout="topleft" -         left="0" -         min_height="0" -         mouse_opaque="false" -         width="147" -         top="0" -         name="speakers_list_panel"> -            <avatar_list -             color="DkGray2" -             follows="all" -             height="130" -             ignore_online_status="true" -             layout="topleft" -             name="speakers_list" -             opaque="false" -             show_info_btn="true" -             show_profile_btn="false" -             show_speaking_indicator="false" -             width="147" /> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="top|left|right" -         height="25" -         layout="topleft" -         min_height="25" -         width="130" -         name="call_btn_panel" -         visible="false"> -            <button -             follows="all" -             height="20" -             label="Call" -             name="call_btn" -             width="130" -             top="0" /> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="top|left|right" -         height="25" -         layout="topleft" -         min_height="25" -         width="130" -         name="end_call_btn_panel" -         visible="false"> -            <button -             follows="all" -             height="20" -             label="Leave Call" -             name="end_call_btn" -             top="0"/> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="top|left|right" -         height="25" -         layout="topleft" -         min_height="25" -         width="130" -         name="voice_ctrls_btn_panel" -         visible="false"> -            <button -             follows="all" -             height="20" -             label="Voice Controls" -             name="voice_ctrls_btn" -             top="0" -             use_ellipses="true" /> -        </layout_panel> -    </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml deleted file mode 100644 index a5295ebe01..0000000000 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel - border="false" - follows="all" - height="238" - name="panel_im_control_panel" - width="150"> -    <layout_stack -     mouse_opaque="false" -     border_size="0" -     clip="false" -     follows="all" -     height="238" -     layout="topleft" -     left="5" -     name="vertical_stack" -     orientation="vertical" -     top="0" -     width="145"> -        <layout_panel -         auto_resize="true" -         follows="top|left" -         height="100" -         layout="topleft" -         min_height="0" -         mouse_opaque="false" -         width="145" -         top="0" -         name="speakers_list_panel"> -            <avatar_list -             color="DkGray2" -             follows="all" -             height="100" -             ignore_online_status="true" -             layout="topleft" -             name="speakers_list" -             opaque="false" -             show_info_btn="true" -             show_profile_btn="false" -             show_speaking_indicator="false" -             width="145" /> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="top|left|right" -         height="28" -         layout="topleft" -         min_height="28" -         width="130" -         name="voice_ctrls_btn_panel" -         visible="false"> -            <button -             follows="all" -             height="23" -             label="Open Voice Controls" -             name="voice_ctrls_btn" -             use_ellipses="true" /> -        </layout_panel> -    </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml index b415ba780d..4de56b424e 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml @@ -6,16 +6,17 @@   help_topic="nearby_chat"   layout="topleft"   name="nearby_chat" - width="394"> + width="242" + height="169">    <layout_stack     follows="all" -   height="278" +   height="164"     layout="topleft"     left="0"     name="stack"     top="5"     orientation="vertical" -   width="394"> +   width="242">      <layout_panel       auto_resize="false"       height="26" @@ -24,7 +25,7 @@       name="translate_chat_checkbox_lp"       top_delta="0"       visible="true" -     width="387"> +     width="230">        <check_box         top="10"         control_name="TranslateChat" @@ -34,15 +35,15 @@         layout="topleft"         left="5"         name="translate_chat_checkbox" -       width="374" /> +       width="230" />      </layout_panel>      <layout_panel       auto_resize="true" -     height="256" +     height="138"       left_delta="0"       layout="topleft"       name="chat_history_lp" -     width="394"> +     width="242">        <chat_history         bg_readonly_color="ChatHistoryBgColor"         bg_writeable_color="ChatHistoryBgColor" @@ -50,7 +51,7 @@         layout="topleft"         left="5"         left_widget_pad="0" -       height="240" +       height="138"         name="chat_history"         parse_highlights="true"         parse_urls="true" @@ -58,7 +59,7 @@         text_color="ChatHistoryTextColor"         text_readonly_color="ChatHistoryTextColor"         top="0" -       width="384" /> +       width="237" />      </layout_panel>    </layout_stack>  </panel>  | 
