diff options
46 files changed, 1392 insertions, 633 deletions
diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 7b010d6739..acd0da61a4 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -65,6 +65,12 @@ typedef enum e_chat_audible_level  	CHAT_AUDIBLE_FULLY = 1  } EChatAudible; +typedef enum e_chat_style +{ +	CHAT_STYLE_NORMAL, +	CHAT_STYLE_IRC +}EChatStyle; +  // A piece of chat  class LLChat  { @@ -79,7 +85,8 @@ public:  		mMuted(FALSE),  		mTime(0.0),  		mPosAgent(), -		mURL() +		mURL(), +		mChatStyle(CHAT_STYLE_NORMAL)  	{ }  	std::string		mText;		// UTF-8 line of text @@ -92,6 +99,7 @@ public:  	F64				mTime;		// viewer only, seconds from viewer start  	LLVector3		mPosAgent;  	std::string		mURL; +	EChatStyle		mChatStyle;  };  #endif diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 8b0fcc68c4..a7f899ce41 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -48,6 +48,7 @@ set(llui_SOURCE_FILES      lllayoutstack.cpp      lllineeditor.cpp      lllink.cpp +    lllistctrl.cpp      llmenugl.cpp      llmodaldialog.cpp      llmultifloater.cpp  @@ -124,6 +125,7 @@ set(llui_HEADER_FILES      lllazyvalue.h      lllineeditor.h      lllink.h +    lllistctrl.h      llmenugl.h      llmodaldialog.h      llmultifloater.h  diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 13f862f3af..556ff80991 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -66,9 +66,12 @@ static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container")  #include "llscrollingpanellist.h"  #include "llcontainerview.h"  #include "llpanel.h" +#include "lllistctrl.h" +  static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list");  static ScrollContainerRegistry::Register<LLContainerView> r2("container_view");  static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML); +static ScrollContainerRegistry::Register<LLListCtrl> r4("list");  LLScrollContainer::Params::Params()  :	is_opaque("opaque"), diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 7ff942268d..1ab04054ff 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -257,6 +257,13 @@ BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask)  	return handled;  } +BOOL LLUICtrl::handleDoubleClick(S32 x, S32 y, MASK mask) +{ +	BOOL handled = LLView::handleDoubleClick(x, y, mask); +	mDoubleClickSignal(this, x, y, mask); +	return handled; +} +  // can't tab to children of a non-tab-stop widget  BOOL LLUICtrl::canFocusChildren() const  { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 3e2e1f41a1..5011adcfe9 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -166,6 +166,7 @@ public:  	/*virtual*/ BOOL 	handleMouseUp(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);  	// From LLFocusableElement  	/*virtual*/ void	setFocus( BOOL b ); @@ -239,6 +240,8 @@ public:  	boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); }  	boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); } +	boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { return mDoubleClickSignal.connect(cb); } +  	// *TODO: Deprecate; for backwards compatability only:  	boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data);	  	boost::signals2::connection setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb ); @@ -273,6 +276,8 @@ protected:  	mouse_signal_t		mMouseUpSignal;  	mouse_signal_t		mRightMouseDownSignal;  	mouse_signal_t		mRightMouseUpSignal; + +	mouse_signal_t		mDoubleClickSignal;      LLViewModelPtr  mViewModel; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 4770807ac7..83d45f0dfa 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -2735,3 +2735,17 @@ LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const  	}  	return *mDefaultWidgets;  } +void	LLView::notifyParent(const LLSD& info) +{ +	LLView* parent = getParent(); +	if(parent) +		parent->notifyParent(info); +} +void	LLView::notifyChilds(const LLSD& info) +{ +	for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) +	{ +		(*child_it)->notifyChilds(info); +	} +} + diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ecc6bf47da..87298b5292 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -549,6 +549,9 @@ public:  	virtual void	handleReshape(const LLRect& rect, bool by_user); +	virtual void	notifyParent(const LLSD& info); +	virtual void	notifyChilds(const LLSD& info); +  protected:  	void			drawDebugRect();  	void			drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b95c5d46dd..05459cfcac 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -66,7 +66,6 @@ include_directories(  set(viewer_SOURCE_FILES      llaccordionctrltab.cpp      llaccordionctrl.cpp -    llactiveimwindow.cpp      llagent.cpp      llagentaccess.cpp      llagentdata.cpp @@ -518,7 +517,6 @@ set(viewer_HEADER_FILES      ViewerInstall.cmake      llaccordionctrltab.h      llaccordionctrl.h -    llactiveimwindow.h      llagent.h      llagentaccess.h      llagentdata.h diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index f557adf6a6..080d540f4a 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -220,6 +220,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str  #endif  	setScrollPos(pos); +	LLRect	rect = getRequiredRect(); + +	LLSD params; +	params["action"] = "size_changes"; +	params["width"] = rect.getWidth(); +	params["height"] = rect.getHeight(); + +	getParent()->notifyParent(params); +  	return have_names;  } diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 2403e891f6..fe13d4f652 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -40,13 +40,12 @@  #include "lllayoutstack.h"  #include "llnearbychatbar.h"  #include "llsplitbutton.h" +#include "llsyswellwindow.h"  #include "llfloatercamera.h"  #include "llimpanel.h" -#include "llactiveimwindow.h"  LLBottomTray::LLBottomTray(const LLSD&)  :	mChicletPanel(NULL), -	mIMWell(NULL),  	mSysWell(NULL),  	mTalkBtn(NULL),  	mNearbyChatBar(NULL), @@ -58,10 +57,11 @@ LLBottomTray::LLBottomTray(const LLSD&)  	LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");  	mChicletPanel = getChild<LLChicletPanel>("chiclet_list"); -	mIMWell = getChild<LLNotificationChiclet>("im_well");  	mSysWell = getChild<LLNotificationChiclet>("sys_well");  	mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window")); +	LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->setSysWell(mSysWell); +  	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));  	LLSplitButton* presets = getChild<LLSplitButton>("presets"); @@ -76,8 +76,6 @@ LLBottomTray::LLBottomTray(const LLSD&)  	// Necessary for focus movement among child controls  	setFocusRoot(TRUE); - -	LLActiveIMWindow::init(mIMWell);  }  BOOL LLBottomTray::postBuild() @@ -119,6 +117,34 @@ void* LLBottomTray::createNearbyChatBar(void* userdata)  	return new LLNearbyChatBar();  } +LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id) +{ +	if(session_id.isNull()) +	{ +		return NULL; +	} + +	LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id); +	if (!im)  +	{ +		return NULL; //should never happen +	} + +	switch(im->getDialogType()) +	{ +	case IM_NOTHING_SPECIAL: +		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id); +		break; +	case IM_SESSION_GROUP_START: +	case IM_SESSION_INVITE: +		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id); +		break; +	default: +		return NULL; +		break; +	} +} +  //virtual  void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)  { @@ -130,12 +156,18 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam  		}  		else  		{ -			LLIMChiclet* chiclet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id); -			chiclet->setIMSessionName(name); -			chiclet->setOtherParticipantId(other_participant_id); +			LLIMChiclet* chiclet = createIMChiclet(session_id); +			if(chiclet) +			{ +				chiclet->setIMSessionName(name); +				chiclet->setOtherParticipantId(other_participant_id); +			} +			else +			{ +				llerrs << "Could not create chiclet" << llendl; +			}  		}  	} -	updateImChicletCount();  }  //virtual @@ -145,7 +177,6 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id)  	{  		getChicletPanel()->removeChiclet(session_id);  	} -	updateImChicletCount();  }  //virtual @@ -185,7 +216,3 @@ void LLBottomTray::setVisible(BOOL visible)  	}  } -void LLBottomTray::updateImChicletCount() { -	U32 chicletCount = mChicletPanel->getChicletCount(); -	mIMWell->setCounter(chicletCount); -} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 7f606339bc..a8fe65a9d3 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -42,6 +42,7 @@ class LLLayoutStack;  class LLNotificationChiclet;  class LLTalkButton;  class LLNearbyChatBar; +class LLIMChiclet;  class LLBottomTray   	: public LLSingleton<LLBottomTray> @@ -55,7 +56,6 @@ public:  	BOOL postBuild();  	LLChicletPanel*		getChicletPanel()	{return mChicletPanel;} -	LLNotificationChiclet*	getIMWell()	{return mIMWell;}  	LLNotificationChiclet*	getSysWell()	{return mSysWell;}  	LLNearbyChatBar*		getNearbyChatBar()	{return mNearbyChatBar;} @@ -69,7 +69,6 @@ public:  	virtual void setVisible(BOOL visible);  private: -	void updateImChicletCount();  protected: @@ -79,8 +78,12 @@ protected:  	static void* createNearbyChatBar(void* userdata); +	/** +	 * Creates IM Chiclet based on session type (IM chat or Group chat) +	 */ +	LLIMChiclet* createIMChiclet(const LLUUID& session_id); +  	LLChicletPanel* 	mChicletPanel; -	LLNotificationChiclet* 	mIMWell;  	LLNotificationChiclet* 	mSysWell;  	LLTalkButton* 		mTalkBtn;  	LLNearbyChatBar*	mNearbyChatBar; diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index 9399e1f68d..fb5ab8ec5a 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -239,8 +239,9 @@ std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_widt  		{  			if (wtext[cur] == '\n')  				cur += 1; -			else -				final_wtext += '\n'; + +			// There is no need to to cut line ending symbols found in origin string, see EXT-702. +			final_wtext += '\n';  		}  	} diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 6b4dfa73a4..1109d8174f 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -47,13 +47,11 @@  #include "llvoicecontrolpanel.h"  #include "llgroupmgr.h" -static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu"; -static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu"; -  static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");  static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");  static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); -static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im"); +static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t4("chiclet_im_p2p"); +static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t5("chiclet_im_group");  S32 LLNotificationChiclet::mUreadSystemNotifications = 0;  S32 LLNotificationChiclet::mUreadIMNotifications = 0; @@ -187,9 +185,48 @@ void LLChiclet::setValue(const LLSD& value)  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// -LLIMChiclet::Params::Params() +LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p) +: LLChiclet(p) +{ +} + +void LLIMChiclet::onMouseDown() +{ +	LLIMFloater::toggle(getSessionId()); +	setCounter(0); +} + +BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask) +{ +	onMouseDown(); +	return LLChiclet::handleMouseDown(x, y, mask); +} + +void LLIMChiclet::draw() +{ +	LLUICtrl::draw(); + +	//if we have a docked floater, we want to position it relative to us +	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", getSessionId()); + +	if (im_floater && im_floater->isDocked())  +	{ +		S32 x, y; +		getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y); +		im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom);	 +		//set this so the docked floater knows it's been positioned and can now draw +		im_floater->setPositioned(true); +	} + +	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLIMP2PChiclet::Params::Params()  : avatar_icon("avatar_icon") -, group_insignia("group_insignia")  , unread_notifications("unread_notifications")  , speaker("speaker")  , show_speaker("show_speaker") @@ -197,14 +234,8 @@ LLIMChiclet::Params::Params()  	rect(LLRect(0, 25, 45, 0));  	avatar_icon.name("avatar_icon"); -	avatar_icon.visible(false);  	avatar_icon.rect(LLRect(0, 25, 25, 0)); -	//it's an icon for a group in case there is a group chat created -	group_insignia.name("group_icon"); -	group_insignia.visible(false); -	group_insignia.rect(LLRect(0, 25, 25, 0)); -  	unread_notifications.name("unread");  	unread_notifications.rect(LLRect(25, 25, 45, 0));  	unread_notifications.font(LLFontGL::getFontSansSerif()); @@ -218,25 +249,16 @@ LLIMChiclet::Params::Params()  	show_speaker = false;  } -LLIMChiclet::LLIMChiclet(const Params& p) -: LLChiclet(p) -, LLGroupMgrObserver(LLUUID()) -, mAvatarCtrl(NULL) -, mGroupInsignia(NULL) +LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) +: LLIMChiclet(p) +, mChicletIconCtrl(NULL)  , mCounterCtrl(NULL)  , mSpeakerCtrl(NULL) -, mShowSpeaker(p.show_speaker)  , mPopupMenu(NULL)  {  	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; -	mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); -	addChild(mAvatarCtrl); - -	//Before setOtherParticipantId() we are UNAWARE which dialog type will it be -	//so keeping both icons for all both p2p and group chat cases -	LLIconCtrl::Params grop_icon_params = p.group_insignia; -	mGroupInsignia = LLUICtrlFactory::create<LLIconCtrl>(grop_icon_params); -	addChild(mGroupInsignia); +	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); +	addChild(mChicletIconCtrl);  	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;  	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); @@ -249,16 +271,10 @@ LLIMChiclet::LLIMChiclet(const Params& p)  	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);  	addChild(mSpeakerCtrl); -	setShowSpeaker(getShowSpeaker()); -} - -LLIMChiclet::~LLIMChiclet() -{ -	LLGroupMgr::getInstance()->removeObserver(this); +	setShowSpeaker(p.show_speaker);  } - -void LLIMChiclet::setCounter(S32 counter) +void LLIMP2PChiclet::setCounter(S32 counter)  {  	mCounterCtrl->setCounter(counter); @@ -279,15 +295,9 @@ void LLIMChiclet::setCounter(S32 counter)  	}  } -void LLIMChiclet::onMouseDown() +LLRect LLIMP2PChiclet::getRequiredRect()  { -	LLIMFloater::toggle(getSessionId()); -	setCounter(0); -} - -LLRect LLIMChiclet::getRequiredRect() -{ -	LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0); +	LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0);  	if(getShowCounter())  	{  		rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); @@ -299,169 +309,234 @@ LLRect LLIMChiclet::getRequiredRect()  	return rect;  } -void LLIMChiclet::setShowCounter(bool show) +void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)  { -	bool needs_resize = getShowCounter() != show; - -	LLChiclet::setShowCounter(show); -	mCounterCtrl->setVisible(getShowCounter()); - -	if(needs_resize) -	{ -		onChicletSizeChanged(); -	} +	LLIMChiclet::setOtherParticipantId(other_participant_id); +	mChicletIconCtrl->setValue(getOtherParticipantId());  } - -void LLIMChiclet::setSessionId(const LLUUID& session_id) +void LLIMP2PChiclet::updateMenuItems()  { -	LLChiclet::setSessionId(session_id); +	if(!mPopupMenu) +		return; +	if(getSessionId().isNull()) +		return; -	//for a group chat session_id = group_id -	LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id); -	if (!im) return; //should never happen -	 -	EInstantMessage type = im->getDialogType(); -	if (type == IM_SESSION_INVITE || type == IM_SESSION_GROUP_START) -	{ -		if (!gAgent.isInGroup(session_id)) return; +	bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); -		if (mGroupInsignia) { -			LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); -			LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); -			if (group_data && group_data->mInsigniaID.notNull()) -			{ -				mGroupInsignia->setVisible(TRUE); -				mGroupInsignia->setValue(group_data->mInsigniaID); -			} -			else -			{ -				mID = session_id; //needed for LLGroupMgrObserver -				grp_mgr->addObserver(this); -				grp_mgr->sendGroupPropertiesRequest(session_id); -			} -		} -	}	 +	mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); +	mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);  } -void LLIMChiclet::setIMSessionName(const std::string& name) +BOOL LLIMP2PChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)  { -	setToolTip(name); +	if(!mPopupMenu) +	{ +		createPopupMenu(); +	} + +	if (mPopupMenu) +	{ +		updateMenuItems(); +		mPopupMenu->arrangeAndClear(); +		LLMenuGL::showPopup(this, mPopupMenu, x, y); +	} + +	return TRUE;  } -//session id should be set before calling this -void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id) +void LLIMP2PChiclet::createPopupMenu()  { -	llassert(getSessionId().notNull()); +	if(mPopupMenu) +	{ +		llwarns << "Menu already exists" << llendl; +		return; +	} +	if(getSessionId().isNull()) +	{ +		return; +	} -	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); +	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); -	//all alive sessions have alive floater, haven't they? -	llassert(floater); +	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> +		("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +} -	mOtherParticipantId = other_participant_id; +void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) +{ +	std::string level = user_data.asString(); +	LLUUID other_participant_id = getOtherParticipantId(); -	if (mAvatarCtrl && floater->getDialogType() == IM_NOTHING_SPECIAL) +	if("profile" == level) +	{ +		LLAvatarActions::showProfile(other_participant_id); +	} +	else if("im" == level) +	{ +		LLAvatarActions::startIM(other_participant_id); +	} +	else if("add" == level)  	{ -		mAvatarCtrl->setVisible(TRUE); -		mAvatarCtrl->setValue(other_participant_id); +		LLAvatarActions::requestFriendshipDialog(other_participant_id);  	}  } - -void LLIMChiclet::changed(LLGroupChange gc) +void LLIMP2PChiclet::setShowSpeaker(bool show)  { -	LLSD group_insignia = mGroupInsignia->getValue(); -	if (group_insignia.isUUID() && group_insignia.asUUID().notNull()) return; +	LLIMChiclet::setShowSpeaker(show); -	if (GC_PROPERTIES == gc) +	bool needs_resize = getShowSpeaker() != show; +	mSpeakerCtrl->setVisible(getShowSpeaker()); +	if(needs_resize)  	{ -		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); -		if (group_data && group_data->mInsigniaID.notNull()) -		{ -			mGroupInsignia->setVisible(TRUE); -			mGroupInsignia->setValue(group_data->mInsigniaID); -		} +		onChicletSizeChanged();  	}  } -LLUUID LLIMChiclet::getOtherParticipantId() +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLIMGroupChiclet::Params::Params() +: group_icon("group_icon")  { -	return mOtherParticipantId; +	rect(LLRect(0, 25, 45, 0)); + +	group_icon.name("group_icon"); +	group_icon.rect(LLRect(0, 25, 25, 0)); + +	unread_notifications.name("unread"); +	unread_notifications.rect(LLRect(25, 25, 45, 0)); +	unread_notifications.font(LLFontGL::getFontSansSerif()); +	unread_notifications.font_halign(LLFontGL::HCENTER); +	unread_notifications.v_pad(5); +	unread_notifications.text_color(LLColor4::white); + +	speaker.name("speaker"); +	speaker.rect(LLRect(45, 25, 65, 0)); + +	show_speaker = false;  } -void LLIMChiclet::updateMenuItems() +LLIMGroupChiclet::LLIMGroupChiclet(const Params& p) +: LLIMChiclet(p) +, LLGroupMgrObserver(LLUUID::null) +, mChicletIconCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mPopupMenu(NULL)  { -	if(!mPopupMenu) -		return; -	if(getSessionId().isNull()) -		return; +	LLChicletGroupIconCtrl::Params avatar_params = p.group_icon; +	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params); +	addChild(mChicletIconCtrl); -	if(P2P_MENU_NAME == mPopupMenu->getName()) -	{ -		bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); +	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; +	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); +	addChild(mCounterCtrl); -		mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); -		mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend); -	} +	setCounter(getCounter()); +	setShowCounter(getShowCounter()); + +	LLChicletSpeakerCtrl::Params speaker_params = p.speaker; +	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); +	addChild(mSpeakerCtrl); + +	setShowSpeaker(p.show_speaker);  } -BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask) +LLIMGroupChiclet::~LLIMGroupChiclet()  { -	onMouseDown(); -	return LLChiclet::handleMouseDown(x, y, mask); +	LLGroupMgr::getInstance()->removeObserver(this);  } -void LLIMChiclet::setShowSpeaker(bool show) +void LLIMGroupChiclet::setCounter(S32 counter)  { -	bool needs_resize = getShowSpeaker() != show; - -	mShowSpeaker = show; -	mSpeakerCtrl->setVisible(getShowSpeaker()); +	mCounterCtrl->setCounter(counter); -	if(needs_resize) +	if(getShowCounter())  	{ -		onChicletSizeChanged(); +		LLRect counter_rect = mCounterCtrl->getRect(); +		LLRect required_rect = mCounterCtrl->getRequiredRect(); +		bool needs_resize = required_rect.getWidth() != counter_rect.getWidth(); + +		if(needs_resize) +		{ +			counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth(); +			mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight()); +			mCounterCtrl->setRect(counter_rect); + +			onChicletSizeChanged(); +		}  	}  } -void LLIMChiclet::draw() +LLRect LLIMGroupChiclet::getRequiredRect()  { -	LLUICtrl::draw(); +	LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0); +	if(getShowCounter()) +	{ +		rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); +	} +	if(getShowSpeaker()) +	{ +		rect.mRight += mSpeakerCtrl->getRect().getWidth(); +	} +	return rect; +} -	//if we have a docked floater, we want to position it relative to us -	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", getSessionId()); +void LLIMGroupChiclet::setSessionId(const LLUUID& session_id) +{ +	LLChiclet::setSessionId(session_id); -	if (im_floater && im_floater->isDocked())  +	LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); +	LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); +	if (group_data && group_data->mInsigniaID.notNull())  	{ -		S32 x, y; -		getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y); -		im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom);	 -		//set this so the docked floater knows it's been positioned and can now draw -		im_floater->setPositioned(true); +		mChicletIconCtrl->setValue(group_data->mInsigniaID);  	} +	else +	{ +		if(getSessionId() != mID) +		{ +			grp_mgr->removeObserver(this); +			mID = getSessionId(); +			grp_mgr->addObserver(this); +		} +		grp_mgr->sendGroupPropertiesRequest(session_id); +	} +} -	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); +void LLIMGroupChiclet::changed(LLGroupChange gc) +{ +	if (GC_PROPERTIES == gc) +	{ +		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); +		if (group_data) +		{ +			mChicletIconCtrl->setValue(group_data->mInsigniaID); +		} +	}  } -BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)  {  	if(!mPopupMenu) +	{  		createPopupMenu(); - -	updateMenuItems(); +	}  	if (mPopupMenu)  	{  		mPopupMenu->arrangeAndClear(); +		LLMenuGL::showPopup(this, mPopupMenu, x, y);  	} -	 -	LLMenuGL::showPopup(this, mPopupMenu, x, y);  	return TRUE;  } -void LLIMChiclet::createPopupMenu() +void LLIMGroupChiclet::createPopupMenu()  {  	if(mPopupMenu)  	{ @@ -469,55 +544,41 @@ void LLIMChiclet::createPopupMenu()  		return;  	}  	if(getSessionId().isNull()) +	{  		return; - -	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); -	if(!floater) -		return; +	}  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2)); +	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); -	switch(floater->getDialogType()) -	{ -	case IM_SESSION_GROUP_START: -		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> -			("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -		break; -	case IM_NOTHING_SPECIAL: -		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> -			("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -		break; -	default: -		llwarns << "Unexpected dialog type" << llendl; -		break; -	} +	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> +		("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  } -void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) +void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)  {  	std::string level = user_data.asString(); -	LLUUID other_participant_id = getOtherParticipantId(); +	LLUUID group_id = getSessionId(); -	if("profile" == level) +	if("group chat" == level)  	{ -		LLAvatarActions::showProfile(other_participant_id); +		LLGroupActions::startChat(group_id);  	} -	else if("im" == level) -	{ -		LLAvatarActions::startIM(other_participant_id); -	} -	else if("add" == level) -	{ -		LLAvatarActions::requestFriendshipDialog(other_participant_id); -	} -	else if("group chat" == level) +	else if("info" == level)  	{ -		LLGroupActions::startChat(other_participant_id); +		LLGroupActions::show(group_id);  	} -	else if("info" == level) +} + +void LLIMGroupChiclet::setShowSpeaker(bool show) +{ +	LLIMChiclet::setShowSpeaker(show); + +	bool needs_resize = getShowSpeaker() != show; +	mSpeakerCtrl->setVisible(getShowSpeaker()); +	if(needs_resize)  	{ -		LLGroupActions::show(other_participant_id); +		onChicletSizeChanged();  	}  } @@ -1178,6 +1239,28 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p) +: LLIconCtrl(p) +, mDefaultIcon(p.default_icon) +{ +} + +void LLChicletGroupIconCtrl::setValue(const LLSD& value ) +{ +	if(value.asUUID().isNull()) +	{ +		LLIconCtrl::setValue(mDefaultIcon); +	} +	else +	{ +		LLIconCtrl::setValue(value); +	} +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +  LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)   : LLIconCtrl(p)  { diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index b1e73c9d8d..ba202515a8 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -95,7 +95,7 @@ private:  };  /* - * Class for displaying avatar's icon. + * Class for displaying avatar's icon in P2P chiclet.  */  class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl  { @@ -116,6 +116,36 @@ protected:  	friend class LLUICtrlFactory;  }; +/** + * Class for displaying group's icon in Group chiclet. + */ +class LLChicletGroupIconCtrl : public LLIconCtrl +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLIconCtrl::Params> +	{ +		Optional<std::string> default_icon; + +		Params() +		 : default_icon("default_icon", "default_land_picture.j2c") +		{ +		}; +	}; + +	/** +	 * Sets icon, if value is LLUUID::null - default icon will be set. +	 */ +	virtual void setValue(const LLSD& value ); + +protected: + +	LLChicletGroupIconCtrl(const Params& p); +	friend class LLUICtrlFactory; + +	std::string mDefaultIcon; +}; +  /*   * Class for displaying status of Voice Chat   */ @@ -231,53 +261,40 @@ private:  	chiclet_size_changed_signal_t mChicletSizeChangedSignal;  }; +  /* -* Implements Instant Message chiclet. -* IMChiclet displays avatar's icon, number of unread messages(optional) +* Base class for Instant Message chiclets. +* IMChiclet displays icon, number of unread messages(optional)  * and voice chat status(optional). +* Every chiclet should override LLUICtrl::getRequiredRect and return  +* desired width.  */ -class LLIMChiclet : public LLChiclet, LLGroupMgrObserver +class LLIMChiclet : public LLChiclet  {  public: -	struct Params : public LLInitParam::Block<Params, LLChiclet::Params> -	{ -		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon; - -		Optional<LLIconCtrl::Params> group_insignia; - -		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; - -		Optional<LLChicletSpeakerCtrl::Params> speaker; - -		Optional<bool>	show_speaker; - -		Params(); -	}; - -	/*virtual*/ ~LLIMChiclet(); - -	virtual void setSessionId(const LLUUID& session_id); +	 +	/*virtual*/ ~LLIMChiclet() {};  	/*  	 * Sets IM session name. This name will be displayed in chiclet tooltip.  	*/ -	virtual void setIMSessionName(const std::string& name); +	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }  	/*  	 * Sets id of person/group user is chatting with.  	 * Session id should be set before calling this  	*/ -	virtual void setOtherParticipantId(const LLUUID& other_participant_id); +	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }  	/*  	 * Gets id of person/group user is chatting with.  	 */ -	virtual LLUUID getOtherParticipantId(); +	virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }  	/*  	 * Shows/hides voice chat status control.  	*/ -	virtual void setShowSpeaker(bool show); +	virtual void setShowSpeaker(bool show) { mShowSpeaker = show; }  	/*  	 * Returns voice chat status control visibility. @@ -285,22 +302,6 @@ public:  	virtual bool getShowSpeaker() {return mShowSpeaker;};  	/* -	 * Sets number of unread messages. Will update chiclet's width if number text  -	 * exceeds size of counter and notify it's parent about size change. -	*/ -	/*virtual*/ void setCounter(S32); - -	/* -	 * Returns number of unread messages. -	*/ -	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - -	/* -	 * Shows/hides number of unread messages. -	*/ -	/*virtual*/ void setShowCounter(bool show); - -	/*  	 * Draws border around chiclet.  	*/  	/*virtual*/ void draw(); @@ -313,52 +314,13 @@ public:  	 */  	void onMouseDown(); -	/* -	 * Returns rect, required to display chiclet. -	 * Width is the only valid value. -	*/ -	/*virtual*/ LLRect getRequiredRect(); - -	/** comes from LLGroupMgrObserver */ -	virtual void changed(LLGroupChange gc); -  protected: -	LLIMChiclet(const Params& p); -	friend class LLUICtrlFactory; - -	/* -	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu  -	 * based on other participant's id. -	*/ -	virtual void createPopupMenu(); - -	/* -	 * Processes clicks on chiclet popup menu. -	*/ -	virtual void onMenuItemClicked(const LLSD& user_data); - -	/*  -	 * Enables/disables menus based on relationship with other participant. -	*/ -	virtual void updateMenuItems(); - -	/* -	 * Displays popup menu. -	*/ -	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); +	LLIMChiclet(const LLChiclet::Params& p);  	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);  protected: -	LLChicletAvatarIconCtrl* mAvatarCtrl; - -	/** the icon of a group in case of group chat */ -	LLIconCtrl* mGroupInsignia; -	LLChicletNotificationCounterCtrl* mCounterCtrl; -	LLChicletSpeakerCtrl* mSpeakerCtrl; - -	LLMenuGL* mPopupMenu;  	bool mShowSpeaker; @@ -387,6 +349,160 @@ public:  			sFindChicletsSignal;  }; +/** + * Implements P2P chiclet. + */ +class LLIMP2PChiclet : public LLIMChiclet +{ +public: +	struct Params : public LLInitParam::Block<Params, LLChiclet::Params> +	{ +		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon; + +		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; + +		Optional<LLChicletSpeakerCtrl::Params> speaker; + +		Optional<bool>	show_speaker; + +		Params(); +	}; + +	void setOtherParticipantId(const LLUUID& other_participant_id); + +	/*virtual*/ void setShowSpeaker(bool show); + +	/* +	* Sets number of unread messages. Will update chiclet's width if number text  +	* exceeds size of counter and notify it's parent about size change. +	*/ +	/*virtual*/ void setCounter(S32); + +	/* +	* Returns number of unread messages. +	*/ +	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + +	/* +	* Returns rect, required to display chiclet. +	* Width is the only valid value. +	*/ +	/*virtual*/ LLRect getRequiredRect(); + +protected: +	LLIMP2PChiclet(const Params& p); +	friend class LLUICtrlFactory; + +	/* +	* Creates chiclet popup menu. Will create P2P or Group IM Chat menu  +	* based on other participant's id. +	*/ +	virtual void createPopupMenu(); + +	/* +	* Processes clicks on chiclet popup menu. +	*/ +	virtual void onMenuItemClicked(const LLSD& user_data); + +	/* +	* Displays popup menu. +	*/ +	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + +	/*  +	* Enables/disables menus based on relationship with other participant. +	*/ +	virtual void updateMenuItems(); + +private: + +	LLChicletAvatarIconCtrl* mChicletIconCtrl; +	LLChicletNotificationCounterCtrl* mCounterCtrl; +	LLChicletSpeakerCtrl* mSpeakerCtrl; +	LLMenuGL* mPopupMenu; +}; + +/** + * Implements Group chat chiclet. + */ +class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver +{ +public: + +	struct Params : public LLInitParam::Block<Params, LLChiclet::Params> +	{ +		Optional<LLChicletGroupIconCtrl::Params> group_icon; + +		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; + +		Optional<LLChicletSpeakerCtrl::Params> speaker; + +		Optional<bool>	show_speaker; + +		Params(); +	}; + +	/** +	 * Sets session id. +	 * Session ID for group chat is actually Group ID. +	 */ +	/*virtual*/ void setSessionId(const LLUUID& session_id); + +	/** +	 * Callback for LLGroupMgrObserver, we get this when group data is available or changed. +	 * Sets group icon. +	 */ +	/*virtual*/ void changed(LLGroupChange gc); + +	/*virtual*/ void setShowSpeaker(bool show); + +	/* +	* Sets number of unread messages. Will update chiclet's width if number text  +	* exceeds size of counter and notify it's parent about size change. +	*/ +	/*virtual*/ void setCounter(S32); + +	/* +	* Returns number of unread messages. +	*/ +	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + +	/* +	* Returns rect, required to display chiclet. +	* Width is the only valid value. +	*/ +	/*virtual*/ LLRect getRequiredRect(); + +	~LLIMGroupChiclet(); + +protected: +	LLIMGroupChiclet(const Params& p); +	friend class LLUICtrlFactory; + +	/* +	* Creates chiclet popup menu. Will create P2P or Group IM Chat menu  +	* based on other participant's id. +	*/ +	virtual void createPopupMenu(); + +	/* +	* Processes clicks on chiclet popup menu. +	*/ +	virtual void onMenuItemClicked(const LLSD& user_data); + +	/* +	* Displays popup menu. +	*/ +	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + +private: + +	LLChicletGroupIconCtrl* mChicletIconCtrl; +	LLChicletNotificationCounterCtrl* mCounterCtrl; +	LLChicletSpeakerCtrl* mSpeakerCtrl; +	LLMenuGL* mPopupMenu; +}; +  /*   * Implements notification chiclet. Used to display total amount of unread messages    * across all IM sessions, total amount of system notifications. diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 5272bc2165..c1a5f21010 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1338,7 +1338,10 @@ S32 LLIMMgr::getNumberOfUnreadIM()  	S32 num = 0;  	for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it)  	{ -		num += (*it).second->mNumUnread; +		if((*it).first != mBeingRemovedSessionID) +		{ +			num += (*it).second->mNumUnread; +		}  	}  	return num; @@ -1460,6 +1463,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)  		clearPendingInvitation(session_id);  		clearPendingAgentListUpdates(session_id);  	} + +	// for some purposes storing ID of a sessios that is being removed +	mBeingRemovedSessionID = session_id;  	notifyObserverSessionRemoved(session_id);  	//if we don't clear session data on removing the session @@ -1467,6 +1473,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)  	//creating chiclets only on session created even, we need to handle chiclets creation  	//the same way as LLFloaterIMPanels were managed.  	LLIMModel::getInstance()->clearSession(session_id); + +	// now this session is completely removed +	mBeingRemovedSessionID.setNull();  }  void LLIMMgr::inviteToSession( diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index ce6f0394dd..aed3b68471 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -264,6 +264,9 @@ private:  	LLSD mPendingInvitations;  	LLSD mPendingAgentListUpdates; +	// ID of a session that is being removed: observers are already told +	// that this session is being removed, but it is still present in the sessions' map +	LLUUID	mBeingRemovedSessionID;  }; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index aadda3fbfd..8062da0dfe 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1112,7 +1112,7 @@ void LLInventoryModel::notifyObservers(const std::string service_name)  			observer->changed(mModifyMask);  		} -		// safe way to incrament since changed may delete entries! (@!##%@!@&*!) +		// safe way to increment since changed may delete entries! (@!##%@!@&*!)  		iter = mObservers.upper_bound(observer);   	} diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index e40568a0cb..28e9c93779 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -413,7 +413,9 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()  		LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle());  		item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i)); -		mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params)); +		LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params); +		//new_itemp->setFont() +		mTeleportHistoryMenu->addChild(new_itemp);  	}  } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 3856a86da0..6150d5da37 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -183,9 +183,13 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)  void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)  { -	std::string line = chat.mFromName; -	line +=": "; -	line +=chat.mText; +	std::string line = chat.mText; + +	//chat.mText starts with Avatar Name if entered message was "/me <action>".  +	// In this case output chat message should be "<Avatar Name> <action>". See EXT-656 +	// See also process_chat_from_simulator() in the llviewermessage.cpp where ircstyle = TRUE; +	if (CHAT_STYLE_IRC != chat.mChatStyle) +		line = chat.mFromName + ": " + line;  	bool prepend_newline = true;  	if (gSavedSettings.getBOOL("ChatShowTimestamps")) diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 4cbb018ce9..d1ce6b14ed 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -298,6 +298,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)  	if(button_create)  		button_create->setVisible(is_null_group_id); +	getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id); +  	LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab");  	LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab");  	LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab"); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 73ea990b3f..4b2a1a4e48 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -769,11 +769,6 @@ void LLPanelGroupGeneral::updateMembers()  		}  		// Owners show up in bold.  		std::string style = "NORMAL"; -		if ( member->isOwner() ) -		{ -			style = "BOLD"; -		} -		  		sd_timer.reset();  		LLSD row;  		row["id"] = member->getID(); @@ -793,7 +788,14 @@ void LLPanelGroupGeneral::updateMembers()  		sSDTime += sd_timer.getElapsedTimeF32();  		element_timer.reset(); -		mListVisibleMembers->addElement(row);//, ADD_SORTED); +		LLScrollListItem* member_row = mListVisibleMembers->addElement(row);//, ADD_SORTED); +		 +		if ( member->isOwner() ) +		{ +			LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0)); +			if (name_textp) +				name_textp->setFontStyle(LLFontGL::BOLD); +		}  		sElementTime += element_timer.getElapsedTimeF32();  	}  	sAllTime += all_timer.getElapsedTimeF32(); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 4618b49df4..59f7319b2b 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -659,6 +659,12 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,  		row["columns"][1]["font"]["style"] = "BOLD";  		LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData); +		 +		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(title_row->getColumn(1)); +		if (name_textp) +			name_textp->setFontStyle(LLFontGL::BOLD); + +  		bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 697182c8fc..34d5ef8f86 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -133,18 +133,23 @@ public:  class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver  {  	LOG_CLASS(LLFriendListUpdater); +	class LLInventoryFriendCardObserver;  public:  +	friend class LLInventoryFriendCardObserver;  	LLFriendListUpdater(callback_t cb)  	:	LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT)  	{  		LLAvatarTracker::instance().addObserver(this); +  		// For notification when SIP online status changes.  		LLVoiceClient::getInstance()->addObserver(this); +		mInvObserver = new LLInventoryFriendCardObserver(this);  	}  	~LLFriendListUpdater()  	{ +		delete mInvObserver;  		LLVoiceClient::getInstance()->removeObserver(this);  		LLAvatarTracker::instance().removeObserver(this);  	} @@ -166,6 +171,7 @@ public:  		mMask |= mask;  	} +  	/*virtual*/ BOOL tick()  	{  		if (updateList(mMask)) @@ -180,6 +186,75 @@ public:  private:  	U32 mMask; +	LLInventoryFriendCardObserver* mInvObserver; + +	/** +	 *	This class is intended for updating Friend List when Inventory Friend Card is added/removed. +	 *  +	 *	The main usage is when Inventory Friends/All content is added while synchronizing with  +	 *		friends list on startup is performed. In this case Friend Panel should be updated when  +	 *		missing Inventory Friend Card is created. +	 *	*NOTE: updating is fired when Inventory item is added into CallingCards/Friends subfolder. +	 *		Otherwise LLFriendObserver functionality is enough to keep Friends Panel synchronized. +	 */ +	class LLInventoryFriendCardObserver : public LLInventoryObserver +	{ +		LOG_CLASS(LLFriendListUpdater::LLInventoryFriendCardObserver); + +		friend class LLFriendListUpdater; + +	private: +		LLInventoryFriendCardObserver(LLFriendListUpdater* updater) : mUpdater(updater) +		{ +			gInventory.addObserver(this); +		} +		~LLInventoryFriendCardObserver() +		{ +			gInventory.removeObserver(this); +		} +		/*virtual*/ void changed(U32 mask) +		{ +			lldebugs << "Inventory changed: " << mask << llendl; + +			// *NOTE: deleting of InventoryItem is performed via moving to Trash.  +			// That means LLInventoryObserver::STRUCTURE is present in MASK instead of LLInventoryObserver::REMOVE +			if ((CALLINGCARD_ADDED & mask) == CALLINGCARD_ADDED) +			{ +				lldebugs << "Calling card added: count: " << gInventory.getChangedIDs().size()  +					<< ", first Inventory ID: "<< (*gInventory.getChangedIDs().begin()) +					<< llendl; + +				bool friendFound = false; +				std::set<LLUUID> changedIDs = gInventory.getChangedIDs(); +				for (std::set<LLUUID>::const_iterator it = changedIDs.begin(); it != changedIDs.end(); ++it) +				{ +					if (isDescendentOfInventoryFriends(*it)) +					{ +						friendFound = true; +						break; +					} +				} + +				if (friendFound) +				{ +					lldebugs << "friend found, panel should be updated" << llendl; +					mUpdater->changed(LLFriendObserver::ADD); +				} +			} +		} + +		bool isDescendentOfInventoryFriends(const LLUUID& invItemID) +		{ +			LLViewerInventoryItem * item = gInventory.getItem(invItemID); +			if (NULL == item) +				return false; + +			return LLFriendCardsManager::instance().isItemInAnyFriendsList(item); +		} +		LLFriendListUpdater* mUpdater; + +		static const U32 CALLINGCARD_ADDED = LLInventoryObserver::ADD | LLInventoryObserver::CALLING_CARD; +	};  };  /** @@ -438,8 +513,13 @@ bool LLPanelPeople::updateFriendList(U32 changed_mask)  		LLFriendCardsManager::instance().collectFriendsLists(listMap);  		if (listMap.size() > 0)  		{ +			lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;  			mAllFriendVec = listMap.begin()->second;  		} +		else +		{ +			lldebugs << "Friends Cards were not found" << llendl; +		}  		LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();  		for (; buddy_it != all_buddies.end(); ++buddy_it) diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 973afae73b..bd6ca4746c 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -46,6 +46,7 @@  #include "llpanelprofile.h"  #include "llpanelpick.h"  #include "llscrollcontainer.h" +#include "lllistctrl.h"  static const std::string XML_BTN_NEW = "new_btn";  static const std::string XML_BTN_DELETE = "trash_btn"; @@ -53,10 +54,6 @@ static const std::string XML_BTN_INFO = "info_btn";  static const std::string XML_BTN_TELEPORT = "teleport_btn";  static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; -static const std::string XML_PICKS_LIST = "back_panel"; - -#define PICK_ITEMS_BETWEEN 5 -  static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");  //----------------------------------------------------------------------------- @@ -65,9 +62,9 @@ static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");  LLPanelPicks::LLPanelPicks()  :	LLPanelProfileTab(),  	mPopupMenu(NULL), -	mSelectedPickItem(NULL),  	mProfilePanel(NULL), -	mPickPanel(NULL) +	mPickPanel(NULL), +	mPicksList(NULL)  {  } @@ -100,16 +97,13 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  			gCacheName->getName(getAvatarId(),name,second_name);  			childSetTextArg("pick_title", "[NAME]",name); -			LLView* picks_list = getPicksList(); -			  			// to restore selection of the same item later  			LLUUID pick_id_selected(LLUUID::null); -			if (mSelectedPickItem) pick_id_selected = mSelectedPickItem->getPickId(); +			if (getSelectedPickItem()) pick_id_selected = getSelectedPickItem()->getPickId(); -			clear(); +			mPicksList->clear();  			//*TODO move it somewhere else? -			picks_list->setEnabled(FALSE);  			childSetEnabled(XML_BTN_NEW, false);  			childSetEnabled(XML_BTN_DELETE, false);  			childSetEnabled(XML_BTN_INFO, false); @@ -124,109 +118,38 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)  				LLPickItem* picture = LLPickItem::create();  				picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); -				 -				picks_list->addChild(picture); -  				picture->setPickName(pick_name);  				picture->setPickId(pick_id);  				picture->setCreatorId(getAvatarId());  				LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);  				picture->update(); -				mPickItemList.push_back(picture); +				mPicksList->addItem(picture);  				if (pick_id_selected != LLUUID::null &&  -					pick_id == pick_id_selected) setSelectedPickItem(picture); +					pick_id == pick_id_selected) mPicksList->toggleSelection(picture); + +				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1)); +				picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));  			} -			reshapePicksList();  			LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); -  			updateButtons(); -			if (!mSelectedPickItem && mPickItemList.size()) setSelectedPickItem(mPickItemList.back()); -			picks_list->setEnabled(TRUE); -  		}  	}  } -void LLPanelPicks::clear() -{ -	LLView* scroll = getPicksList(); -	picture_list_t::const_iterator it = mPickItemList.begin(); -	for(; mPickItemList.end() != it; ++it) -	{ -		scroll->removeChild(*it); -		delete *it; -	} -	mPickItemList.clear(); -	mSelectedPickItem = NULL; -} - -  LLPickItem* LLPanelPicks::getSelectedPickItem()  { -	return mSelectedPickItem; -} - - -void LLPanelPicks::removePickItem( LLPickItem* pick_item ) -{ -	LLView* scroll = getPicksList(); -	scroll->removeChild(pick_item); -	mPickItemList.remove(pick_item); -	if (mPickItemList.size() == 0) -	{ -		mSelectedPickItem = NULL; -	} -	else  -	{ -		setSelectedPickItem(mPickItemList.back()); -	} - -	reshapePicksList(); -} - -void LLPanelPicks::reshapePicksList() -{ -	if (!mPickItemList.size()) return; -	LLView* pickList = getPicksList(); - -	//We don't need to update size of the 'pick list' before reshaping pick items. Don't need to reshape the pick list -	S32 height = mPickItemList.size() * (mPickItemList.front()->getRect().getHeight() + PICK_ITEMS_BETWEEN); -	LLRect rc = pickList->getRect(); -	rc.setLeftTopAndSize(rc.mLeft, rc.mTop, rc.getWidth(), height); -	pickList->setRect(rc); - -	S32 last_bottom = pickList->getRect().getHeight(); -	std::list<LLPickItem*>::const_iterator pick_it, pick_first_it = mPickItemList.begin(); -	for ( pick_it = pick_first_it; pick_it != mPickItemList.end(); ++pick_it) -	{ -		LLView* const pick = *pick_it; -		if(pick_it != pick_first_it) -		{ -			last_bottom -= pick->getRect().getHeight(); -			last_bottom -= PICK_ITEMS_BETWEEN; -		} -		reshapePickItem(pick, last_bottom,pickList->getRect().getWidth()); -	} -} - -void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth) -{ -	LLRect rc = pick_item->getRect(); -	rc.mBottom = last_bottom - rc.getHeight(); -	rc.mTop = last_bottom; -	pick_item->setRect(rc); -	pick_item->reshape(newWidth, rc.getHeight()); -} +	std::list<LLPanel*> selected_items = mPicksList->getSelectedItems(); -LLView* LLPanelPicks::getPicksList() const -{ -	return getChild<LLView>(XML_PICKS_LIST); +	if (selected_items.empty()) return NULL; +	return dynamic_cast<LLPickItem*>(selected_items.front());  }  BOOL LLPanelPicks::postBuild()  { +	mPicksList = getChild<LLListCtrl>("picks_list"); +  	childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));  	childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this)); @@ -295,7 +218,7 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response  	if (0 == option)  	{  		LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId()); -		removePickItem(pick_item); +		mPicksList->removeItem(pick_item);  	}  	updateButtons();  	return false; @@ -329,47 +252,29 @@ void LLPanelPicks::onClickMap()  } -BOOL LLPanelPicks::handleRightMouseDown(S32 x, S32 y, MASK mask) +void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)  { -	if (isMouseInPick(x, y)) +	if (mPopupMenu)  	{ -		if (mPopupMenu) -		{ -			mPopupMenu->buildDrawLabels(); -			mPopupMenu->updateParent(LLMenuGL::sMenuContainer); -			((LLContextMenu*)mPopupMenu)->show(x, y); -			LLMenuGL::showPopup(this, mPopupMenu, x, y); -		} -		return TRUE; +		mPopupMenu->buildDrawLabels(); +		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); +		((LLContextMenu*)mPopupMenu)->show(x, y); +		LLMenuGL::showPopup(item, mPopupMenu, x, y);  	} -	return LLPanel::handleRightMouseDown(x, y, mask); -} - -BOOL LLPanelPicks::handleMouseDown( S32 x, S32 y, MASK mask ) -{ -	isMouseInPick(x, y); -	return LLPanel::handleMouseDown(x, y, mask);  } -BOOL LLPanelPicks::handleDoubleClick(S32 x, S32 y, MASK mask) +void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)  { -	if (isMouseInPick(x, y)) -	{ -		LLPickItem* pick_item = getSelectedPickItem(); -		if (pick_item)  -		{ -			LLSD args;  -			args["PICK"] = pick_item->getPickName();  -			LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));  -		} -		return TRUE; -	} -	return LLPanel::handleDoubleClick(x, y, mask); +	LLPickItem* pick_item = dynamic_cast<LLPickItem*>(item); +	if (!pick_item) return; +	LLSD args;  +	args["PICK"] = pick_item->getPickName();  +	LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));   }  void LLPanelPicks::updateButtons()  { -	int picks_num = mPickItemList.size(); +	int picks_num = mPicksList->size();  	childSetEnabled(XML_BTN_INFO, picks_num > 0);  	if (getAvatarId() == gAgentID) @@ -388,42 +293,6 @@ void LLPanelPicks::updateButtons()  } -void LLPanelPicks::setSelectedPickItem(LLPickItem* item) -{ -	if (!item) return; -	if (mSelectedPickItem == item) return; -	if (mSelectedPickItem && mSelectedPickItem->isBackgroundVisible()) -	{ -		mSelectedPickItem->setBackgroundVisible(FALSE); -	} -	item->setBackgroundVisible(TRUE); -	mSelectedPickItem = item; -} - -BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y ) -{ -	S32 x_l = x; -	S32 y_l = y; -	 -	if(!getChild<LLUICtrl>("profile_scroll")->getRect().pointInRect(x, y)) -	{ -		return FALSE; -	} - -	picture_list_t::const_iterator it = mPickItemList.begin(); -	for(; mPickItemList.end() != it; ++it) -	{ -		localPointToOtherView(x, y, &x_l, &y_l, (*it)); -		if ((*it)->pointInView(x_l, y_l)) -		{ -			setSelectedPickItem(*it); -			return TRUE; -		} -	}	 -	return FALSE; -} - -  void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)  {  	mProfilePanel = profile_panel; diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index da7bc32ab1..5860354902 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -48,7 +48,7 @@ class LLPanelPick;  class LLAgent;  class LLMenuGL;  class LLPickItem; - +class LLListCtrl;  class LLPanelPicks   	: public LLPanelProfileTab @@ -67,18 +67,9 @@ public:  	void updateData(); -	void clear(); -  	// returns the selected pick item  	LLPickItem* getSelectedPickItem(); -	// removes the specified pick item -	void removePickItem(LLPickItem* pick_item); - -	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); -	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); -	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); -  	//*NOTE top down approch when panel toggling is done only by   	// parent panels failed to work (picks related code was in me profile panel)  	void setProfilePanel(LLPanelProfile* profile_panel); @@ -106,25 +97,17 @@ private:  	bool callbackDelete(const LLSD& notification, const LLSD& response);  	bool callbackTeleport(const LLSD& notification, const LLSD& response); -	void reshapePicksList(); -	void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth); -	LLView* getPicksList() const;  	void updateButtons(); -	void setSelectedPickItem(LLPickItem* item); - -	BOOL isMouseInPick(S32 x, S32 y); +	virtual void onDoubleClickItem(LLUICtrl* item); +	virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);  	LLPanelProfile* getProfilePanel(); - -	typedef std::list<LLPickItem*> picture_list_t; -	picture_list_t mPickItemList; -  	LLMenuGL* mPopupMenu; -	LLPickItem* mSelectedPickItem;  	LLPanelProfile* mProfilePanel;  	LLPanelPick* mPickPanel; +	LLListCtrl* mPicksList;  };  class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index a01977c9b5..73e09a36f9 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -48,6 +48,7 @@  #include "llscrollcontainer.h"  #include "lltextbox.h" +#include "llaccordionctrl.h"  #include "llagent.h"  #include "llavatarpropertiesprocessor.h"  #include "llfloaterworldmap.h" @@ -93,14 +94,42 @@ BOOL LLPanelPlaceInfo::postBuild()  	mSnapshotCtrl = getChild<LLTextureCtrl>("logo");  	mSnapshotCtrl->setEnabled(FALSE); -	mRegionName = getChild<LLTextBox>("region_name"); -	mParcelName = getChild<LLTextBox>("parcel_name"); +	mRegionName = getChild<LLTextBox>("region_title"); +	mParcelName = getChild<LLTextBox>("parcel_title");  	mDescEditor = getChild<LLTextEditor>("description"); -	mRating = getChild<LLIconCtrl>("maturity"); -	mRegionInfoDrillIn = getChild<LLButton>("region_info_drill_in"); -	mMediaDrillIn = getChild<LLButton>("media_drill_in"); -	mMediaDrillIn->setClickedCallback(boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, this, TRUE)); +	mMaturityRatingIcon = getChild<LLIconCtrl>("maturity"); +	mMaturityRatingText = getChild<LLTextBox>("maturity_value"); + +	mParcelOwner = getChild<LLTextBox>("owner_value"); + +	mLastVisited = getChild<LLTextBox>("last_visited_value"); + +	mRatingIcon = getChild<LLIconCtrl>("rating_icon"); +	mRatingText = getChild<LLTextBox>("rating_value"); +	mVoiceIcon = getChild<LLIconCtrl>("voice_icon"); +	mVoiceText = getChild<LLTextBox>("voice_value"); +	mFlyIcon = getChild<LLIconCtrl>("fly_icon"); +	mFlyText = getChild<LLTextBox>("fly_value"); +	mPushIcon = getChild<LLIconCtrl>("push_icon"); +	mPushText = getChild<LLTextBox>("push_value"); +	mBuildIcon = getChild<LLIconCtrl>("build_icon"); +	mBuildText = getChild<LLTextBox>("build_value"); +	mScriptsIcon = getChild<LLIconCtrl>("scripts_icon"); +	mScriptsText = getChild<LLTextBox>("scripts_value"); +	mDamageIcon = getChild<LLIconCtrl>("damage_icon"); +	mDamageText = getChild<LLTextBox>("damage_value"); + +	mRegionNameText = getChild<LLTextBox>("region_name"); +	mRegionTypeText = getChild<LLTextBox>("region_type"); +	mRegionRatingText = getChild<LLTextBox>("region_rating"); +	mRegionOwnerText = getChild<LLTextBox>("region_owner"); +	mRegionGroupText = getChild<LLTextBox>("region_group"); + +	mEstateNameText = getChild<LLTextBox>("estate_name"); +	mEstateRatingText = getChild<LLTextBox>("estate_rating"); +	mEstateOwnerText = getChild<LLTextBox>("estate_owner"); +	mCovenantText = getChild<LLTextEditor>("covenant");  	mOwner = getChild<LLTextBox>("owner");  	mCreator = getChild<LLTextBox>("creator"); @@ -224,7 +253,10 @@ void LLPanelPlaceInfo::resetLocation()  	mLandmarkID.setNull();  	mPosRegion.clearVec();  	std::string not_available = getString("not_available"); -	mRating->setValue(not_available); +	mMaturityRatingIcon->setValue(not_available); +	mMaturityRatingText->setValue(not_available); +	mParcelOwner->setValue(not_available); +	mLastVisited->setValue(not_available);  	mRegionName->setText(not_available);  	mParcelName->setText(not_available);  	mDescEditor->setText(not_available); @@ -235,6 +267,32 @@ void LLPanelPlaceInfo::resetLocation()  	mNotesEditor->setText(LLStringUtil::null);  	mSnapshotCtrl->setImageAssetID(LLUUID::null);  	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); + +	mRatingIcon->setValue(not_available); +	mRatingText->setText(not_available); +	mVoiceIcon->setValue(not_available); +	mVoiceText->setText(not_available); +	mFlyIcon->setValue(not_available); +	mFlyText->setText(not_available); +	mPushIcon->setValue(not_available); +	mPushText->setText(not_available); +	mBuildIcon->setValue(not_available); +	mBuildText->setText(not_available); +	mScriptsIcon->setValue(not_available); +	mScriptsText->setText(not_available); +	mDamageIcon->setValue(not_available); +	mDamageText->setText(not_available); + +	mRegionNameText->setValue(not_available); +	mRegionTypeText->setValue(not_available); +	mRegionRatingText->setValue(not_available); +	mRegionOwnerText->setValue(not_available); +	mRegionGroupText->setValue(not_available); + +	mEstateNameText->setValue(not_available); +	mEstateRatingText->setValue(not_available); +	mEstateOwnerText->setValue(not_available); +	mCovenantText->setValue(not_available);  }  //virtual @@ -251,12 +309,22 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	bool is_info_type_agent = type == AGENT;  	bool is_info_type_landmark = type == LANDMARK; +	bool is_info_type_teleport_history = type == TELEPORT_HISTORY; + +	getChild<LLTextBox>("maturity_label")->setVisible(!is_info_type_agent); +	mMaturityRatingIcon->setVisible(!is_info_type_agent); +	mMaturityRatingText->setVisible(!is_info_type_agent); + +	getChild<LLTextBox>("owner_label")->setVisible(is_info_type_agent); +	mParcelOwner->setVisible(is_info_type_agent); + +	getChild<LLTextBox>("last_visited_label")->setVisible(is_info_type_teleport_history); +	mLastVisited->setVisible(is_info_type_teleport_history);  	landmark_info_panel->setVisible(is_info_type_landmark);  	landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK); -	mRegionInfoDrillIn->setVisible(is_info_type_agent); -	mMediaDrillIn->setVisible(is_info_type_agent); +	getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);  	switch(type)  	{ @@ -274,14 +342,15 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  			}  		break; -		// Hide Media Panel if showing information about -		// a landmark or a teleport history item  		case LANDMARK:  			mCurrentTitle = getString("title_landmark");  		break;  		case TELEPORT_HISTORY: -			mCurrentTitle = getString("title_place"); +			mCurrentTitle = getString("title_teleport_history"); + +			// *TODO: Add last visited timestamp. +			mLastVisited->setText(getString("unknown"));  		break;  	} @@ -293,7 +362,7 @@ BOOL LLPanelPlaceInfo::isMediaPanelVisible()  {  	if (!mMediaPanel)  		return FALSE; -	 +  	return mMediaPanel->getVisible();  } @@ -363,18 +432,23 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  	// HACK: Flag 0x2 == adult region,  	// Flag 0x1 == mature region, otherwise assume PG  	std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); -	std::string rating_icon = "icon_event.tga"; +	std::string rating_icon = "places_rating_pg.tga";  	if (parcel_data.flags & 0x2)  	{  		rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); -		rating_icon = "icon_event_adult.tga"; +		rating_icon = "places_rating_adult.tga";  	}  	else if (parcel_data.flags & 0x1)  	{  		rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE); -		rating_icon = "icon_event_mature.tga"; +		rating_icon = "places_rating_mature.tga";  	} -	mRating->setValue(rating_icon); + +	mMaturityRatingIcon->setValue(rating_icon); +	mMaturityRatingText->setValue(rating); + +	mRatingIcon->setValue(rating_icon); +	mRatingText->setValue(rating);  	//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE  	//because we deal with remote parcel response format @@ -450,6 +524,14 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  	if (!region || !parcel)  		return; +	// send EstateCovenantInfo message +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessage("EstateCovenantRequest"); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID,	gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); +	msg->sendReliable(region->getHost()); +  	LLParcelData parcel_data;  	// HACK: Converting sim access flags to the format @@ -481,9 +563,139 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()  	parcel_data.global_y = global_pos.mdV[1];  	parcel_data.global_z = global_pos.mdV[2]; +	processParcelInfo(parcel_data); + +	// Processing parcel characteristics +	if (parcel->getParcelFlagAllowVoice()) +	{ +		mVoiceIcon->setValue("places_voice_on.tga"); +		mVoiceText->setText(getString("on")); +	} +	else +	{ +		mVoiceIcon->setValue("places_voice_off.tga"); +		mVoiceText->setText(getString("off")); +	} +	if (!region->getBlockFly() && parcel->getAllowFly()) +	{ +		mFlyIcon->setValue("places_fly_on.tga"); +		mFlyText->setText(getString("on")); +	} +	else +	{ +		mFlyIcon->setValue("places_fly_off.tga"); +		mFlyText->setText(getString("off")); +	} -	processParcelInfo(parcel_data); +	if (region->getRestrictPushObject() || parcel->getRestrictPushObject()) +	{ +		mPushIcon->setValue("places_push_off.tga"); +		mPushText->setText(getString("off")); +	} +	else +	{ +		mPushIcon->setValue("places_push_on.tga"); +		mPushText->setText(getString("on")); +	} + +	if (parcel->getAllowModify()) +	{ +		mBuildIcon->setValue("places_build_on.tga"); +		mBuildText->setText(getString("on")); +	} +	else +	{ +		mBuildIcon->setValue("places_build_off.tga"); +		mBuildText->setText(getString("off")); +	} + +	if((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) || +	   (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) || +	   !parcel->getAllowOtherScripts()) +	{ +		mScriptsIcon->setValue("places_scripts_off.tga"); +		mScriptsText->setText(getString("off")); +	} +	else +	{ +		mScriptsIcon->setValue("places_scripts_on.tga"); +		mScriptsText->setText(getString("on")); +	} + +	if (region->getAllowDamage() || parcel->getAllowDamage()) +	{ +		mDamageIcon->setValue("places_damage_on.tga"); +		mDamageText->setText(getString("on")); +	} +	else +	{ +		mDamageIcon->setValue("places_damage_off.tga"); +		mDamageText->setText(getString("off")); +	} + +	mRegionNameText->setText(region->getName()); +	mRegionTypeText->setText(region->getSimProductName()); +	mRegionRatingText->setText(region->getSimAccessString()); + +	// Determine parcel owner +	if (parcel->isPublic()) +	{ +		mParcelOwner->setText(getString("public")); +		mRegionOwnerText->setText(getString("public")); +	} +	else +	{ +		if (parcel->getIsGroupOwned()) +		{ +			mRegionOwnerText->setText(getString("group_owned_text")); + +			if(!parcel->getGroupID().isNull()) +			{ +				// FIXME: Using parcel group as region group. +				gCacheName->get(parcel->getGroupID(), TRUE, +								boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionGroupText, _2, _3)); + +				mParcelOwner->setText(mRegionGroupText->getText()); +			} +			else +			{ +				std::string owner = getString("none_text"); +				mRegionGroupText->setText(owner); +				mParcelOwner->setText(owner); +			} +		} +		else +		{ +			// Figure out the owner's name +			gCacheName->get(parcel->getOwnerID(), FALSE, +							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3)); +			gCacheName->get(region->getOwner(), FALSE, +							boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionOwnerText, _2, _3)); +		} + +		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) +		{ +			mRegionOwnerText->setText(mRegionOwnerText->getText() + getString("sale_pending_text")); +		} +	} + +	mEstateRatingText->setText(region->getSimAccessString()); +} + +void LLPanelPlaceInfo::updateEstateName(const std::string& name) +{ +	mEstateNameText->setText(name); +} + +void LLPanelPlaceInfo::updateEstateOwnerName(const std::string& name) +{ +	mEstateOwnerText->setText(name); +} + +void LLPanelPlaceInfo::updateCovenantText(const std::string &text) +{ +	mCovenantText->setText(text);  }  void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 77ce2c6619..0cdeaab2b7 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -105,6 +105,10 @@ public:  	// without sending a request to the server.  	void displayAgentParcelInfo(); +	void updateEstateName(const std::string& name); +	void updateEstateOwnerName(const std::string& name); +	void updateCovenantText(const std::string &text); +  	void nameUpdatedCallback(LLTextBox* text,  							 const std::string& first,  							 const std::string& last); @@ -133,15 +137,42 @@ private:  	LLTextBox*			mRegionName;  	LLTextBox*			mParcelName;  	LLTextEditor*		mDescEditor; -	LLIconCtrl*			mRating; -	LLButton*			mRegionInfoDrillIn; -	LLButton*			mMediaDrillIn; +	LLIconCtrl*			mMaturityRatingIcon; +	LLTextBox*			mMaturityRatingText; +	LLTextBox*			mParcelOwner; +	LLTextBox*			mLastVisited; + +	LLIconCtrl*			mRatingIcon; +	LLTextBox*			mRatingText; +	LLIconCtrl*			mVoiceIcon; +	LLTextBox*			mVoiceText; +	LLIconCtrl*			mFlyIcon; +	LLTextBox*			mFlyText; +	LLIconCtrl*			mPushIcon; +	LLTextBox*			mPushText; +	LLIconCtrl*			mBuildIcon; +	LLTextBox*			mBuildText; +	LLIconCtrl*			mScriptsIcon; +	LLTextBox*			mScriptsText; +	LLIconCtrl*			mDamageIcon; +	LLTextBox*			mDamageText; + +	LLTextBox*			mRegionNameText; +	LLTextBox*			mRegionTypeText; +	LLTextBox*			mRegionRatingText; +	LLTextBox*			mRegionOwnerText; +	LLTextBox*			mRegionGroupText; + +	LLTextBox*			mEstateNameText; +	LLTextBox*			mEstateRatingText; +	LLTextBox*			mEstateOwnerText; +	LLTextEditor*		mCovenantText; +  	LLTextBox*			mOwner;  	LLTextBox*			mCreator;  	LLTextBox*			mCreated;  	LLLineEditor*		mTitleEditor;  	LLTextEditor*		mNotesEditor; -	LLTextBox*			mLocationEditor;  	LLPanel*            mScrollingPanel;  	LLPanel*			mInfoPanel;  	LLMediaPanel*		mMediaPanel; diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 7cb9e61e72..2aebfdabfa 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -119,9 +119,6 @@ BOOL LLPanelPlaces::postBuild()  	//mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this));  	mOverflowBtn = getChild<LLButton>("overflow_btn"); - -	// *TODO: Assign the action to an appropriate event. -	//mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));  	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -156,20 +153,17 @@ BOOL LLPanelPlaces::postBuild()  	LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn");  	back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); -	// *TODO: Assign the action to an appropriate event. -	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this)); -  	return TRUE;  }  void LLPanelPlaces::onOpen(const LLSD& key)  { -	mFilterEditor->clear(); -	onFilterEdit(""); -	  	if(mPlaceInfo == NULL || key.size() == 0)  		return; +	mFilterEditor->clear(); +	onFilterEdit(""); +  	mPlaceInfoType = key["type"].asString();  	mPosGlobal.setZero();  	togglePlaceInfoPanel(TRUE); @@ -228,8 +222,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)  									  hist_items[index].mRegionID,  									  mPosGlobal);  	} -	 -  }  void LLPanelPlaces::setItem(LLInventoryItem* item) diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 089a854762..057c430230 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -79,7 +79,7 @@ private:  	void onAgentParcelChange();  	void updateVerbs(); -	 +  	void showLandmarkFoldersMenu();  	LLFilterEditor*				mFilterEditor; diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 18184a6476..0762bbeb87 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -31,12 +31,16 @@  */  #include "llviewerprecompiledheaders.h" + +#include "lluserrelations.h" +  #include "llpanelprofileview.h" +#include "llcallingcard.h"  #include "llpanelavatar.h"  #include "llpanelpicks.h" -#include "llsidetraypanelcontainer.h"  #include "llpanelprofile.h" +#include "llsidetraypanelcontainer.h"  static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view"); @@ -45,6 +49,7 @@ static const std::string PANEL_PROFILE = "panel_profile";  LLPanelProfileView::LLPanelProfileView()  :	LLPanelProfile() +,	mStatusText(NULL)  {  } @@ -65,6 +70,10 @@ void LLPanelProfileView::onOpen(const LLSD& key)  		setAvatarId(id);  	} +	// status should only show if viewer has permission to view online/offline. EXT-453  +	mStatusText->setVisible(isGrantedToSeeOnlineStatus()); +	updateOnlineStatus(); +  	LLPanelProfile::onOpen(key);  } @@ -78,6 +87,8 @@ BOOL LLPanelProfileView::postBuild()  	getTabContainer()[PANEL_PROFILE]->childSetVisible("online_me_status_text", FALSE);  	getTabContainer()[PANEL_PROFILE]->childSetVisible("status_combo", FALSE); +	mStatusText = getChild<LLTextBox>("status"); +  	childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL);  	return TRUE; @@ -94,3 +105,32 @@ void LLPanelProfileView::onBackBtnClick()  		parent->openPreviousPanel();  	}  } + +bool LLPanelProfileView::isGrantedToSeeOnlineStatus() +{ +	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); +	if (NULL == relationship) +		return false; + +	// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. +	// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer +	// see comments for ChangeUserRights template message. EXT-453. +//	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); +	return true; +} + +void LLPanelProfileView::updateOnlineStatus() +{ +	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); +	if (NULL == relationship) +		return; + +	bool online = relationship->isOnline(); +//	std::string statusName(); + +	std::string status = getString(online ? "status_online" : "status_offline"); + +	mStatusText->setValue(status); +} + +// EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 92def7b7ca..533ab94cc3 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -39,7 +39,7 @@  class LLPanelProfile;  class LLPanelProfileTab; - +class LLTextBox;  /**  * Panel for displaying Avatar's profile. It consists of three sub panels - Profile, @@ -63,6 +63,11 @@ public:  protected:  	void onBackBtnClick(); +	bool isGrantedToSeeOnlineStatus(); +	void updateOnlineStatus(); + +private: +	LLTextBox* mStatusText;  };  #endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 2bbb5a2767..15d77dbf88 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -40,29 +40,36 @@  //---------------------------------------------------------------------------------  LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), +													mSysWell(NULL),  													mChannel(NULL),  													mScrollContainer(NULL),  													mNotificationList(NULL)  { +	LLIMMgr::getInstance()->addSessionObserver(this); +	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1));  }  //---------------------------------------------------------------------------------  BOOL LLSysWellWindow::postBuild()  {  	mScrollContainer = getChild<LLScrollContainer>("notification_list_container"); +	mTwinListPanel = getChild<LLPanel>("twin_list_panel");  	mNotificationList = getChild<LLScrollingPanelList>("notification_list"); +	mIMRowList = getChild<LLScrollingPanelList>("im_row_panel_list");  	gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized  	mScrollContainer->setBorderVisible(FALSE);  	mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); +  	return TRUE;  }  //---------------------------------------------------------------------------------  LLSysWellWindow::~LLSysWellWindow()  { +	LLIMMgr::getInstance()->removeSessionObserver(this);  }  //--------------------------------------------------------------------------------- @@ -121,10 +128,9 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)  	reshapeWindow();  	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized +  	// hide chiclet window if there are no items left -	S32 items_left = mNotificationList->getPanelList().size(); -	if(items_left == 0) -		setVisible(FALSE); +	setVisible(!isWindowEmpty());  }  //--------------------------------------------------------------------------------- @@ -177,6 +183,7 @@ void LLSysWellWindow::adjustWindowPosition()	// *TODO: won't be necessary after  	LLRect this_rect = getRect();  	setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN);   } +  //---------------------------------------------------------------------------------  void LLSysWellWindow::reshapeWindow()  { @@ -184,30 +191,210 @@ void LLSysWellWindow::reshapeWindow()  	const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0);  	const LLUICachedControl<S32> HEADER_SIZE("UIFloaterHeaderSize", 0); -	// Get item list	 -	const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList(); +	LLRect notif_list_rect = mNotificationList->getRect(); +	LLRect im_list_rect = mIMRowList->getRect(); +	LLRect panel_rect = mTwinListPanel->getRect(); + +	S32 notif_list_height = notif_list_rect.getHeight(); +	S32 im_list_height = im_list_rect.getHeight(); -	// Get height for a scrolling panel list -	S32 list_height	= mNotificationList->getRect().getHeight(); +	S32 new_panel_height = notif_list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + im_list_height; +	S32 new_window_height = new_panel_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE; -	// Check that the floater doesn't exceed its parent view limits after reshape -	S32 new_height = list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE; +	U32 twinListWidth = 0; -	if(new_height > MAX_WINDOW_HEIGHT) +	if (new_window_height > MAX_WINDOW_HEIGHT)  	{ -		reshape(MIN_WINDOW_WIDTH, MAX_WINDOW_HEIGHT, FALSE); -		mNotificationList->reshape(MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE, list_height, TRUE); +		twinListWidth = MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE; +		new_window_height = MAX_WINDOW_HEIGHT;  	}  	else  	{ -		reshape(MIN_WINDOW_WIDTH, new_height, FALSE); -		mNotificationList->reshape(MIN_PANELLIST_WIDTH, list_height, TRUE); +		twinListWidth = MIN_PANELLIST_WIDTH;  	} -	 + +	reshape(MIN_WINDOW_WIDTH, new_window_height, FALSE); +	mTwinListPanel->reshape(twinListWidth, new_panel_height, TRUE); +	mNotificationList->reshape(twinListWidth, notif_list_height, TRUE); +	mIMRowList->reshape(twinListWidth, im_list_height, TRUE); + +	// arrange panel and lists +	// move panel +	panel_rect.setLeftTopAndSize(1, new_panel_height, twinListWidth, new_panel_height); +	mTwinListPanel->setRect(panel_rect); +	// move notif list panel +	notif_list_rect.setLeftTopAndSize(notif_list_rect.mLeft, new_panel_height, twinListWidth, notif_list_height); +	mNotificationList->setRect(notif_list_rect); +	// move IM list panel +	im_list_rect.setLeftTopAndSize(im_list_rect.mLeft, notif_list_rect.mBottom - LLScrollingPanelList::GAP_BETWEEN_PANELS, twinListWidth, im_list_height); +	mIMRowList->setRect(im_list_rect); +  	mNotificationList->updatePanels(TRUE); +	mIMRowList->updatePanels(TRUE); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel * LLSysWellWindow::findIMRow(const LLUUID& sessionId) +{ +	RowPanel * res = NULL; +	const LLScrollingPanelList::panel_list_t &list = mIMRowList->getPanelList(); +	if (!list.empty()) +	{ +		for (LLScrollingPanelList::panel_list_t::const_iterator iter = list.begin(); iter != list.end(); ++iter) +		{ +			RowPanel *panel = static_cast<RowPanel*> (*iter); +			if (panel->mChiclet->getSessionId() == sessionId) +			{ +				res = panel; +				break; +			} +		} +	} +	return res; +} + +//--------------------------------------------------------------------------------- +LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId) +{ +	LLChiclet* res = NULL; +	RowPanel* panel = findIMRow(sessionId); +	if (panel != NULL) +	{ +		res = panel->mChiclet; +	} + +	return res; +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, +		const std::string& name, const LLUUID& otherParticipantId) +{ + +	mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId)); +	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::delIMRow(const LLUUID& sessionId) +{ +	RowPanel *panel = findIMRow(sessionId); +	if (panel != NULL) +	{ +		mIMRowList->removePanel(panel); +	} + +	// hide chiclet window if there are no items left +	setVisible(!isWindowEmpty()); + +	adjustWindowPosition();	// *TODO: won't be necessary after docking is realized +} + +//--------------------------------------------------------------------------------- +bool LLSysWellWindow::isWindowEmpty() +{ +	if(mIMRowList->getPanelList().size() == 0 && mNotificationList->getPanelList().size() == 0) +	{ +		return true; +	} +	else +	{ +		return false; +	} +} + +//--------------------------------------------------------------------------------- +//virtual +void LLSysWellWindow::sessionAdded(const LLUUID& sessionId, +		const std::string& name, const LLUUID& otherParticipantId) +{ +	if (findIMRow(sessionId) == NULL) +	{ +		S32 chicletCounter = 0; +		LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap, +				sessionId, (LLIMModel::LLIMSession*) NULL); +		if (session != NULL) +		{ +			chicletCounter = session->mNumUnread; +		} +		addIMRow(sessionId, chicletCounter, name, otherParticipantId); +		reshapeWindow(); +	} +} + +//--------------------------------------------------------------------------------- +//virtual +void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId) +{ +	delIMRow(sessionId); +	reshapeWindow(); +	mSysWell->updateUreadIMNotifications(); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, +		S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : +		LLScrollingPanel(LLPanel::Params()), mParent(parent) +{ +	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL); + +	mChiclet = getChild<LLIMChiclet>("chiclet"); +	mChiclet->setCounter(chicletCounter); +	mChiclet->setSessionId(sessionId); +	mChiclet->setIMSessionName(name); +	mChiclet->setOtherParticipantId(otherParticipantId); + +	LLTextBox* contactName = getChild<LLTextBox>("contact_name"); +	contactName->setValue(name); + +	mCloseBtn = getChild<LLButton>("hide_btn"); +	mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClose, this)); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel::~RowPanel() +{ +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onClose() +{ +	mParent->mIMRowList->removePanel(this); +	gIMMgr->removeSession(mChiclet->getSessionId()); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask) +{ +	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected")); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask) +{ +	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));  }  //--------------------------------------------------------------------------------- +// virtual +BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask) +{ +	// Pass the mouse down event to the chiclet (EXT-596). +	if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown() +		mChiclet->onMouseDown(); +	return LLPanel::handleMouseDown(x, y, mask); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify) +{ +	S32 parent_width = getParent()->getRect().getWidth(); +	S32 panel_height = getRect().getHeight(); + +	reshape(parent_width, panel_height, TRUE); +} + +//--------------------------------------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 7a107af0d1..d9fdf77a04 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -39,20 +39,26 @@  #include "llbutton.h"  #include "llscreenchannel.h"  #include "llscrollcontainer.h" +#include "llchiclet.h" +#include "llimview.h"  #include "boost/shared_ptr.hpp" -class LLSysWellWindow : public LLFloater +class LLSysWellWindow : public LLFloater, LLIMSessionObserver  {  public:      LLSysWellWindow(const LLSD& key);      ~LLSysWellWindow();  	BOOL postBuild(); +	// other interface functions +	bool isWindowEmpty(); +  	// change attributes  	void setChannel(LLNotificationsUI::LLScreenChannel*	channel) {mChannel = channel;} +	void setSysWell(LLNotificationChiclet*	sys_well) {mSysWell = sys_well;}  	// Operating with items  	void addItem(LLSysWellItem::Params p); @@ -75,15 +81,49 @@ public:  	static const S32 MIN_PANELLIST_WIDTH	= 318;  private: - +	class RowPanel;  	void reshapeWindow(); +	RowPanel * findIMRow(const LLUUID& sessionId); +	LLChiclet * findIMChiclet(const LLUUID& sessionId); +	void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId); +	void delIMRow(const LLUUID& sessionId); +	// LLIMSessionObserver observe triggers +	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); +	virtual void sessionRemoved(const LLUUID& session_id);  	// pointer to a corresponding channel's instance  	LLNotificationsUI::LLScreenChannel*	mChannel; +	LLNotificationChiclet*	mSysWell;  	LLUIImagePtr			mDockTongue; +	LLPanel*				mTwinListPanel;  	LLScrollContainer*		mScrollContainer; +	LLScrollingPanelList*	mIMRowList;  	LLScrollingPanelList*	mNotificationList; + +private: +	/** +	 * Scrolling row panel. +	 */ +	class RowPanel: public LLScrollingPanel +	{ +	public: +		RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter, +				const std::string& name, const LLUUID& otherParticipantId); +		virtual ~RowPanel(); +		/*virtual*/ +		void updatePanel(BOOL allow_modify); +		void onMouseEnter(S32 x, S32 y, MASK mask); +		void onMouseLeave(S32 x, S32 y, MASK mask); +		BOOL handleMouseDown(S32 x, S32 y, MASK mask); +	private: +		void onClose(); +	public: +		LLIMChiclet* mChiclet; +	private: +		LLButton*	mCloseBtn; +		const LLSysWellWindow* mParent; +	};  };  #endif // LL_LLSYSWELLWINDOW_H diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index abe5fd8ce8..18fab3ec2e 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -138,6 +138,8 @@  #include "llkeythrottle.h"  #include "llgroupactions.h"  #include "llagentui.h" +#include "llsidetray.h" +#include "llpanelplaceinfo.h"  #include <boost/tokenizer.hpp>  #include <boost/algorithm/string/split.hpp> @@ -2397,6 +2399,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  		// Look for IRC-style emotes  		if (ircstyle)  		{ +			// set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656 +			chat.mChatStyle = CHAT_STYLE_IRC; +  			// Do nothing, ircstyle is fixed above for chat bubbles  		}  		else @@ -5565,6 +5570,12 @@ void process_covenant_reply(LLMessageSystem* msg, void**)  	LLPanelLandCovenant::updateEstateName(estate_name);  	LLFloaterBuyLand::updateEstateName(estate_name); +	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); +	if (panel) +	{ +		panel->updateEstateName(estate_name); +	} +  	// standard message, not from system  	std::string last_modified;  	if (covenant_timestamp == 0) @@ -5621,6 +5632,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**)  		LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);  		LLPanelLandCovenant::updateCovenantText(covenant_text);  		LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id); +		panel->updateCovenantText(covenant_text);  	}  } @@ -5641,6 +5653,12 @@ void callbackCacheEstateOwnerName(const LLUUID& id,  	LLPanelEstateCovenant::updateEstateOwnerName(name);  	LLPanelLandCovenant::updateEstateOwnerName(name);  	LLFloaterBuyLand::updateEstateOwnerName(name); + +	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); +	if (panel) +	{ +		panel->updateEstateOwnerName(name); +	}  }  void onCovenantLoadComplete(LLVFS *vfs, @@ -5708,6 +5726,12 @@ void onCovenantLoadComplete(LLVFS *vfs,  	LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);  	LLPanelLandCovenant::updateCovenantText(covenant_text);  	LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid); + +	LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); +	if (panel) +	{ +		panel->updateCovenantText(covenant_text); +	}  } diff --git a/indra/newview/skins/default/textures/places_rating_adult.tga b/indra/newview/skins/default/textures/places_rating_adult.tga Binary files differnew file mode 100644 index 0000000000..c344fb1e78 --- /dev/null +++ b/indra/newview/skins/default/textures/places_rating_adult.tga diff --git a/indra/newview/skins/default/textures/places_rating_mature.tga b/indra/newview/skins/default/textures/places_rating_mature.tga Binary files differnew file mode 100644 index 0000000000..61c879bc92 --- /dev/null +++ b/indra/newview/skins/default/textures/places_rating_mature.tga diff --git a/indra/newview/skins/default/textures/places_rating_pg.tga b/indra/newview/skins/default/textures/places_rating_pg.tga Binary files differnew file mode 100644 index 0000000000..7805dbce60 --- /dev/null +++ b/indra/newview/skins/default/textures/places_rating_pg.tga diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml index 38c6d44fdf..0af4e1db54 100644 --- a/indra/newview/skins/default/xui/en/floater_activeim.xml +++ b/indra/newview/skins/default/xui/en/floater_activeim.xml @@ -5,7 +5,7 @@  	top="26"  	left="0"  	height="22" -	width="350" +	width="320"  	follows="right|bottom"  	background_visible="true"  	can_close="true" @@ -18,13 +18,14 @@  		layout="topleft"  		top="20"  		left="1" -		width="349" +		width="320"  		height="2"  		name="panel_list_container">  		<scrolling_panel_list  			follows="left|right"  			layout="topleft" +      left="1"        			name="chiclet_row_panel_list" -			width="335"/> +			width="318"/>  	</scroll_container>  </floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index 46c8960fbd..d76ea398d5 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -4,16 +4,16 @@   background_visible="true"    bevel_style="in"   bg_alpha_color="0.0 0.0 0.0 0.0" - height="30"   left="0"   top="0"    follows="right|bottom"   layout="topleft"   name="notification_chiclet"   save_rect="true" - title="NOTIFICATIONS" + title="NOTIFICATIONS"    width="320"   min_width="320" + height="60"   can_minimize="false"   can_tear_off="false"   can_resize="false" @@ -21,20 +21,36 @@   can_close="false"   can_dock="true"  > -  <scroll_container -   follows="top|bottom" -   layout="topleft" -   name="notification_list_container" -   left="0" -   top="18" -   width="320" -   height="12"> -    <scrolling_panel_list -     layout="topleft" -     name="notification_list" -     left="1" -     top="0" -     height="10" -     width="318" /> -  </scroll_container> +	<scroll_container +	follows="top|bottom" +	layout="topleft" +	name="notification_list_container" +	left="0" +	top="18" +	width="320" +	height="42"> +	<panel +		layout="topleft" +		name="twin_list_panel" +		left="1" +		top="0" +		width="318" +    height="32" +    bg_alpha_color="1.0 1.0 1.0 1.0"> +		<scrolling_panel_list +			layout="topleft" +			name="notification_list" +			left="1" +			top="0" +			height="0" +			width="318"/> +		<scrolling_panel_list +			layout="topleft" +			name="im_row_panel_list" +			left="1" +			top="2" +			height="0" +			width="318"/> +	</panel> +</scroll_container>  </floater> diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml index 8977f30a51..f5af8e7b30 100644 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml @@ -1,47 +1,53 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel -	follows="bottom|right" +<panel	  	name="panel_activeim_row"  	layout="topleft" +	follows="left|right"  	top="0"  	left="0" -	height="40" -	width="332" +	height="35" +	width="318"  	background_visible="true"  	bevel_style="in"  	bg_alpha_color="0 0 0 0"> -	<chiclet_im +  <chiclet_im_p2p  		name="chiclet"  		layout="topleft" -		top="4" -		left="10" -		height="26" +		follows="left" +		top="5" +		left="5" +		height="25"  		width="45"> -	</chiclet_im> +  </chiclet_im_p2p>  	<text  		type="string"  		name="contact_name"  		layout="topleft"  		top="8" -		left="70" -		height="20" -		width="230" +		left_pad="6" +		height="28" +		width="235"  		length="1" -		follows="left|top|right|bottom" -		font="SansSerifBigBold" -		text_color="White">Contact Name</text> -	<button -		name="hide_btn" -		layout="topleft" -		top="10" -		left="310" -		height="20" -		width="20" -		label="" -		image_unselected="toast_hide_btn.tga" -		image_disabled="toast_hide_btn.tga" -		image_selected="toast_hide_btn.tga" -		image_hover_selected="toast_hide_btn.tga" -		image_disabled_selected="toast_hide_btn.tga"> -	</button> +		follows="right|left" +		font="SansSerifBold" +		text_color="White"> +    Contact Name +  </text> +  <button +    top="5" +    left_pad="5" +    width="15" +    height="15" +    layout="topleft" +    follows="right" +    name="hide_btn" +    mouse_opaque="true" +    label="" +    tab_stop="false" +    image_unselected="toast_hide_btn.tga" +    image_disabled="toast_hide_btn.tga" +    image_selected="toast_hide_btn.tga" +    image_hover_selected="toast_hide_btn.tga" +    image_disabled_selected="toast_hide_btn.tga" +  />  </panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index b6d0678cfb..8fc029bea6 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -216,41 +216,7 @@           left="0"           top="0"           width="5"/> -        <layout_panel -         auto_resize="false" -         follows="right" -         height="28" -         layout="topleft" -         min_height="28" -         name="im_well_panel" -         width="40" -         top="0" -         min_width="40"  -         user_resize="false"> -            <chiclet_notification -             follows="right" -             height="25" -             layout="topleft" -             left="0" -             name="im_well" -             top="2" -             width="40"> -              <button -               image_selected="im_notifications.tga" -               image_unselected="im_notifications.tga"/> -              <unread_notifications -               width="20" -               height="20" -               left="18" -               top="23"/> -<!--  -			  <chiclet_notification.commit_callback -				 function="Notification.Show" -				 parameter="ClickUnimplemented" /> - -->               				  -			</chiclet_notification> -        </layout_panel> -        <icon +      <icon           auto_resize="false"           color="0 0 0 0"           follows="left|right" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 2de41a9ee6..6ba4d13117 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -69,6 +69,7 @@       left_delta="0"       name="founder_name"       top_pad="10" +     use_ellipses="true"       width="140" />      <button       top="632" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 22823ea98b..e5a417e3d0 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -130,24 +130,15 @@                   min_height="100"                   name="tab_online"                   title="Online"> -                    <panel -                     follows="all" -                     height="150" -                     layout="topleft" -                     left="0" -                     name="tab_online_panel" -                     top="100" -                     width="285">                          <avatar_list                           draw_heading="false"                           follows="all" -                         height="145" +                         height="150"                           layout="topleft"                           left="0"                           name="avatars_online"                           top="0"                           width="285" /> -                    </panel>                  </accordion_tab>                  <accordion_tab                   can_resize="false" @@ -155,14 +146,6 @@                   min_height="100"                   name="tab_all"                   title="All"> -                    <panel -                     follows="all" -                     height="260" -                     layout="topleft" -                     left="0" -                     name="tab_all_panel" -                     top="100" -                     width="285">                          <avatar_list                           draw_heading="false"                           follows="all" @@ -172,7 +155,6 @@                           name="avatars_all"                           top="0"                           width="285" /> -                    </panel>                  </accordion_tab>              </accordion>              <panel diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index ff161cc2ab..c56bb32feb 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -28,11 +28,11 @@           opaque="true"           top="0"           width="284"> -            <panel +            <list               height="115"               layout="topleft"               left="0" -             name="back_panel" +             name="picks_list"               top="0"               width="284" />          </scroll_container> diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index 32223d542d..9aa2c304f2 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -8,6 +8,14 @@   min_width="240"   name="panel_target_profile"   width="305"> +    <string +     name="status_online"> +        Online +    </string> +    <string +     name="status_offline"> +        Offline +    </string>      <text       follows="top|left|right"       font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/widgets/list.xml b/indra/newview/skins/default/xui/en/widgets/list.xml new file mode 100644 index 0000000000..8c264205d5 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/list.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<list + allow_select="true" + bg_opaque_color="PanelFocusBackgroundColor" + bg_alpha_color="PanelDefaultBackgroundColor" + background_visible="false" + background_opaque="false" + item_pad="5" + multi_select="false" />
\ No newline at end of file  | 
