diff options
| author | Steven Bennetts <steve@lindenlab.com> | 2009-07-30 23:22:41 +0000 | 
|---|---|---|
| committer | Steven Bennetts <steve@lindenlab.com> | 2009-07-30 23:22:41 +0000 | 
| commit | e97f7728a90dd66014f6b3f0cd5e8d4c71f48691 (patch) | |
| tree | 4be178df6b50a3395105cdd3ac0044d6467a9fa3 | |
| parent | d5aa10143a0e6457b3326ba839c81b7c956a015e (diff) | |
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1170 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1187 -> viewer-2.0.0-3
97 files changed, 2625 insertions, 1388 deletions
| diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index fdb4bdd5c1..ad2d8afe45 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -793,6 +793,16 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )  	return FALSE;  } +BOOL LLMenuItemCallGL::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ +	if (pointInView(x, y)) +	{ +		mRightClickSignal(this, getValue()); +	} + +	return TRUE; +} +  ///============================================================================  /// Class LLMenuItemCheckGL  ///============================================================================ diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 262f75f1e1..f786c891d7 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -283,6 +283,7 @@ public:  	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);  	virtual BOOL handleKeyHere(KEY key, MASK mask); +	virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);  	//virtual void draw(); @@ -295,6 +296,11 @@ public:  	{  		return mEnableSignal.connect(cb);  	} + +	boost::signals2::connection setRightClickedCallback( const commit_signal_t::slot_type& cb ) +	{ +		return mRightClickSignal.connect(cb); +	}  private:  	enable_signal_t mEnableSignal; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 2b6ae1f67e..9845b7e2ce 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -710,6 +710,15 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe  	return mChanged.connect(slot);  } +LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot) +{ +	for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it) +	{ +		slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id())); +	} +	return mChanged.connect(slot, boost::signals2::at_front); +} +  LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)  {  	// these two filters only fire for notifications added after the current one, because @@ -1076,10 +1085,13 @@ void LLNotifications::createDefaultChannels()  	// connect action methods to these channels  	LLNotifications::instance().getChannel("Expiration")->          connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1)); +	// uniqueHandler slot should be added as first slot of the signal due to +	// usage LLStopWhenHandled combiner in LLStandardSignal  	LLNotifications::instance().getChannel("Unique")-> -        connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); -	LLNotifications::instance().getChannel("Unique")-> -        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1)); +        connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1)); +// failedUniquenessTest slot isn't necessary +//	LLNotifications::instance().getChannel("Unique")-> +//        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));  	LLNotifications::instance().getChannel("Ignore")->  		connectFailedFilter(&handleIgnoredNotification);  } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 63eae7278f..4da121c9c5 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -693,6 +693,14 @@ public:                                                this,                                                _1));      } +	template <typename LISTENER> +    LLBoundListener connectAtFrontChanged(const LISTENER& slot) +    { +        return LLEventDetail::visit_and_connect(slot, +                                  boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl, +                                              this, +                                              _1)); +    }      template <typename LISTENER>  	LLBoundListener connectPassedFilter(const LISTENER& slot)      { @@ -718,6 +726,7 @@ public:  protected:      LLBoundListener connectChangedImpl(const LLEventListener& slot); +    LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot);      LLBoundListener connectPassedFilterImpl(const LLEventListener& slot);      LLBoundListener connectFailedFilterImpl(const LLEventListener& slot); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2e29a56e79..9a0c9d9c7b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -243,6 +243,7 @@ set(viewer_SOURCE_FILES      llinventoryfilter.cpp      llinventorymodel.cpp      lljoystickbutton.cpp +    lllandmarkactions.cpp      lllandmarklist.cpp      lllistbrowser.cpp      lllistview.cpp @@ -269,6 +270,7 @@ set(viewer_SOURCE_FILES      llnamelistctrl.cpp      llnavigationbar.cpp      llnearbychat.cpp +    llnearbychatbar.cpp      llnearbychathandler.cpp      llnetmap.cpp      llnotificationalerthandler.cpp @@ -680,6 +682,7 @@ set(viewer_HEADER_FILES      llinventoryfilter.h      llinventorymodel.h      lljoystickbutton.h +    lllandmarkactions.h      lllandmarklist.h      lllightconstants.h      lllistbrowser.h @@ -707,6 +710,7 @@ set(viewer_HEADER_FILES      llnamelistctrl.h      llnavigationbar.h      llnearbychat.h +    llnearbychatbar.h      llnearbychathandler.h      llnetmap.h      llnotificationhandler.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ab9b018150..edcd288b7d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4749,6 +4749,83 @@        <key>Value</key>        <integer>350</integer>      </map> +    <key>NotificationToastTime</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>5</integer> +    </map> +    <key>StartUpToastTime</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>10</integer> +    </map> +    <key>ToastMargin</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>5</integer> +    </map> +    <key>ChannelBottomPanelMargin</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>35</integer> +    </map> +    <key>NotificationChannelRightMargin</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>10</integer> +    </map> +    <key>NavBarMargin</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>60</integer> +    </map> +    <key>OverflowToastHeight</key> +    <map> +      <key>Comment</key> +      <string>Width of notification messages</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>72</integer> +    </map>      <key>NotifyMoneyChange</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index afad88770e..f527719a7a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -98,6 +98,7 @@  #include "pipeline.h"  #include "lltrans.h"  #include "llbottomtray.h" +#include "llnearbychatbar.h"  #include "stringize.h"  #include "llcapabilitylistener.h" @@ -2721,7 +2722,7 @@ void LLAgent::startTyping()  	{  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);  	} -	LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); +	LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);  }  //----------------------------------------------------------------------------- @@ -2733,7 +2734,7 @@ void LLAgent::stopTyping()  	{  		clearRenderState(AGENT_STATE_TYPING);  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); -		LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); +		LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);  	}  } @@ -6575,49 +6576,6 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)  	}//end for (all message sets in xml file)  } -// static -void LLAgent::createLandmarkHere() -{ -	std::string landmark_name, landmark_desc; - -	gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK); -	gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL); -	LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); - -	createLandmarkHere(landmark_name, landmark_desc, folder_id); -} - -// static -void LLAgent::createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id) -{ -	LLViewerRegion* agent_region = gAgent.getRegion(); -	if(!agent_region) -	{ -		llwarns << "No agent region" << llendl; -		return; -	} -	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); -	if (!agent_parcel) -	{ -		llwarns << "No agent parcel" << llendl; -		return; -	} -	if (!agent_parcel->getAllowLandmark() -		&& !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) -	{ -		LLNotifications::instance().add("CannotCreateLandmarkNotOwner"); -		return; -	} - -	create_inventory_item(gAgent.getID(), gAgent.getSessionID(), -						  folder_id, LLTransactionID::tnull, -						  name, desc, -						  LLAssetType::AT_LANDMARK, -						  LLInventoryType::IT_LANDMARK, -						  NOT_WEARABLE, PERM_ALL,  -						  NULL); -} -  void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )  {  	gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 22b3790c6b..e25bb0a578 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -263,8 +263,6 @@ public:  	std::string		getSLURL() const;  	BOOL			inPrelude();  	BOOL 			buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK); // Utility to build a location string -	static void		createLandmarkHere(); -	static void		createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id);  private:  	LLViewerRegion	*mRegionp; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2299a439e6..245e358d80 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4034,5 +4034,8 @@ void LLAppViewer::handleLoginComplete()  	{  		gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();  	} + +	mOnLoginCompleted(); +  	writeDebugInfo();  } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index bbc2b646c4..646b677264 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -161,6 +161,11 @@ public:      LLAllocator & getAllocator() { return mAlloc; } +	// On LoginCompleted callback +	typedef boost::signals2::signal<void (void)> login_completed_signal_t; +	login_completed_signal_t mOnLoginCompleted; +	boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }  +  	void purgeCache(); // Clear the local cache.   protected: diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 2cf7298569..281d73b18b 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -73,6 +73,9 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin  	{      	LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);  	} + +	// add friend to recent people list +	LLRecentPeople::instance().add(id);  }  // static diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index a3b8f6726d..f6eb7f6494 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -42,12 +42,15 @@  #include "lluictrlfactory.h"  #include "llcachename.h" +#include "llagentdata.h"  #define MENU_ITEM_VIEW_PROFILE 0  #define MENU_ITEM_SEND_IM 1  static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon"); +LLAvatarIconCtrl::avatar_image_map_t LLAvatarIconCtrl::sImagesCache; +  LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)  :	LLIconCtrl(p),  	mDrawTooltip(p.draw_tooltip) @@ -137,7 +140,17 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)  			LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this);  			LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(value.asUUID(),APT_PROPERTIES);  			mAvatarId = value.asUUID(); + +			// Check if cache already contains image_id for that avatar +			avatar_image_map_t::iterator it; + +			it = sImagesCache.find(mAvatarId); +			if (it != sImagesCache.end()) +			{ +				updateFromCache(it->second); +			}  		} +  	}  	else  	{ @@ -147,6 +160,37 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)  	gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4));  } +void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data) +{ +	// Update the avatar +	if (data.image_id.notNull()) +	{ +		LLIconCtrl::setValue(data.image_id); +	} +	else +	{ +		LLIconCtrl::setValue("default_profile_picture.j2c"); +	} + +	// Update color of status symbol and tool tip +	if (data.flags & AVATAR_ONLINE) +	{ +		mStatusSymbol->setColor(LLColor4::green); +		if (mDrawTooltip) +		{ +			setToolTip((LLStringExplicit)"Online"); +		} +	} +	else +	{ +		mStatusSymbol->setColor(LLColor4::grey); +		if (mDrawTooltip) +		{ +			setToolTip((LLStringExplicit)"Offline"); +		} +	} +} +  //virtual  void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)  { @@ -160,33 +204,10 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)  				return;  			} -			// Update the avatar -			if (avatar_data->image_id.notNull()) -			{ -				LLIconCtrl::setValue(avatar_data->image_id); -			} -			else -			{ -				LLIconCtrl::setValue("default_profile_picture.j2c"); -			} +			LLAvatarIconCtrl::LLImagesCacheItem data(avatar_data->image_id, avatar_data->flags); -			// Update color of status symbol and tool tip -			if (avatar_data->flags & AVATAR_ONLINE) -			{ -				mStatusSymbol->setColor(LLColor4::green); -				if (mDrawTooltip) -				{ -					setToolTip((LLStringExplicit)"Online"); -				} -			} -			else -			{ -				mStatusSymbol->setColor(LLColor4::grey); -				if (mDrawTooltip) -				{ -					setToolTip((LLStringExplicit)"Offline"); -				} -			} +			updateFromCache(data); +			sImagesCache.insert(std::pair<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem>(mAvatarId, data));  		}  	}  } @@ -198,10 +219,17 @@ BOOL LLAvatarIconCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  	if(menu)  	{  		bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarId) != NULL; - +		  		menu->setItemEnabled("Add Friend", !is_friend);  		menu->setItemEnabled("Remove Friend", is_friend); +		if(gAgentID == mAvatarId) +		{ +			menu->setItemEnabled("Add Friend", false); +			menu->setItemEnabled("Send IM", false); +			menu->setItemEnabled("Remove Friend", false); +		} +  		menu->buildDrawLabels();  		menu->updateParent(LLMenuGL::sMenuContainer);  		LLMenuGL::showPopup(this, menu, x, y); diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index e34f2ff474..10ce827d6d 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -85,6 +85,20 @@ protected:  	std::string			mLastName;  	LLHandle<LLView>	mPopupMenuHandle;  	bool				mDrawTooltip; + +	struct LLImagesCacheItem +	{ +		LLUUID	image_id; +		U32   	flags; + +		LLImagesCacheItem(LLUUID image_id_, U32 flags_) : image_id(image_id_), flags(flags_) {} +	}; + +	typedef std::map<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem> avatar_image_map_t; +	 +	static avatar_image_map_t sImagesCache; + +	void updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data);  };  #endif  // LL_LLAVATARICONCTRL_H diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 7b5ce765d3..a85f8710c7 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -37,24 +37,40 @@  // newview  #include "llcallingcard.h" // for LLAvatarTracker  #include "llcachename.h" +#include "lloutputmonitorctrl.h" +#include "llvoiceclient.h"  static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");  LLAvatarList::Params::Params() +: +	volume_column_width("volume_column_width", 0) +	, online_go_first("online_go_first", true)  {  	draw_heading	= true;  	draw_stripes	= false;  	multi_select	= false;  	column_padding	= 0; -	search_column	= LIST_NAME; -	sort_column		= LIST_NAME; +	search_column	= COL_NAME; +	sort_column		= COL_NAME;  }  LLAvatarList::LLAvatarList(const Params& p)  :	LLScrollListCtrl(p) +	, mHaveVolumeColumn(p.volume_column_width > 0) +	, mOnlineGoFirst(p.online_go_first)  {  	setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params +    // "volume" column +    { +    	LLScrollListColumn::Params col_params; +    	col_params.name = "volume"; +    	col_params.header.label = "Volume"; // *TODO: localize or remove the header +    	col_params.width.pixel_width = p.volume_column_width; +    	addColumn(col_params); +    } +      // "name" column      {      	LLScrollListColumn::Params col_params; @@ -63,18 +79,42 @@ LLAvatarList::LLAvatarList(const Params& p)      	col_params.width.dynamic_width = true;      	addColumn(col_params);      } + +    // "online status" column +    { +    	LLScrollListColumn::Params col_params; +    	col_params.name = "online"; +    	col_params.header.label = "Online"; // *TODO: localize or remove the header +    	col_params.width.pixel_width = 0; // invisible column +    	addColumn(col_params); +    } +      // invisible "id" column      {      	LLScrollListColumn::Params col_params;      	col_params.name = "id"; +    	col_params.header.label = "ID"; // *TODO: localize or remove the header      	col_params.width.pixel_width = 0;      	addColumn(col_params);      } -    // The corresponding parameters don't work because we create columns dynamically. -    sortByColumnIndex(LIST_NAME, TRUE); -    setSearchColumn(LIST_NAME); +	// Primary sort = online status, secondary sort = name +	// The corresponding parameters don't work because we create columns dynamically. +	sortByColumnIndex(COL_NAME, TRUE); +	if (mOnlineGoFirst) +		sortByColumnIndex(COL_ONLINE, FALSE); +	setSearchColumn(COL_NAME); +} + +// virtual +void LLAvatarList::draw() +{ +	LLScrollListCtrl::draw(); +	if (mHaveVolumeColumn) +	{ +		updateVolume(); +	}  }  std::vector<LLUUID> LLAvatarList::getSelectedIDs() @@ -97,17 +137,30 @@ void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bo  	LLSD element;  	element["id"] = id; -	LLSD& friend_column = element["columns"][LIST_NAME]; +	// Update volume column (if we have one) +	{ +		std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : ""; +		LLSD& volume_column = element["columns"][COL_VOLUME]; +		volume_column["column"] = "volume"; +		volume_column["type"] = "icon"; +		volume_column["value"] = icon; +	} + +	LLSD& friend_column = element["columns"][COL_NAME];  	friend_column["column"] = "name";  	friend_column["value"] = name; +	LLSD& online_column = element["columns"][COL_ONLINE]; +	online_column["column"] = "online"; +	online_column["value"] = is_bold ? "1" : "0"; +  	LLScrollListItem* new_itemp = addElement(element, pos);  	// Indicate buddy online status.  	// (looks like parsing font parameters from LLSD is broken)  	if (is_bold)  	{ -		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(LIST_NAME)); +		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(COL_NAME));  		if (name_textp)  			name_textp->setFontStyle(LLFontGL::BOLD);  		else @@ -169,3 +222,70 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str  	return have_names;  } + +// static +std::string LLAvatarList::getVolumeIcon(const LLUUID& id) +{ +	// +	// Determine icon appropriate for the current avatar volume. +	// +	// *TODO: remove this in favor of LLOutputMonitorCtrl +	// when ListView widget is implemented +	// which is capable of containing arbitrary widgets. +	// +	static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>()); +	bool		muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id); +	F32			power = gVoiceClient->getCurrentPower(id); +	std::string	icon; + +	if (muted) +	{ +		icon = default_monitor_params.image_mute.name; +	} +	else if (power == 0.f) +	{ +		icon = default_monitor_params.image_off.name; +	} +	else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL) +	{ +		S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)); +		switch(icon_image_idx) +		{ +		default: +		case 0: +			icon = default_monitor_params.image_on.name; +			break; +		case 1: +			icon = default_monitor_params.image_level_1.name; +			break; +		case 2: +			icon = default_monitor_params.image_level_2.name; +			break; +		} +	} +	else +	{ +		// overdriven +		icon = default_monitor_params.image_level_3.name; +	} + +	return icon; +} + +// Update volume column for all list rows. +void LLAvatarList::updateVolume() +{ +	item_list& items = getItemList(); + +	for (item_list::iterator item_it = items.begin(); +		item_it != items.end(); +		++item_it) +	{ +		LLScrollListItem* itemp = (*item_it); +		LLUUID speaker_id = itemp->getUUID(); + +		LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME); +		if (icon_cell) +			icon_cell->setValue(getVolumeIcon(speaker_id)); +	} +} diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 9dba719fee..8b419dbb57 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -42,23 +42,37 @@ class LLAvatarList : public LLScrollListCtrl  public:  	struct Params : public LLInitParam::Block<Params, LLScrollListCtrl::Params>  	{ +		Optional<S32> volume_column_width; +		Optional<bool> online_go_first;  		Params();  	}; -	enum AVATAR_LIST_COLUMN_ORDER +	enum EColumnOrder  	{ -		LIST_NAME, +		COL_VOLUME, +		COL_NAME, +		COL_ONLINE, +		COL_ID,  	};  	LLAvatarList(const Params&);  	virtual	~LLAvatarList() {} +	/*virtual*/ void	draw(); +  	BOOL update(const std::vector<LLUUID>& all_buddies,  		const std::string& name_filter = LLStringUtil::null);  protected:  	std::vector<LLUUID> getSelectedIDs();  	void addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM); + +private: +	static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume +	void updateVolume(); // update volume for all avatars + +	bool mHaveVolumeColumn; +	bool mOnlineGoFirst;  };  #endif // LL_LLAVATARLIST_H diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 963946e888..1781e6b3f1 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -37,174 +37,30 @@  #include "llchiclet.h"  #include "llfloaterreg.h"  #include "llflyoutbutton.h" -#include "llimpanel.h" -#include "llkeyboard.h" -#include "lllineeditor.h" -#include "llgesturemgr.h" -#include "llanimationstates.h" -#include "llmultigesture.h" -#include "llviewerstats.h" -#include "llcommandhandler.h" +#include "llnearbychatbar.h"  //FIXME: temporary, for stand up proto  #include "llselectmgr.h"   #include "llvoavatarself.h" -S32 LLBottomTray::sLastSpecialChatChannel = 0; - -// legacy calllback glue -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); - -static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); - -LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p) -	: LLComboBox(p) -	, mGestureLabelTimer() -{ -	setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1)); - -	// now register us as observer since we have a place to put the results -	gGestureManager.addObserver(this); - -	// refresh list from current active gestures -	refreshGestures(); -} - -LLGestureComboBox::~LLGestureComboBox() -{ -	gGestureManager.removeObserver(this); -} - -void LLGestureComboBox::refreshGestures() -{ -	//store current selection so we can maintain it -	std::string cur_gesture = getValue().asString(); -	selectFirstItem(); -	std::string label = getValue().asString();; -	// clear -	clearRows(); - -	// collect list of unique gestures -	std::map <std::string, BOOL> unique; -	LLGestureManager::item_map_t::iterator it; -	for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) -	{ -		LLMultiGesture* gesture = (*it).second; -		if (gesture) -		{ -			if (!gesture->mTrigger.empty()) -			{ -				unique[gesture->mTrigger] = TRUE; -			} -		} -	} - -	// add unique gestures -	std::map <std::string, BOOL>::iterator it2; -	for (it2 = unique.begin(); it2 != unique.end(); ++it2) -	{ -		addSimpleElement((*it2).first); -	} - -	sortByName(); -	// Insert label after sorting, at top, with separator below it -	addSeparator(ADD_TOP);		 -	//FIXME: get it from xml -	addSimpleElement("Gestures", ADD_TOP);	 - -	if (!cur_gesture.empty()) -	{  -		selectByValue(LLSD(cur_gesture)); -	} -	else -	{ -		selectFirstItem(); -	} -} - -void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) -{ -	LLCtrlListInterface* gestures = getListInterface(); -	if (gestures) -	{ -		S32 index = gestures->getFirstSelectedIndex(); -		if (index == 0) -		{ -			return; -		} -		const std::string& trigger = gestures->getSelectedValue().asString(); - -		// pretend the user chatted the trigger string, to invoke -		// substitution and logging. -		std::string text(trigger); -		std::string revised_text; -		gGestureManager.triggerAndReviseString(text, &revised_text); - -		revised_text = utf8str_trim(revised_text); -		if (!revised_text.empty()) -		{ -			// Don't play nodding animation -			LLBottomTray::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); -		} -	} - -	mGestureLabelTimer.start(); -	// free focus back to chat bar -	setFocus(FALSE); -} - -//virtual -void LLGestureComboBox::draw() -{ -	// HACK: Leave the name of the gesture in place for a few seconds. -	const F32 SHOW_GESTURE_NAME_TIME = 2.f; -	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) -	{ -		LLCtrlListInterface* gestures = getListInterface(); -		if (gestures) gestures->selectFirstItem(); -		mGestureLabelTimer.stop(); -	} - -	LLComboBox::draw(); -} -  LLBottomTray::LLBottomTray(const LLSD&) -	: mChatBox(NULL) -	, mChicletPanel(NULL) +	: mChicletPanel(NULL)  	, mIMWell(NULL)  	, mSysWell(NULL)  	, mTalkBtn(NULL) -	, mGestureCombo(NULL)  	, mStandUpBtn(NULL)  ////FIXME: temporary, for stand up proto +	, mNearbyChatBar(NULL)  { +	mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL); +  	LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");  	mChicletPanel = getChild<LLChicletPanel>("chiclet_list",TRUE,FALSE);  	mIMWell = getChild<LLNotificationChiclet>("im_well",TRUE,FALSE);  	mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE); -	mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE);  	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); -	if (mChatBox) -	{ -		mChatBox->setCommitCallback(boost::bind(&LLBottomTray::onChatBoxCommit, this)); -		mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); -		mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this); - -		mChatBox->setIgnoreArrowKeys(TRUE); -		mChatBox->setCommitOnFocusLost( FALSE ); -		mChatBox->setRevertOnEsc( FALSE ); -		mChatBox->setIgnoreTab(TRUE); -		mChatBox->setPassDelete(TRUE); -		mChatBox->setReplaceNewlinesWithSpaces(FALSE); -		mChatBox->setMaxTextLength(1023); -		mChatBox->setEnableLineHistory(TRUE); - -	} - -	mGestureCombo = getChild<LLGestureComboBox>( "Gesture", TRUE, FALSE); -  	////FIXME: temporary, for stand up proto  	mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE);  	if (mStandUpBtn) @@ -246,156 +102,15 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)  	}  } -void LLBottomTray::onChatBoxCommit() -{ -	if (mChatBox && mChatBox->getText().length() > 0) -	{ -		sendChat(CHAT_TYPE_NORMAL); -	} - -	gAgent.stopTyping(); -} - -void LLBottomTray::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) -{ -	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); -} - -void LLBottomTray::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) -{ -	// Look for "/20 foo" channel chats. -	S32 channel = 0; -	LLWString out_text = stripChannelNumber(wtext, &channel); -	std::string utf8_out_text = wstring_to_utf8str(out_text); -	std::string utf8_text = wstring_to_utf8str(wtext); - -	utf8_text = utf8str_trim(utf8_text); -	if (!utf8_text.empty()) -	{ -		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); -	} - -	// Don't animate for chats people can't hear (chat to scripts) -	if (animate && (channel == 0)) -	{ -		if (type == CHAT_TYPE_WHISPER) -		{ -			lldebugs << "You whisper " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_NORMAL) -		{ -			lldebugs << "You say " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_SHOUT) -		{ -			lldebugs << "You shout " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); -		} -		else -		{ -			llinfos << "send_chat_from_viewer() - invalid volume" << llendl; -			return; -		} -	} -	else -	{ -		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) -		{ -			lldebugs << "Channel chat: " << utf8_text << llendl; -		} -	} - -	send_chat_from_viewer(utf8_out_text, type, channel); -} - -// static -void LLBottomTray::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) -{ -	LLBottomTray* self = (LLBottomTray *)userdata; - -	LLWString raw_text; -	if (self->getChatBox()) raw_text = self->getChatBox()->getWText(); - -	// Can't trim the end, because that will cause autocompletion -	// to eat trailing spaces that might be part of a gesture. -	LLWStringUtil::trimHead(raw_text); - -	S32 length = raw_text.length(); - -	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences -	{ -		gAgent.startTyping(); -	} -	else -	{ -		gAgent.stopTyping(); -	} - -	/* Doesn't work -- can't tell the difference between a backspace -	   that killed the selection vs. backspace at the end of line. -	if (length > 1  -		&& text[0] == '/' -		&& key == KEY_BACKSPACE) -	{ -		// the selection will already be deleted, but we need to trim -		// off the character before -		std::string new_text = raw_text.substr(0, length-1); -		self->mInputEditor->setText( new_text ); -		self->mInputEditor->setCursorToEnd(); -		length = length - 1; -	} -	*/ - -	KEY key = gKeyboard->currentKey(); - -	// Ignore "special" keys, like backspace, arrows, etc. -	if (length > 1  -		&& raw_text[0] == '/' -		&& key < KEY_SPECIAL) -	{ -		// we're starting a gesture, attempt to autocomplete - -		std::string utf8_trigger = wstring_to_utf8str(raw_text); -		std::string utf8_out_str(utf8_trigger); - -		if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) -		{ -			if (self->getChatBox()) -			{ -				std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -				self->getChatBox()->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part -				S32 outlength = self->getChatBox()->getLength(); // in characters -			 -				// Select to end of line, starting from the character -				// after the last one the user typed. -				self->getChatBox()->setSelection(length, outlength); -			} -		} - -		//llinfos << "GESTUREDEBUG " << trigger  -		//	<< " len " << length -		//	<< " outlen " << out_str.getLength() -		//	<< llendl; -	} -} - -// static -void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) +void* LLBottomTray::createNearbyChatBar(void* userdata)  { -	// stop typing animation -	gAgent.stopTyping(); -} +	LLBottomTray *bt = LLBottomTray::getInstance(); +	if (!bt) +		return NULL; -BOOL LLBottomTray::inputEditorHasFocus() -{ -	return mChatBox && mChatBox->hasFocus(); -} +	bt->mNearbyChatBar = new LLNearbyChatBar(); -std::string LLBottomTray::getCurrentChat() -{ -	return mChatBox ? mChatBox->getText() : LLStringUtil::null; +	return bt->mNearbyChatBar;  }  //virtual @@ -440,14 +155,9 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam  		}  		else  		{ -			LLIMChiclet* chicklet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id); -			chicklet->setIMSessionName(name); -			chicklet->setOtherParticipantId(other_participant_id); - -			if(getChicletPanel()->getChicletCount()) -			{ -				setChicletPanelVisible(true); -			} +			LLIMChiclet* chiclet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id); +			chiclet->setIMSessionName(name); +			chiclet->setOtherParticipantId(other_participant_id);  		}  	}  } @@ -458,27 +168,6 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id)  	if(getChicletPanel())  	{  		getChicletPanel()->removeChiclet(session_id); - -		if(0 == getChicletPanel()->getChicletCount()) -		{ -			setChicletPanelVisible(false); -		} -	} -} - -void LLBottomTray::setChicletPanelVisible(bool visible) -{ -	// Chiclet panel is placed in layout_panel, which is child of layout_stack. -	// To gide chiclet panel we need to also hide layout_panel to make layout_stack resize its -	// content. -	getChicletPanel()->getParent()->setVisible(visible); -	if(visible) -	{ -		// Reshape layout stack after making chiclet panel visible -		LLView* layout = getChild<LLView>("toolbar_stack"); -		LLRect rc = layout->getRect(); -		layout->reshape(rc.getWidth(), rc.getHeight()); -		layout->setRect(rc);  	}  } @@ -491,22 +180,6 @@ void LLBottomTray::onFocusLost()  	}  } -// virtual -BOOL LLBottomTray::handleKeyHere( KEY key, MASK mask ) -{ -	BOOL handled = FALSE; - -	// ALT-RETURN is reserved for windowed/fullscreen toggle -	if( KEY_RETURN == key && mask == MASK_CONTROL) -	{ -		// shout -		sendChat(CHAT_TYPE_SHOUT); -		handled = TRUE; -	} - -	return handled; -} -  //virtual  // setVisible used instead of onVisibilityChange, since LLAgent calls it on entering/leaving mouselook mode.  // If bottom tray is already visible in mouselook mode, then onVisibilityChange will not be called from setVisible(true), @@ -514,192 +187,22 @@ void LLBottomTray::setVisible(BOOL visible)  {  	LLPanel::setVisible(visible); -	 -	BOOL visibility = gAgent.cameraMouselook() ? false : true; +	LLView* stack = getChild<LLView>("toolbar_stack",TRUE,FALSE); -	LLViewBorder* separator = getChild<LLViewBorder>("well_separator",TRUE,FALSE); - -	if (separator && separator->getVisible() == visibility) -		return; - -	if (separator) -		separator->setVisible(visibility); - -	LLPanel* p = getChild<LLPanel>("chiclet_list_panel",TRUE,FALSE); -	if (p) -		p->setVisible(visibility); - -	p = getChild<LLPanel>("im_well_panel",TRUE,FALSE); -	if (p) -		p->setVisible(visibility); - -	p = getChild<LLPanel>("sys_well_panel",TRUE,FALSE); -	if (p) -		p->setVisible(visibility); - -} - -// static  -void LLBottomTray::startChat(const char* line) -{ -	LLBottomTray *bt = LLBottomTray::getInstance(); - -	if(bt && bt->getChatBox()) +	if (stack)  	{ -		bt->setVisible(TRUE); -		bt->getChatBox()->setFocus(TRUE); +		BOOL visibility = gAgent.cameraMouselook() ? false : true; -		if (line) +		for ( child_list_const_iter_t child_it = stack->getChildList()->begin(); child_it != stack->getChildList()->end(); child_it++)  		{ -			std::string line_string(line); -			bt->getChatBox()->setText(line_string); -		} - -		bt->getChatBox()->setCursorToEnd(); -	} -} - -// Exit "chat mode" and do the appropriate focus changes -// static -void LLBottomTray::stopChat() -{ -	LLBottomTray *bt = LLBottomTray::getInstance(); - -	if(bt && bt->getChatBox()) -	{ -		bt->getChatBox()->setFocus(FALSE); -	} - - 	// stop typing animation - 	gAgent.stopTyping(); -} - -void LLBottomTray::sendChat( EChatType type ) -{ -	if (mChatBox) -	{ -		LLWString text = mChatBox->getConvertedText(); -		if (!text.empty()) -		{ -			// store sent line in history, duplicates will get filtered -			mChatBox->updateHistory(); -			// Check if this is destined for another channel -			S32 channel = 0; -			stripChannelNumber(text, &channel); +			LLView* viewp = *child_it; -			std::string utf8text = wstring_to_utf8str(text); -			// Try to trigger a gesture, if not chat to a script. -			std::string utf8_revised_text; -			if (0 == channel) -			{ -				// discard returned "found" boolean -				gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); -			} -			else -			{ -				utf8_revised_text = utf8text; -			} - -			utf8_revised_text = utf8str_trim(utf8_revised_text); - -			if (!utf8_revised_text.empty()) +			if ("chat_bar" == viewp->getName()) +				continue; +			else   			{ -				// Chat with animation -				sendChatFromViewer(utf8_revised_text, type, TRUE); +				viewp->setVisible(visibility);  			}  		} - -		mChatBox->setText(LLStringExplicit(""));  	} - -	gAgent.stopTyping();  } - -// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -// Otherwise returns input and channel 0. -LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel) -{ -	if (mesg[0] == '/' -		&& mesg[1] == '/') -	{ -		// This is a "repeat channel send" -		*channel = sLastSpecialChatChannel; -		return mesg.substr(2, mesg.length() - 2); -	} -	else if (mesg[0] == '/' -			 && mesg[1] -			 && LLStringOps::isDigit(mesg[1])) -	{ -		// This a special "/20" speak on a channel -		S32 pos = 0; - -		// Copy the channel number into a string -		LLWString channel_string; -		llwchar c; -		do -		{ -			c = mesg[pos+1]; -			channel_string.push_back(c); -			pos++; -		} -		while(c && pos < 64 && LLStringOps::isDigit(c)); -		 -		// Move the pointer forward to the first non-whitespace char -		// Check isspace before looping, so we can handle "/33foo" -		// as well as "/33 foo" -		while(c && iswspace(c)) -		{ -			c = mesg[pos+1]; -			pos++; -		} -		 -		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); -		*channel = sLastSpecialChatChannel; -		return mesg.substr(pos, mesg.length() - pos); -	} -	else -	{ -		// This is normal chat. -		*channel = 0; -		return mesg; -	} -} - -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ChatFromViewer); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ChatData); -	msg->addStringFast(_PREHASH_Message, utf8_out_text); -	msg->addU8Fast(_PREHASH_Type, type); -	msg->addS32("Channel", channel); - -	gAgent.sendReliableMessage(); - -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} - -class LLChatHandler : public LLCommandHandler -{ -public: -	// not allowed from outside the app -	LLChatHandler() : LLCommandHandler("chat", true) { } - -    // Your code here -	bool handle(const LLSD& tokens, const LLSD& query_map, -				LLWebBrowserCtrl* web) -	{ -		if (tokens.size() < 2) return false; -		S32 channel = tokens[0].asInteger(); -		std::string mesg = tokens[1].asString(); -		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); -		return true; -	} -}; - -// Creating the object registers with the dispatcher. -LLChatHandler gChatHandler; - diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 08f5cb91d8..e5848f72dc 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -35,35 +35,12 @@  #include "llpanel.h"  #include "llimview.h" -#include "llchat.h" -#include "llgesturemgr.h" -#include "llcombobox.h"  class LLChicletPanel;  class LLLineEditor;  class LLNotificationChiclet;  class LLTalkButton; - -class LLGestureComboBox -	: public LLComboBox -	, public LLGestureManagerObserver -{ -protected: -	LLGestureComboBox(const LLComboBox::Params&); -	friend class LLUICtrlFactory; -public: -	~LLGestureComboBox(); - -	void refreshGestures(); -	void onCommitGesture(LLUICtrl* ctrl); -	virtual void draw(); - -	// LLGestureManagerObserver trigger -	virtual void changed() { refreshGestures(); } - -protected: -	LLFrameTimer mGestureLabelTimer; -}; +class LLNearbyChatBar;  class LLBottomTray   	: public LLUISingleton<LLBottomTray> @@ -74,19 +51,10 @@ class LLBottomTray  public:  	~LLBottomTray(); -	LLLineEditor*		getChatBox()	{return mChatBox;}  	LLChicletPanel*		getChicletPanel()	{return mChicletPanel;}  	LLNotificationChiclet*	getIMWell()	{return mIMWell;}  	LLNotificationChiclet*	getSysWell()	{return mSysWell;} - -	void onChatBoxCommit(); -	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); -	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); -	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); -	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); - -	BOOL inputEditorHasFocus(); -	std::string getCurrentChat(); +	LLNearbyChatBar*		getNearbyChatBar()	{return mNearbyChatBar;}  	/*virtual*/void draw();  	void refreshStandUp(); @@ -100,33 +68,22 @@ public:  	virtual void sessionRemoved(const LLUUID& session_id);  	virtual void onFocusLost(); -	virtual BOOL handleKeyHere(KEY key, MASK mask);  	virtual void setVisible(BOOL visible); -	static void startChat(const char* line); -	static void stopChat(); -  protected:  	LLBottomTray(const LLSD& key = LLSD()); -	void sendChat( EChatType type ); -	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); -  	void onChicletClick(LLUICtrl* ctrl); -	void setChicletPanelVisible(bool visible); - -	// Which non-zero channel did we last chat on? -	static S32 sLastSpecialChatChannel; +	static void* createNearbyChatBar(void* userdata); -	LLLineEditor*		mChatBox;  	LLChicletPanel* 	mChicletPanel;  	LLNotificationChiclet* 	mIMWell;  	LLNotificationChiclet* 	mSysWell;  	LLTalkButton* 		mTalkBtn; -	LLGestureComboBox*	mGestureCombo;  	LLButton*           mStandUpBtn; +	LLNearbyChatBar*	mNearbyChatBar;  };  #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 723bf2a248..0eb0801a2c 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -34,6 +34,9 @@  #include "llchannelmanager.h" +#include "llappviewer.h" +#include "llviewercontrol.h" +  #include <algorithm>  using namespace LLNotificationsUI; @@ -41,6 +44,7 @@ using namespace LLNotificationsUI;  //--------------------------------------------------------------------------  LLChannelManager::LLChannelManager()  { +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));  }  //-------------------------------------------------------------------------- @@ -50,6 +54,45 @@ LLChannelManager::~LLChannelManager()  }  //-------------------------------------------------------------------------- +void LLChannelManager::onLoginCompleted() +{ +	S32 hidden_notifications = 0; + +	for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it !=  mChannelList.end(); ++it) +	{ +		//(*it).channel->showToasts(); +		hidden_notifications +=(*it).channel->getNumberOfHiddenToasts(); +	} + +	if(!hidden_notifications) +	{ +		LLScreenChannel::setStartUpToastShown(); +		return; +	} +	 +	LLChannelManager::Params p; +	p.id = LLUUID(STARTUP_CHANNEL_ID); +	p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");  +	p.channel_width = gSavedSettings.getS32("NotifyBoxWidth"); +	mStartUpChannel = NULL; +	mStartUpChannel = createChannel(p); + +	if(!mStartUpChannel) +		return; + +	static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::enableShowToasts, this)); +	mStartUpChannel->setNumberOfHiddenToasts(hidden_notifications); +	mStartUpChannel->createOverflowToast(gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime")); +} + +//-------------------------------------------------------------------------- +void LLChannelManager::enableShowToasts() +{ +	LLScreenChannel::setStartUpToastShown(); +	delete mStartUpChannel; +} + +//--------------------------------------------------------------------------  LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)  {  	LLScreenChannel* new_channel = NULL; @@ -67,7 +110,8 @@ LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)  		return new_channel;  	new_channel = new LLScreenChannel();  -	new_channel->init(p.channel_right_bound - p.channel_width, getRootView()); +	getRootView()->addChild(new_channel); +	new_channel->init(p.channel_right_bound - p.channel_width, p.channel_right_bound);  	new_channel->setToastAlignment(p.align);  	ChannelElem new_elem; diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h index 564535ff24..3914d20ebc 100644 --- a/indra/newview/llchannelmanager.h +++ b/indra/newview/llchannelmanager.h @@ -45,6 +45,8 @@  namespace LLNotificationsUI  { +#define STARTUP_CHANNEL_ID		"AEED3193-8709-4693-8558-7452CCA97AE5" +  /**   * Manager for screen channels.   * Responsible for instantiating and retrieving screen channels. @@ -98,6 +100,10 @@ public:  	LLChannelManager();	  	virtual ~LLChannelManager(); +	// On LoginCompleted - show StartUp toast +	void onLoginCompleted(); +	void enableShowToasts(); +  	//TODO: make protected? in order to be shure that channels are created only by notification handlers  	LLScreenChannel*	createChannel(LLChannelManager::Params& p); @@ -108,6 +114,7 @@ public:  private: +	LLScreenChannel*			mStartUpChannel;  	std::vector<ChannelElem>	mChannelList;  }; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index bb31b7f2e8..2b455485ca 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -41,6 +41,7 @@  #include "lltrans.h"  #include "llviewercontrol.h" +#include "llagentdata.h"  static const S32 BORDER_MARGIN = 2;  static const S32 PARENT_BORDER_MARGIN = 0; @@ -51,6 +52,9 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;  static const F32 MAX_AUTO_SCROLL_RATE = 500.f;  static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; +static const S32 msg_left_offset = 30; +static const S32 msg_right_offset = 10; +  #define MAX_CHAT_HISTORY 100 @@ -89,8 +93,8 @@ void	LLChatItemCtrl::reshape		(S32 width, S32 height, BOOL called_from_parent )  		LLRect msg_text_rect = msg_text->getRect(); -		msg_text_rect.setLeftTopAndSize( 10, height - caption_rect.getHeight() , width - 20, height - caption_rect.getHeight()); -		msg_text->reshape( width - 20, height - caption_rect.getHeight(), 1); +		msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight()); +		msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1);  		msg_text->setRect(msg_text_rect);  	} @@ -132,11 +136,22 @@ void	LLChatItemCtrl::setMessage	(const LLChat& msg)  	LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);  	if(!caption)  		return; -	caption->getChild<LLTextBox>("sender_name",false,false)->setText(msg.mFromName); + +	std::string str_sender; + +	 +	if(gAgentID != msg.mFromID) +		str_sender = msg.mFromName; +	else +		str_sender = LLTrans::getString("You");; + +	caption->getChild<LLTextBox>("sender_name",false,false)->setText(str_sender); +	  	std::string tt = appendTime();  	caption->getChild<LLTextBox>("msg_time",false,false)->setText(tt); +  	caption->getChild<LLAvatarIconCtrl>("avatar_icon",false,false)->setValue(msg.mFromID);  	mOriginalMessage = msg; @@ -153,6 +168,28 @@ void	LLChatItemCtrl::setMessage	(const LLChat& msg)  } +void	LLChatItemCtrl::snapToMessageHeight	() +{ +	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text",false,false); +	if(!text_box) +		return;///actually assert fits better +	S32 new_height = text_box->getTextPixelHeight(); +	LLRect panel_rect = getRect(); + +	S32 caption_height = 0; +	LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); +	if(caption) +		caption_height = caption->getRect().getHeight(); + + +	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth()	, caption_height + new_height); +	 +	reshape( getRect().getWidth(), caption_height + new_height, 1); +	 +	setRect(panel_rect); + +} +  void	LLChatItemCtrl::setWidth(S32 width)  { @@ -160,7 +197,7 @@ void	LLChatItemCtrl::setWidth(S32 width)  	if(!text_box)  		return;///actually assert fits better -	text_box->reshape(width - 20,100/*its not magic number, we just need any number*/); +	text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);  	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text",false,false);  	if(msg_text && mOriginalMessage.mText.length()) @@ -169,13 +206,8 @@ void	LLChatItemCtrl::setWidth(S32 width)  	for(size_t i=0;i<mMessages.size();++i)  		msg_text->addText(mMessages[i]); -	S32 new_height = text_box->getTextPixelHeight(); -	LLRect panel_rect = getRect(); -	panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, width	, 35 + new_height); -	 -	reshape( width, panel_rect.getHeight(), 1); -	 -	setRect(panel_rect); +	setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width	, getRect().mBottom)); +	snapToMessageHeight	();  }  void LLChatItemCtrl::onMouseLeave			(S32 x, S32 y, MASK mask) @@ -190,6 +222,8 @@ void LLChatItemCtrl::onMouseLeave			(S32 x, S32 y, MASK mask)  }  void LLChatItemCtrl::onMouseEnter				(S32 x, S32 y, MASK mask)  { +	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) +		return;  	LLPanel* caption = getChild<LLPanel>("msg_caption",false,false);  	if(!caption)  		return; @@ -200,8 +234,10 @@ void LLChatItemCtrl::onMouseEnter				(S32 x, S32 y, MASK mask)  BOOL	LLChatItemCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)  { +	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) +		return LLPanel::handleMouseDown(x,y,mask);  	LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); -	if(mOriginalMessage.mSourceType == CHAT_SOURCE_AGENT && caption) +	if(caption)  	{  		LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");  		if(msg_inspector) @@ -242,6 +278,23 @@ bool	LLChatItemCtrl::canAddText	()  	return msg_text->getTextLinesNum()<10;  } +BOOL	LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	LLPanel* caption = getChild<LLPanel>("msg_caption",false,false); +	if(!caption) +		return LLPanel::handleRightMouseDown(x,y,mask); +	LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon",false,false); +	if(!avatar_icon) +		return LLPanel::handleRightMouseDown(x,y,mask); +	S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft; +	S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom; + +	//eat message for avatar icon if msg was from object +	if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT) +		return TRUE; +	return LLPanel::handleRightMouseDown(x,y,mask); +} +  //*******************************************************************************************************************  //LLChatItemsContainerCtrl @@ -264,13 +317,18 @@ void	LLChatItemsContainerCtrl::addMessage(const LLChat& msg)  		LLChatItemCtrl* item = mItems[0];  		removeChild(item);  		delete item; +		mItems.erase(mItems.begin());  	} -	if(mItems.size() > 0 && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID && mItems[mItems.size()-1]->canAddText()) +	if(mItems.size() > 0  +		&& msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID  +		&& (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60 +		&& mItems[mItems.size()-1]->canAddText() +		)  	{  		mItems[mItems.size()-1]->addText(msg.mText); -		mItems[mItems.size()-1]->setWidth(getRect().getWidth() - 16); +		mItems[mItems.size()-1]->snapToMessageHeight();  	}  	else  	{ @@ -279,6 +337,8 @@ void	LLChatItemsContainerCtrl::addMessage(const LLChat& msg)  		addChild(item,0);  		item->setWidth(getRect().getWidth() - 16);  		item->setMessage(msg); +		item->snapToMessageHeight(); +		  		item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));  		item->setVisible(true); diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index f5791078aa..de16cf9505 100644 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -63,6 +63,7 @@ public:  	void	addText		(const std::string& message);  	void	setMessage	(const LLChat& msg);  	void	setWidth		(S32 width); +	void	snapToMessageHeight	();  	bool	canAddText	(); @@ -75,6 +76,7 @@ public:  	void	reshape		(S32 width, S32 height, BOOL called_from_parent = TRUE);  	void	setHeaderVisibility(EShowItemHeader e); +	BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);  private:  	std::string appendTime	(); diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index 8fb4b78cb8..933d9b8771 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -51,9 +51,8 @@ LLChatMsgBox::Params::Params()  	disabled_color("disabled_color"),  	background_color("background_color"),  	border_color("border_color"), -	v_pad("v_pad", 0), -	h_pad("h_pad", 0), -	line_spacing("line_spacing", 0), +	line_spacing("line_spacing", 4), +	block_spacing("block_spacing",10),  	text("text"),  	font_shadow("font_shadow", LLFontGL::NO_SHADOW)  {} @@ -68,8 +67,6 @@ LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)  	mShadowType( p.font_shadow ),  	mBorderDropShadowVisible( p.border_drop_shadow_visible ),  	mUseEllipses( p.use_ellipses ), -	mHPad(p.h_pad), -	mVPad(p.v_pad),  	mVAlign( LLFontGL::TOP ),  	mClickedCallback(NULL),  	mTextColor(p.text_color()), @@ -79,6 +76,7 @@ LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)  	mHoverColor(p.hover_color()),  	mHAlign(p.font_halign),  	mLineSpacing(p.line_spacing), +	mBlockSpasing(p.block_spacing),  	mWordWrap( p.word_wrap ),  	mFontStyle(LLFontGL::getStyleFromString(p.font.style))  { @@ -271,7 +269,7 @@ S32	LLChatMsgBox::getTextLinesNum()  S32 LLChatMsgBox::getTextPixelHeight()  {  	S32 num_lines = getTextLinesNum(); -	return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*4); +	return (S32)(num_lines * mFontGL->getLineHeight() +  (num_lines-1)*mLineSpacing + mBlockSpasing*(mTextStrings.size()-1) + 2*mLineSpacing);//some extra space  }  void LLChatMsgBox::setValue(const LLSD& value ) @@ -305,17 +303,16 @@ void LLChatMsgBox::draw()  	switch( mHAlign )  	{  	case LLFontGL::LEFT:	 -		text_x = mHPad;						  		break;  	case LLFontGL::HCENTER:  		text_x = getRect().getWidth() / 2;  		break;  	case LLFontGL::RIGHT: -		text_x = getRect().getWidth() - mHPad; +		text_x = getRect().getWidth() ;  		break;  	} -	S32 text_y = getRect().getHeight() - mVPad; +	S32 text_y = getRect().getHeight() ;  	if ( getEnabled() )  	{ @@ -358,6 +355,7 @@ void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent)  void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )  {  	S32 width = getRect().getWidth()-10; +  	for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();  			it!=mTextStrings.end();++it) @@ -383,8 +381,9 @@ void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )  		if(next == mTextStrings.end())  			break;  		//separator -		gl_line_2d(5,y-2,width,y-2,LLColor4::grey); -		y-=4; +		gl_line_2d(5,y-mBlockSpasing/2,width,y-mBlockSpasing/2,LLColor4::grey); +		y-=mBlockSpasing;  	} +  } diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h index c0e1964afa..61035499c7 100644 --- a/indra/newview/llchatmsgbox.h +++ b/indra/newview/llchatmsgbox.h @@ -71,9 +71,9 @@ public:  							background_color,  							border_color; -		Optional<S32>		v_pad, -							h_pad, -							line_spacing; +		Optional<S32>		line_spacing; +		 +		Optional<S32>		block_spacing;  		Params();  	}; @@ -104,8 +104,6 @@ public:  	void			setBackgroundVisible(BOOL visible)		{ mBackgroundVisible = visible; }  	void			setBorderVisible(BOOL visible)			{ mBorderVisible = visible; }  	void			setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; } -	void			setHPad(S32 pixels)						{ mHPad = pixels; } -	void			setVPad(S32 pixels)						{ mVPad = pixels; }  	void			setRightAlign()							{ mHAlign = LLFontGL::RIGHT; }  	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }  	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); }		// mouse down and up within button @@ -145,9 +143,8 @@ private:  	BOOL			mUseEllipses;  	S32				mLineSpacing; +	S32				mBlockSpasing; -	S32				mHPad; -	S32				mVPad;  	LLFontGL::HAlign mHAlign;  	LLFontGL::VAlign mVAlign; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index bfa4e06d2e..f71ea9f8ad 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -428,9 +428,11 @@ LLChicletPanel::Params::Params()  , scrolling_offset("scrolling_offset")  , left_scroll_button("left_scroll_button")  , right_scroll_button("right_scroll_button") +, min_width("min_width")  {  	chiclet_padding = 3;  	scrolling_offset = 40; +	min_width = 70;  	LLRect scroll_button_rect(0, 25, 19, 5); @@ -458,6 +460,8 @@ LLChicletPanel::LLChicletPanel(const Params&p)  , mRightScrollButton(NULL)  , mChicletPadding(p.chiclet_padding)  , mScrollingOffset(p.scrolling_offset) +, mMinWidth(p.min_width) +, mShowControls(true)  {  	LLButton::Params scroll_button_params = p.left_scroll_button; @@ -660,6 +664,9 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )  	mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,  		height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); +	mShowControls = width > mMinWidth; +	mScrollArea->setVisible(mShowControls); +  	trimChiclets();  	showScrollButtonsIfNeeded(); @@ -719,7 +726,7 @@ void LLChicletPanel::showScrollButtonsIfNeeded()  	mLeftScrollButton->setEnabled(can_scroll_left);  	mRightScrollButton->setEnabled(can_scroll_right); -	bool show_scroll_buttons = can_scroll_left || can_scroll_right; +	bool show_scroll_buttons = (can_scroll_left || can_scroll_right) && mShowControls;  	mLeftScrollButton->setVisible(show_scroll_buttons);  	mRightScrollButton->setVisible(show_scroll_buttons); @@ -950,6 +957,11 @@ void LLTalkButton::draw()  	LLUICtrl::draw();  } +void LLTalkButton::setSpeakBtnToggleState(bool state) +{ +	mSpeakBtn->setToggleState(state); +} +  void LLTalkButton::onClick_SpeakBtn()  {  	bool speaking = mSpeakBtn->getToggleState(); @@ -1012,7 +1024,14 @@ void LLChicletNotificationCounterCtrl::setCounter(S32 counter)  	std::stringstream stream;  	stream << getCounter(); -	setText(stream.str()); +	if(mCounter != 0) +	{ +		setText(stream.str()); +	} +	else +	{ +		setText(std::string("")); +	}  }  LLRect LLChicletNotificationCounterCtrl::getRequiredRect() diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 415ae59ca2..c20c81e052 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -390,6 +390,8 @@ public:  		Optional<LLButton::Params> left_scroll_button,  								   right_scroll_button; +		Optional<S32> min_width; +  		Params();  	}; @@ -558,6 +560,8 @@ protected:  	S32 mChicletPadding;  	S32 mScrollingOffset; +	S32 mMinWidth; +	bool mShowControls;  };  /* @@ -580,6 +584,7 @@ public:  	/*virtual*/ ~LLTalkButton();  	/*virtual*/ void draw(); +	void setSpeakBtnToggleState(bool state);  protected:  	friend class LLUICtrlFactory; diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 00d4f80054..72bfac70fc 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -216,6 +216,8 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  		}  	} +	bool recreate_buttons = true; +  	// If inventory items are not changed up to mFirstDropDownItem, no need to recreate them  	if (mFirstDropDownItem == first_drop_down_item && (mItemNamesCache.size() == count || mItemNamesCache.size() == mFirstDropDownItem))  	{ @@ -229,97 +231,113 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  		}  		if (i == mFirstDropDownItem)  		{ -			// Chevron button should stay right aligned -			LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); -			if (chevron_button) +			recreate_buttons = false; +		} +	} + +	if (recreate_buttons) +	{ +		mFirstDropDownItem = first_drop_down_item; + +		mItemNamesCache.clear(); +		for (S32 i = 0; i < mFirstDropDownItem; i++) +		{ +			mItemNamesCache.put(items.get(i)->getName()); +		} + +		// Rebuild the buttons only +		// child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator +		for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ) +		{ +			child_list_const_iter_t cur_it = child_it++; +			LLView* viewp = *cur_it; +			LLButton* button = dynamic_cast<LLButton*>(viewp); +			if (button)  			{ -				LLRect rect; -				rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); -				chevron_button->setRect(rect); -				mChevronRect = rect; +				removeChild(button); +				delete button;  			} -			return;  		} -	} -	mFirstDropDownItem = first_drop_down_item; +		// Adding buttons +		for(S32 i = mFirstDropDownItem -1; i >= 0; i--) +		{ -	mItemNamesCache.clear(); -	for (S32 i = 0; i < mFirstDropDownItem; i++) -	{ -		mItemNamesCache.put(items.get(i)->getName()); -	} +			LLInventoryItem* item = items.get(i); -        // Rebuild the buttons only -        // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator -        for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ) -        { -                child_list_const_iter_t cur_it = child_it++; -                LLView* viewp = *cur_it; -                LLButton* button = dynamic_cast<LLButton*>(viewp); -                if (button) -                { -                        removeChild(button); -                        delete button; -                } -        } - -	// Adding buttons -	for(S32 i = 0; i < mFirstDropDownItem; i++) -	{ -	 -		LLInventoryItem* item = items.get(i); - -		S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2; - -		LLRect rect; -		rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap); - -		LLButton::Params bparams; -		bparams.image_unselected.name(flat_icon); -		bparams.image_disabled.name(flat_icon); -		bparams.image_selected.name(hover_icon_selected); -		bparams.image_hover_selected.name(hover_icon_selected); -		bparams.image_disabled_selected.name(hover_icon_selected); -		bparams.image_hover_unselected.name(hover_icon); -		bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); -		bparams.rect (rect); -		bparams.tab_stop(false); -		bparams.font(mFont); -		bparams.name(item->getName()); -		bparams.tool_tip(item->getName()); -		bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); -		bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); - -		addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); - -		curr_x += buttonWidth + buttonHGap; +			S32 buttonWidth = mFont->getWidth(item->getName()) + buttonHPad * 2; + +			LLRect rect; +			rect.setOriginAndSize(curr_x, buttonVGap, buttonWidth, getRect().getHeight()-buttonVGap); + +			LLButton::Params bparams; +			bparams.image_unselected.name(flat_icon); +			bparams.image_disabled.name(flat_icon); +			bparams.image_selected.name(hover_icon_selected); +			bparams.image_hover_selected.name(hover_icon_selected); +			bparams.image_disabled_selected.name(hover_icon_selected); +			bparams.image_hover_unselected.name(hover_icon); +			bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); +			bparams.rect (rect); +			bparams.tab_stop(false); +			bparams.font(mFont); +			bparams.name(item->getName()); +			bparams.tool_tip(item->getName()); +			bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); +			bparams.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID())); + +			addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); + +			curr_x += buttonWidth + buttonHGap; +		}  	}  	// Chevron button  	if (mFirstDropDownItem != count)  	{ -		LLButton::Params bparams; - -		LLRect rect; -		rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); - -		bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); -		bparams.image_unselected.name(flat_icon); -		bparams.image_disabled.name(flat_icon); -		bparams.image_selected.name(hover_icon_selected); -		bparams.image_hover_selected.name(hover_icon_selected); -		bparams.image_disabled_selected.name(hover_icon_selected); -		bparams.image_hover_unselected.name(hover_icon); -		bparams.rect (rect); -		bparams.tab_stop(false); -		bparams.font(mFont); -		bparams.name(">>"); -		bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); - -		addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); - -		mChevronRect = rect; +		// Chevron button should stay right aligned +		LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); +		if (chevron_button) +		{ +			LLRect rect; +			rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); +			chevron_button->setRect(rect); +			chevron_button->setVisible(TRUE); +			mChevronRect = rect; +		} +		else +		{ +			LLButton::Params bparams; + +			LLRect rect; +			rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap); + +			bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM); +			bparams.image_unselected.name(flat_icon); +			bparams.image_disabled.name(flat_icon); +			bparams.image_selected.name(hover_icon_selected); +			bparams.image_hover_selected.name(hover_icon_selected); +			bparams.image_disabled_selected.name(hover_icon_selected); +			bparams.image_hover_unselected.name(hover_icon); +			bparams.rect (rect); +			bparams.tab_stop(false); +			bparams.font(mFont); +			bparams.name(">>"); +			bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + +			addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); + +			mChevronRect = rect; +		} +	} +	else +	{ +		// Hide chevron button if all items are visible on bar +		LLView *chevron_button = getChildView(std::string(">>"), FALSE, FALSE); +		if (chevron_button) +		{ +			chevron_button->setVisible(FALSE); +		}  	}  } @@ -444,6 +462,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  			item_params.label(item_name);  			item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); +			item_params.rightclick_callback.function(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID()));  			LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index aba2402b0c..6cae4b8abc 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -276,7 +276,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,  		std::string text = obj->getName();  		if (!(next_owner_mask & PERM_COPY))  		{ -			text.append(getString("no_copy")); +			text.append(LLTrans::getString("no_copy"));  		}  		if (!(next_owner_mask & PERM_MODIFY))  		{ diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 8ec9eac196..eb2c6768f3 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -56,7 +56,7 @@  #include "llviewermessage.h"  #include "llvoavatarself.h"  #include "llviewerstats.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h"  LLGestureManager gGestureManager; @@ -871,7 +871,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)  			const BOOL animate = FALSE; -			LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); +			LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);  			gesture->mCurrentStep++;  			break; diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 85da2eb2e3..278fd5b9f6 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -42,6 +42,12 @@  static LLDefaultChildRegistry::Register<LLGroupList> r("group_list"); +LLGroupList::Params::Params() +{ +	// Prevent the active group from being always first in the list. +	online_go_first = false; +} +  LLGroupList::LLGroupList(const Params& p)  :	LLAvatarList(p)  { diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index a246650822..e893313f4b 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -44,6 +44,7 @@ class LLGroupList: public LLAvatarList  public:  	struct Params : public LLInitParam::Block<Params, LLAvatarList::Params>  	{ +		Params();  	};  	LLGroupList(const Params&); diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp new file mode 100644 index 0000000000..b51064f226 --- /dev/null +++ b/indra/newview/lllandmarkactions.cpp @@ -0,0 +1,141 @@ +/**  +* @file lllandmarkactions.cpp +* @brief LLLandmarkActions class implementation +* +* $LicenseInfo:firstyear=2001&license=viewergpl$ +*  +* Copyright (c) 2001-2009, Linden Research, Inc. +*  +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab.  Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +*  +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +*  +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +*  +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "lllandmarkactions.h" + +#include "llagent.h" +#include "llinventory.h" +#include "llinventorymodel.h" +#include "lllandmark.h" +#include "lllandmarklist.h" +#include "llnotifications.h" +#include "llparcel.h" +#include "llviewerinventory.h" +#include "llviewerparcelmgr.h" +#include "roles_constants.h" + +// Returns true if the given inventory item is a landmark pointing to the current parcel. +// Used to filter inventory items. +class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor +{ +public: +	/*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) +	{ +		if (!item || item->getType() != LLAssetType::AT_LANDMARK) +			return false; + +		LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); +		if (!landmark) // the landmark not been loaded yet +			return false; + +		LLVector3d landmark_global_pos; +		if (!landmark->getGlobalPos(landmark_global_pos)) +			return false; + +		return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos); +	} +}; + +bool LLLandmarkActions::landmarkAlreadyExists() +{ +	// Determine whether there are landmarks pointing to the current parcel. +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items; +	LLIsAgentParcelLandmark is_current_parcel_landmark; +	gInventory.collectDescendentsIf(gInventory.getRootFolderID(), +		cats, +		items, +		LLInventoryModel::EXCLUDE_TRASH, +		is_current_parcel_landmark); + +	return !items.empty(); +} + +bool LLLandmarkActions::canCreateLandmarkHere() +{ +	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +	if(!agent_parcel) +	{ +		llwarns << "No agent region" << llendl; +		return false; +	} +	if (agent_parcel->getAllowLandmark() +		|| LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) +	{ +		return true; +	} + +	return false; +} + +void LLLandmarkActions::createLandmarkHere( +	const std::string& name,  +	const std::string& desc,  +	const LLUUID& folder_id) +{ +	if(!gAgent.getRegion()) +	{ +		llwarns << "No agent region" << llendl; +		return; +	} +	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +	if (!agent_parcel) +	{ +		llwarns << "No agent parcel" << llendl; +		return; +	} +	if (!canCreateLandmarkHere()) +	{ +		LLNotifications::instance().add("CannotCreateLandmarkNotOwner"); +		return; +	} + +	create_inventory_item(gAgent.getID(), gAgent.getSessionID(), +		folder_id, LLTransactionID::tnull, +		name, desc, +		LLAssetType::AT_LANDMARK, +		LLInventoryType::IT_LANDMARK, +		NOT_WEARABLE, PERM_ALL,  +		NULL); +} + +void LLLandmarkActions::createLandmarkHere() +{ +	std::string landmark_name, landmark_desc; + +	gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK); +	gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL); +	LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + +	createLandmarkHere(landmark_name, landmark_desc, folder_id); +} diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h new file mode 100644 index 0000000000..e1e94edb75 --- /dev/null +++ b/indra/newview/lllandmarkactions.h @@ -0,0 +1,68 @@ +/**  +* @file lllandmarkactions.h +* @brief LLLandmark class declaration +* +* $LicenseInfo:firstyear=2000&license=viewergpl$ +*  +* Copyright (c) 2000-2009, Linden Research, Inc. +*  +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab.  Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +*  +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at +* http://secondlifegrid.net/programs/open_source/licensing/flossexception +*  +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +*  +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#ifndef LL_LLLANDMARKACTIONS_H +#define LL_LLLANDMARKACTIONS_H + +/** +* @brief Provides helper functions to manage landmarks +*/ +class LLLandmarkActions +{ +public: + +	/** +	* @brief Checks whether landmark exists for current parcel. +	*/ +	static bool landmarkAlreadyExists(); + +	/** +	* @brief Checks whether agent has rights to create landmark for current parcel. +	*/ +	static bool canCreateLandmarkHere(); + +	/** +	* @brief Creates landmark for current parcel. +	*/ +	static void createLandmarkHere(); + +	/** +	* @brief Creates landmark for current parcel. +	*/ +	static void createLandmarkHere( +		const std::string& name,  +		const std::string& desc,  +		const LLUUID& folder_id); + +}; + +#endif //LL_LLLANDMARKACTIONS_H diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp index ed56e3e195..471a0868bc 100644 --- a/indra/newview/lllocationhistory.cpp +++ b/indra/newview/lllocationhistory.cpp @@ -39,8 +39,7 @@  #include "llui.h"  LLLocationHistory::LLLocationHistory() : -	mFilename("typed_locations.txt"), -	mLoadedCallback(NULL) +	mFilename("typed_locations.txt")  {  } @@ -134,6 +133,5 @@ void LLLocationHistory::load()  	file.close(); -	if (mLoadedCallback) -		mLoadedCallback(); +	mLoadedSignal();  } diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index b6552c12ca..19032686c1 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -46,6 +46,7 @@ class LLLocationHistory: public LLSingleton<LLLocationHistory>  public:  	typedef std::vector<std::string>	location_list_t;  	typedef boost::function<void()>		loaded_callback_t; +	typedef boost::signals2::signal<void()> loaded_signal_t;  	LLLocationHistory(); @@ -54,7 +55,7 @@ public:  	size_t					getItemCount() const	{ return mItems.size(); }  	const location_list_t&	getItems() const		{ return mItems; }  	bool					getMatchingItems(std::string substring, location_list_t& result) const; -	void					setLoadedCallback(loaded_callback_t cb) { mLoadedCallback = cb; } +	boost::signals2::connection	setLoadedCallback(loaded_callback_t cb) { return mLoadedSignal.connect(cb); }  	void					save() const;  	void					load(); @@ -63,7 +64,7 @@ public:  private:  	std::vector<std::string>	mItems;  	std::string					mFilename; /// File to store the history to. -	loaded_callback_t			mLoadedCallback; +	loaded_signal_t				mLoadedSignal;  };  #endif diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 99f6823ba1..94abd128c4 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -48,6 +48,7 @@  #include "llagent.h"  #include "llfloaterland.h"  #include "llinventorymodel.h" +#include "lllandmarkactions.h"  #include "lllandmarklist.h"  #include "lllocationhistory.h"  #include "llsidetray.h" @@ -83,28 +84,6 @@   * and choose the appropriate image for the "Add landmark" button.   */ -// Returns true if the given inventory item is a landmark pointing to the current parcel. -// Used to filter inventory items. -class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor -{ -public: -	/*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) -	{ -		if (!item || item->getType() != LLAssetType::AT_LANDMARK) -			return false; - -		LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); -		if (!landmark) // the landmark not been loaded yet -			return false; - -		LLVector3d landmark_global_pos; -		if (!landmark->getGlobalPos(landmark_global_pos)) -			return false; - -		return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos); -	} -}; -  /**   * Initiates loading the landmarks that have been just added.   * @@ -213,10 +192,10 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)  	// - Make the "Add landmark" button updated when either current parcel gets changed  	//   or a landmark gets created or removed from the inventory.  	// - Update the location string on parcel change. -	LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( +	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback(  		boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this)); -	LLLocationHistory::getInstance()->setLoadedCallback( +	mLocationHistoryConnection = LLLocationHistory::getInstance()->setLoadedCallback(  			boost::bind(&LLLocationInputCtrl::onLocationHistoryLoaded, this));  	mRemoveLandmarkObserver	= new LLRemoveLandmarkObserver(this); @@ -231,6 +210,9 @@ LLLocationInputCtrl::~LLLocationInputCtrl()  	gInventory.removeObserver(mAddLandmarkObserver);  	delete mRemoveLandmarkObserver;  	delete mAddLandmarkObserver; + +	mParcelMgrConnection.disconnect(); +	mLocationHistoryConnection.disconnect();  }  void LLLocationInputCtrl::setEnabled(BOOL enabled) @@ -356,6 +338,10 @@ void LLLocationInputCtrl::onInfoButtonClicked()  void LLLocationInputCtrl::onAddLandmarkButtonClicked()  { +	LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); +	 +	// Floater "Add Landmark" functionality moved to Side Tray +	// TODO* Disable floater "Add Landmark" call  	LLFloaterReg::showInstance("add_landmark");  } @@ -450,19 +436,7 @@ void LLLocationInputCtrl::enableAddLandmarkButton(bool val)  // depending on whether current parcel has been landmarked.  void LLLocationInputCtrl::updateAddLandmarkButton()  { -	bool cur_parcel_landmarked = false; -	// Determine whether there are landmarks pointing to the current parcel. -	LLInventoryModel::cat_array_t cats; -	LLInventoryModel::item_array_t items; -	LLIsAgentParcelLandmark is_current_parcel_landmark; -	gInventory.collectDescendentsIf(gInventory.getRootFolderID(), -		cats, -		items, -		LLInventoryModel::EXCLUDE_TRASH, -		is_current_parcel_landmark); -	cur_parcel_landmarked = !items.empty(); - -	enableAddLandmarkButton(!cur_parcel_landmarked); +	enableAddLandmarkButton(!LLLandmarkActions::landmarkAlreadyExists());  }  void LLLocationInputCtrl::updateWidgetlayout() diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 0a863f6dd8..2cc63a33b7 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -112,6 +112,9 @@ private:  	LLAddLandmarkObserver*		mAddLandmarkObserver;  	LLRemoveLandmarkObserver*	mRemoveLandmarkObserver; + +	boost::signals2::connection	mParcelMgrConnection; +	boost::signals2::connection	mLocationHistoryConnection;  };  #endif diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index cfcb331912..efa15e05da 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -67,7 +67,7 @@  #include "llworld.h"  #include "llworldmap.h"  #include "llfocusmgr.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h"  void handle_pay_by_id(const LLUUID& agent_id)  { @@ -85,13 +85,13 @@ void handle_chat(void*)  {  	// give focus to chatbar if it's open but not focused  	if (gSavedSettings.getBOOL("ChatVisible") &&  -		gFocusMgr.childHasKeyboardFocus(LLBottomTray::getInstance()->getChatBox())) +		gFocusMgr.childHasKeyboardFocus(LLNearbyChatBar::getInstance()->getChatBox()))  	{ -		LLBottomTray::stopChat(); +		LLNearbyChatBar::stopChat();  	}  	else  	{ -		LLBottomTray::startChat(NULL); +		LLNearbyChatBar::startChat(NULL);  	}  } @@ -107,5 +107,5 @@ void handle_slash_key(void*)  	// menu accelerators that put input focus into a field.   And Mac works  	// the same way.  JC -	LLBottomTray::startChat(NULL); +	LLNearbyChatBar::startChat(NULL);  } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index c0bddd101e..58ec2d24a8 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -42,6 +42,7 @@  #include "llagent.h"  #include "llfloaterhtmlhelp.h" +#include "lllandmarkactions.h"  #include "lllocationhistory.h"  #include "lllocationinputctrl.h"  #include "llteleporthistory.h" @@ -175,7 +176,6 @@ LLNavigationBar::LLNavigationBar()  	mBtnBack(NULL),  	mBtnForward(NULL),  	mBtnHome(NULL), -	mBtnHelp(NULL),  	mCmbLocation(NULL),  	mLeSearch(NULL),  	mPurgeTPHistoryItems(false) @@ -202,12 +202,11 @@ BOOL LLNavigationBar::postBuild()  	mBtnBack	= getChild<LLButton>("back_btn");  	mBtnForward	= getChild<LLButton>("forward_btn");  	mBtnHome	= getChild<LLButton>("home_btn"); -	mBtnHelp	= getChild<LLButton>("help_btn");  	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");   	mLeSearch	= getChild<LLSearchEditor>("search_input"); -	if (!mBtnBack || !mBtnForward || !mBtnHome || !mBtnHelp || +	if (!mBtnBack || !mBtnForward || !mBtnHome ||  		!mCmbLocation || !mLeSearch)  	{  		llwarns << "Malformed navigation bar" << llendl; @@ -223,7 +222,6 @@ BOOL LLNavigationBar::postBuild()  	mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2));  	mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); -	mBtnHelp->setClickedCallback(boost::bind(&LLNavigationBar::onHelpButtonClicked, this));  	mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this)); @@ -297,11 +295,6 @@ void LLNavigationBar::onHomeButtonClicked()  	gAgent.teleportHome();  } -void LLNavigationBar::onHelpButtonClicked() -{ -	gViewerHtmlHelp.show(); -} -  void LLNavigationBar::onSearchCommit()  {  	invokeSearch(mLeSearch->getValue().asString()); @@ -523,6 +516,10 @@ bool LLNavigationBar::onLocationContextMenuItemEnabled(const LLSD& userdata)  	{  		return location_entry->canSelectAll();  	} +	else if(item == std::string("can_landmark")) +	{ +		return !LLLandmarkActions::landmarkAlreadyExists(); +	}  	return false;  } diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index a82dfc73ff..a46c59306d 100644 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -80,7 +80,6 @@ private:  	void onHelpButtonClicked();  	void onLocationSelection();  	void onLocationPrearrange(const LLSD& data); -	void onLocationHistoryLoaded();  	void onSearchCommit();  	void onRegionNameResponse(  			std::string typed_location, @@ -96,7 +95,6 @@ private:  	LLButton*				mBtnBack;  	LLButton*				mBtnForward;  	LLButton*				mBtnHome; -	LLButton*				mBtnHelp;  	LLSearchEditor*			mLeSearch;  	LLLocationInputCtrl*	mCmbLocation;  	bool					mPurgeTPHistoryItems; diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 411aa72690..847262ddfd 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -36,7 +36,7 @@  #include "llviewercontrol.h"  #include "llviewerwindow.h"  #include "llrootview.h" -#include "llchatitemscontainerctrl.h" +//#include "llchatitemscontainerctrl.h"  #include "lliconctrl.h"  #include "llsidetray.h"  #include "llfocusmgr.h" @@ -45,6 +45,9 @@  #include "llmenugl.h"  #include "llviewermenu.h"//for gMenuHolder +#include "llnearbychathandler.h" +#include "llchannelmanager.h" +  static const S32 RESIZE_BAR_THICKNESS = 3;  LLNearbyChat::LLNearbyChat(const LLSD& key) : @@ -66,6 +69,11 @@ BOOL LLNearbyChat::postBuild()  	mResizeBar[LLResizeBar::LEFT]->setVisible(false);  	mResizeBar[LLResizeBar::RIGHT]->setVisible(false); +	mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500); +	mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500); +	mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600); +	mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600); +  	mResizeHandle[0]->setVisible(false);  	mResizeHandle[1]->setVisible(false);  	mResizeHandle[2]->setVisible(false); @@ -86,24 +94,160 @@ BOOL LLNearbyChat::postBuild()  	gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); +	/*  	LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);  	if(panel)  	{  		panel->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));  	} +	*/  	reshape(getRect().getWidth(), getRect().getHeight(), FALSE);  	return LLFloater::postBuild();  } -void	LLNearbyChat::addMessage(const LLChat& message) +#include "llagent.h" 			// gAgent +#include "llfloaterscriptdebug.h" +#include "llviewertexteditor.h" +#include "llstylemap.h" + +LLColor4 nearbychat_get_text_color(const LLChat& chat) +{ +	LLColor4 text_color; + +	if(chat.mMuted) +	{ +		text_color.setVec(0.8f, 0.8f, 0.8f, 1.f); +	} +	else +	{ +		switch(chat.mSourceType) +		{ +		case CHAT_SOURCE_SYSTEM: +			text_color = LLUIColorTable::instance().getColor("SystemChatColor");  +			break; +		case CHAT_SOURCE_AGENT: +		    if (chat.mFromID.isNull()) +			{ +				text_color = LLUIColorTable::instance().getColor("SystemChatColor"); +			} +			else +			{ +				if(gAgentID == chat.mFromID) +				{ +					text_color = LLUIColorTable::instance().getColor("UserChatColor"); +				} +				else +				{ +					text_color = LLUIColorTable::instance().getColor("AgentChatColor"); +				} +			} +			break; +		case CHAT_SOURCE_OBJECT: +			if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) +			{ +				text_color = LLUIColorTable::instance().getColor("ScriptErrorColor"); +			} +			else if ( chat.mChatType == CHAT_TYPE_OWNER ) +			{ +				text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor"); +			} +			else +			{ +				text_color = LLUIColorTable::instance().getColor("ObjectChatColor"); +			} +			break; +		default: +			text_color.setToWhite(); +		} + +		if (!chat.mPosAgent.isExactlyZero()) +		{ +			LLVector3 pos_agent = gAgent.getPositionAgent(); +			F32 distance = dist_vec(pos_agent, chat.mPosAgent); +			if (distance > gAgent.getNearChatRadius()) +			{ +				// diminish far-off chat +				text_color.mV[VALPHA] = 0.8f; +			} +		} +	} + +	return text_color; +} + +void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color) +{ +	std::string line = chat.mFromName; +	line +=": "; +	line +=chat.mText; + +	bool prepend_newline = true; +	if (gSavedSettings.getBOOL("ChatShowTimestamps")) +	{ +		edit->appendTime(prepend_newline); +		prepend_newline = false; +	} + +	// If the msg is from an agent (not yourself though), +	// extract out the sender name and replace it with the hotlinked name. +	if (chat.mSourceType == CHAT_SOURCE_AGENT && +		chat.mFromID != LLUUID::null) +	{ +		chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str()); +	} + +	// If the chat line has an associated url, link it up to the name. +	if (!chat.mURL.empty() +		&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0)) +	{ +		std::string start_line = line.substr(0, chat.mFromName.length() + 1); +		line = line.substr(chat.mFromName.length() + 1); +		const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL); +		edit->appendStyledText(start_line, false, prepend_newline, sourceStyle); +		prepend_newline = false; +	} +	edit->appendColoredText(line, false, prepend_newline, color); +} + + + +void	LLNearbyChat::addMessage(const LLChat& chat)  { +	/*  	LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);  	if(!panel)  		return;  	panel->addMessage(message); +	*/ + +	//"Chat History Editor" !!!!! + +	LLColor4 color = nearbychat_get_text_color(chat); + +	if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) +	{ +		LLFloaterScriptDebug::addScriptLine(chat.mText, +											chat.mFromName,  +											color,  +											chat.mFromID); +		if (!gSavedSettings.getBOOL("ScriptErrorsAsChat")) +		{ +			return; +		} +	} +	 +	// could flash the chat button in the status bar here. JC + +	LLViewerTextEditor*	history_editor = getChild<LLViewerTextEditor>("Chat History Editor"); + +	history_editor->setParseHTML(TRUE); +	history_editor->setParseHighlights(TRUE); +	 +	if (!chat.mMuted) +		nearbychat_add_timestamped_line(history_editor, chat, color);  }  void LLNearbyChat::onNearbySpeakers() @@ -166,7 +310,9 @@ void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent)  		caption->setRect(caption_rect);  	} -	LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false); +	//LLPanel* scroll_panel = getChild<LLPanel>("chat_history",false,false); +	LLViewerTextEditor*	scroll_panel = getChild<LLViewerTextEditor>("Chat History Editor"); +	  	if (scroll_panel)  	{  		LLRect scroll_rect = scroll_panel->getRect(); @@ -305,10 +451,13 @@ void	LLNearbyChat::float_panel()  	mResizeBar[LLResizeBar::BOTTOM]->setVisible(true);  	mResizeBar[LLResizeBar::LEFT]->setVisible(true);  	mResizeBar[LLResizeBar::RIGHT]->setVisible(true); + +	translate(4,4);  }  void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)  { +	/*  	LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);  	if(!panel)  		return; @@ -322,15 +471,18 @@ void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)  		panel->setHeaderVisibility(CHATITEMHEADER_SHOW_BOTH);  	gSavedSettings.setS32("nearbychat_showicons_and_names", (S32)panel->getHeaderVisibility()); - - +	*/  }  bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)  { +	std::string str = userdata.asString(); +	if(str == "nearby_people") +		onNearbySpeakers();	 +	/*  	LLChatItemsContainerCtrl* panel = getChild<LLChatItemsContainerCtrl>("chat_history",false,false);  	if(!panel)  		return false; -	std::string str = userdata.asString(); +	  	if(str == "show_buddy_icons")  		return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_ONLY_ICON;  	else if(str == "show_names") @@ -339,6 +491,7 @@ bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)  		return panel->getHeaderVisibility() == CHATITEMHEADER_SHOW_BOTH;  	else if(str == "nearby_people")  		onNearbySpeakers(); +	*/  	return false;  } @@ -360,3 +513,11 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)  	return LLFloater::handleRightMouseDown(x, y, mask);  } +void	LLNearbyChat::onOpen(const LLSD& key ) +{ +	LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->getChannelByID(LLUUID(NEARBY_CHAT_ID)); +	if(chat_channel) +	{ +		chat_channel->removeToastsFromChannel(); +	} +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 61ff8890ea..74e3710f40 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -77,8 +77,10 @@ public:  	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);  	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata); -	virtual void	onClose(bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); } -	 +	virtual void	onClose		(bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); } + +	virtual void	onOpen		(const LLSD& key); +  private:  	void	pinn_panel(); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp new file mode 100644 index 0000000000..7b67ae645c --- /dev/null +++ b/indra/newview/llnearbychatbar.cpp @@ -0,0 +1,549 @@ +/**  + * @file llnearbychatbar.cpp + * @brief LLNearbyChatBar class implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + *  + * Copyright (c) 2002-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llnearbychatbar.h" +#include "llbottomtray.h" +#include "llagent.h" +#include "llgesturemgr.h" +#include "llmultigesture.h" +#include "llkeyboard.h" +#include "llanimationstates.h" +#include "llviewerstats.h" +#include "llcommandhandler.h" +#include "llviewercontrol.h" + +S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; + +// legacy calllback glue +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + +static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); + +LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p) +	: LLComboBox(p) +	, mGestureLabelTimer() +	, mLabel(p.label) +{ +	setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1)); + +	// now register us as observer since we have a place to put the results +	gGestureManager.addObserver(this); + +	// refresh list from current active gestures +	refreshGestures(); +} + +LLGestureComboBox::~LLGestureComboBox() +{ +	gGestureManager.removeObserver(this); +} + +void LLGestureComboBox::refreshGestures() +{ +	//store current selection so we can maintain it +	std::string cur_gesture = getValue().asString(); +	selectFirstItem(); +	// clear +	clearRows(); + +	// collect list of unique gestures +	std::map <std::string, BOOL> unique; +	LLGestureManager::item_map_t::iterator it; +	for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) +	{ +		LLMultiGesture* gesture = (*it).second; +		if (gesture) +		{ +			if (!gesture->mTrigger.empty()) +			{ +				unique[gesture->mTrigger] = TRUE; +			} +		} +	} + +	// add unique gestures +	std::map <std::string, BOOL>::iterator it2; +	for (it2 = unique.begin(); it2 != unique.end(); ++it2) +	{ +		addSimpleElement((*it2).first); +	} + +	sortByName(); +	// Insert label after sorting, at top, with separator below it +	addSeparator(ADD_TOP);		 +	addSimpleElement(mLabel, ADD_TOP); + +	if (!cur_gesture.empty()) +	{  +		selectByValue(LLSD(cur_gesture)); +	} +	else +	{ +		selectFirstItem(); +	} +} + +void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) +{ +	LLCtrlListInterface* gestures = getListInterface(); +	if (gestures) +	{ +		S32 index = gestures->getFirstSelectedIndex(); +		if (index == 0) +		{ +			return; +		} +		const std::string& trigger = gestures->getSelectedValue().asString(); + +		// pretend the user chatted the trigger string, to invoke +		// substitution and logging. +		std::string text(trigger); +		std::string revised_text; +		gGestureManager.triggerAndReviseString(text, &revised_text); + +		revised_text = utf8str_trim(revised_text); +		if (!revised_text.empty()) +		{ +			// Don't play nodding animation +			LLNearbyChatBar::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); +		} +	} + +	mGestureLabelTimer.start(); +	// free focus back to chat bar +	setFocus(FALSE); +} + +//virtual +void LLGestureComboBox::draw() +{ +	// HACK: Leave the name of the gesture in place for a few seconds. +	const F32 SHOW_GESTURE_NAME_TIME = 2.f; +	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) +	{ +		LLCtrlListInterface* gestures = getListInterface(); +		if (gestures) gestures->selectFirstItem(); +		mGestureLabelTimer.stop(); +	} + +	LLComboBox::draw(); +} + +LLNearbyChatBar::LLNearbyChatBar()  +	: LLPanel() +	, mChatBox(NULL) +{ +} + +//virtual +BOOL LLNearbyChatBar::postBuild() +{ +	mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE); + +	if (mChatBox) +	{ +		mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this)); +		mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); +		mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this); + +		mChatBox->setIgnoreArrowKeys(TRUE); +		mChatBox->setCommitOnFocusLost( FALSE ); +		mChatBox->setRevertOnEsc( FALSE ); +		mChatBox->setIgnoreTab(TRUE); +		mChatBox->setPassDelete(TRUE); +		mChatBox->setReplaceNewlinesWithSpaces(FALSE); +		mChatBox->setMaxTextLength(1023); +		mChatBox->setEnableLineHistory(TRUE); +	} + +	mTalkBtn = getChild<LLTalkButton>("talk",TRUE,FALSE); + +	return TRUE; +} + +//static +LLNearbyChatBar* LLNearbyChatBar::getInstance() +{ +	return LLBottomTray::getInstance() ? LLBottomTray::getInstance()->getNearbyChatBar() : NULL; +} + +std::string LLNearbyChatBar::getCurrentChat() +{ +	return mChatBox ? mChatBox->getText() : LLStringUtil::null; +} + +// virtual +BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) +{ +	BOOL handled = FALSE; + +	// ALT-RETURN is reserved for windowed/fullscreen toggle +	if( KEY_RETURN == key && mask == MASK_CONTROL) +	{ +		// shout +		sendChat(CHAT_TYPE_SHOUT); +		handled = TRUE; +	} + +	return handled; +} + +void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata) +{ +	LLNearbyChatBar* self = (LLNearbyChatBar *)userdata; + +	LLWString raw_text; +	if (self->mChatBox) raw_text = self->mChatBox->getWText(); + +	// Can't trim the end, because that will cause autocompletion +	// to eat trailing spaces that might be part of a gesture. +	LLWStringUtil::trimHead(raw_text); + +	S32 length = raw_text.length(); + +	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences +	{ +		gAgent.startTyping(); +	} +	else +	{ +		gAgent.stopTyping(); +	} + +	/* Doesn't work -- can't tell the difference between a backspace +	   that killed the selection vs. backspace at the end of line. +	if (length > 1  +		&& text[0] == '/' +		&& key == KEY_BACKSPACE) +	{ +		// the selection will already be deleted, but we need to trim +		// off the character before +		std::string new_text = raw_text.substr(0, length-1); +		self->mInputEditor->setText( new_text ); +		self->mInputEditor->setCursorToEnd(); +		length = length - 1; +	} +	*/ + +	KEY key = gKeyboard->currentKey(); + +	// Ignore "special" keys, like backspace, arrows, etc. +	if (length > 1  +		&& raw_text[0] == '/' +		&& key < KEY_SPECIAL) +	{ +		// we're starting a gesture, attempt to autocomplete + +		std::string utf8_trigger = wstring_to_utf8str(raw_text); +		std::string utf8_out_str(utf8_trigger); + +		if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) +		{ +			if (self->mChatBox) +			{ +				std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); +				self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part +				S32 outlength = self->mChatBox->getLength(); // in characters +			 +				// Select to end of line, starting from the character +				// after the last one the user typed. +				self->mChatBox->setSelection(length, outlength); +			} +		} + +		//llinfos << "GESTUREDEBUG " << trigger  +		//	<< " len " << length +		//	<< " outlen " << out_str.getLength() +		//	<< llendl; +	} +} + +// static +void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata) +{ +	// stop typing animation +	gAgent.stopTyping(); +} + +void LLNearbyChatBar::sendChat( EChatType type ) +{ +	if (mChatBox) +	{ +		LLWString text = mChatBox->getConvertedText(); +		if (!text.empty()) +		{ +			// store sent line in history, duplicates will get filtered +			mChatBox->updateHistory(); +			// Check if this is destined for another channel +			S32 channel = 0; +			stripChannelNumber(text, &channel); +			 +			std::string utf8text = wstring_to_utf8str(text); +			// Try to trigger a gesture, if not chat to a script. +			std::string utf8_revised_text; +			if (0 == channel) +			{ +				// discard returned "found" boolean +				gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); +			} +			else +			{ +				utf8_revised_text = utf8text; +			} + +			utf8_revised_text = utf8str_trim(utf8_revised_text); + +			if (!utf8_revised_text.empty()) +			{ +				// Chat with animation +				sendChatFromViewer(utf8_revised_text, type, TRUE); +			} +		} + +		mChatBox->setText(LLStringExplicit("")); +	} + +	gAgent.stopTyping(); + +	// If the user wants to stop chatting on hitting return, lose focus +	// and go out of chat mode. +	if (gSavedSettings.getBOOL("CloseChatOnReturn")) +	{ +		stopChat(); +	} +} + +void LLNearbyChatBar::onChatBoxCommit() +{ +	if (mChatBox && mChatBox->getText().length() > 0) +	{ +		sendChat(CHAT_TYPE_NORMAL); +	} + +	gAgent.stopTyping(); +} + +void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) +{ +	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); +} + +void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) +{ +	// Look for "/20 foo" channel chats. +	S32 channel = 0; +	LLWString out_text = stripChannelNumber(wtext, &channel); +	std::string utf8_out_text = wstring_to_utf8str(out_text); +	std::string utf8_text = wstring_to_utf8str(wtext); + +	utf8_text = utf8str_trim(utf8_text); +	if (!utf8_text.empty()) +	{ +		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); +	} + +	// Don't animate for chats people can't hear (chat to scripts) +	if (animate && (channel == 0)) +	{ +		if (type == CHAT_TYPE_WHISPER) +		{ +			lldebugs << "You whisper " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); +		} +		else if (type == CHAT_TYPE_NORMAL) +		{ +			lldebugs << "You say " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); +		} +		else if (type == CHAT_TYPE_SHOUT) +		{ +			lldebugs << "You shout " << utf8_text << llendl; +			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); +		} +		else +		{ +			llinfos << "send_chat_from_viewer() - invalid volume" << llendl; +			return; +		} +	} +	else +	{ +		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) +		{ +			lldebugs << "Channel chat: " << utf8_text << llendl; +		} +	} + +	send_chat_from_viewer(utf8_out_text, type, channel); +} + +// static  +void LLNearbyChatBar::startChat(const char* line) +{ +	LLBottomTray *bt = LLBottomTray::getInstance(); + +	if (!bt) +		return; + +	LLNearbyChatBar* cb = bt->getNearbyChatBar(); + +	if (!cb || !cb->mChatBox) +		return; + +	bt->setVisible(TRUE); +	cb->mChatBox->setFocus(TRUE); + +	if (line) +	{ +		std::string line_string(line); +		cb->mChatBox->setText(line_string); +	} + +	cb->mChatBox->setCursorToEnd(); +} + +// Exit "chat mode" and do the appropriate focus changes +// static +void LLNearbyChatBar::stopChat() +{ +	LLBottomTray *bt = LLBottomTray::getInstance(); + +	if (!bt) +		return; + +	LLNearbyChatBar* cb = bt->getNearbyChatBar(); + +	if (!cb || !cb->mChatBox) +		return; + +	cb->mChatBox->setFocus(FALSE); + + 	// stop typing animation + 	gAgent.stopTyping(); +} + +// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. +// Otherwise returns input and channel 0. +LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) +{ +	if (mesg[0] == '/' +		&& mesg[1] == '/') +	{ +		// This is a "repeat channel send" +		*channel = sLastSpecialChatChannel; +		return mesg.substr(2, mesg.length() - 2); +	} +	else if (mesg[0] == '/' +			 && mesg[1] +			 && LLStringOps::isDigit(mesg[1])) +	{ +		// This a special "/20" speak on a channel +		S32 pos = 0; + +		// Copy the channel number into a string +		LLWString channel_string; +		llwchar c; +		do +		{ +			c = mesg[pos+1]; +			channel_string.push_back(c); +			pos++; +		} +		while(c && pos < 64 && LLStringOps::isDigit(c)); +		 +		// Move the pointer forward to the first non-whitespace char +		// Check isspace before looping, so we can handle "/33foo" +		// as well as "/33 foo" +		while(c && iswspace(c)) +		{ +			c = mesg[pos+1]; +			pos++; +		} +		 +		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); +		*channel = sLastSpecialChatChannel; +		return mesg.substr(pos, mesg.length() - pos); +	} +	else +	{ +		// This is normal chat. +		*channel = 0; +		return mesg; +	} +} + +void LLNearbyChatBar::setPTTState(bool state) +{ +	mTalkBtn->setSpeakBtnToggleState(state); +} + +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) +{ +	LLMessageSystem* msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_ChatFromViewer); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast(_PREHASH_ChatData); +	msg->addStringFast(_PREHASH_Message, utf8_out_text); +	msg->addU8Fast(_PREHASH_Type, type); +	msg->addS32("Channel", channel); + +	gAgent.sendReliableMessage(); + +	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +} + +class LLChatHandler : public LLCommandHandler +{ +public: +	// not allowed from outside the app +	LLChatHandler() : LLCommandHandler("chat", true) { } + +    // Your code here +	bool handle(const LLSD& tokens, const LLSD& query_map, +				LLWebBrowserCtrl* web) +	{ +		if (tokens.size() < 2) return false; +		S32 channel = tokens[0].asInteger(); +		std::string mesg = tokens[1].asString(); +		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); +		return true; +	} +}; + +// Creating the object registers with the dispatcher. +LLChatHandler gChatHandler; + + diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h new file mode 100644 index 0000000000..d1f5fbff6b --- /dev/null +++ b/indra/newview/llnearbychatbar.h @@ -0,0 +1,104 @@ +/**  + * @file llnearbychatbar.h + * @brief LLNearbyChatBar class definition + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + *  + * Copyright (c) 2002-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLNEARBYCHATBAR_H +#define LL_LLNEARBYCHATBAR_H + +#include "llpanel.h" +#include "llcombobox.h" +#include "llgesturemgr.h" +#include "llchat.h" +#include "llchiclet.h" + +class LLGestureComboBox +	: public LLComboBox +	, public LLGestureManagerObserver +{ +protected: +	LLGestureComboBox(const LLComboBox::Params&); +	friend class LLUICtrlFactory; +public: +	~LLGestureComboBox(); + +	void refreshGestures(); +	void onCommitGesture(LLUICtrl* ctrl); +	virtual void draw(); + +	// LLGestureManagerObserver trigger +	virtual void changed() { refreshGestures(); } + +protected: +	LLFrameTimer mGestureLabelTimer; +	std::string mLabel; +}; + +class LLNearbyChatBar +:	public LLPanel +{ +public: +	// constructor for inline chat-bars (e.g. hosted in chat history window) +	LLNearbyChatBar(); +	~LLNearbyChatBar() {} + +	virtual BOOL postBuild(); + +	static LLNearbyChatBar* getInstance(); + +	LLLineEditor* getChatBox() { return mChatBox; } + +	std::string getCurrentChat(); +	virtual BOOL handleKeyHere( KEY key, MASK mask ); + +	void setPTTState(bool state); +	static void startChat(const char* line); +	static void stopChat(); + +	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); +	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); + +protected: +	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata); +	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); + +	void sendChat( EChatType type ); +	void onChatBoxCommit(); + +	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); + +	// Which non-zero channel did we last chat on? +	static S32 sLastSpecialChatChannel; + +	LLLineEditor*		mChatBox; +	LLTalkButton*		mTalkBtn; +}; + +#endif diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index ab66421d35..cb1b65a604 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -61,6 +61,7 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i  	// Getting a Channel for our notifications  	mChannel = LLChannelManager::getInstance()->createChannel(p);  	mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP);  +	mChannel->setOverflowFormatString("You have %d unread nearby chat messages");  	mChannel->setStoreToasts(false);  }  LLNearbyChatHandler::~LLNearbyChatHandler() @@ -71,6 +72,9 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)  	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull())           LLRecentPeople::instance().add(chat_msg.mFromID); +	if(chat_msg.mText.empty()) +		return;//don't process empty messages +  	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());  	nearby_chat->addMessage(chat_msg);  	if(nearby_chat->getVisible()) @@ -82,7 +86,9 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)  	LLChatItemCtrl* item = LLChatItemCtrl::createInstance();  	item->setMessage(chat_msg); -	item->setWidth(nearby_chat->getRect().getWidth() - 16); +	//static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16; +	static S32 chat_item_width = 304; +	item->setWidth(chat_item_width);  	item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));  	item->setVisible(true); @@ -91,7 +97,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)  	LLToast* toast = mChannel->addToast(id, item);  	toast->setOnMouseEnterCallback(boost::bind(&LLNearbyChatHandler::onToastDestroy, this, toast)); -	toast->setAndStartTimer(10); //TODO: set correct time +	toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime"));  }  void LLNearbyChatHandler::onToastDestroy(LLToast* toast) diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index 757a0e5999..06826998bf 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -49,7 +49,7 @@ LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsMo  	LLBottomTray* tray = LLBottomTray::getInstance();  	LLChannelManager::Params p; -	p.id = LLUUID("F3E07BC8-A973-476D-8C7F-F3B7293975D1"); +	p.id = LLUUID(ALERT_CHANNEL_ID);  	p.channel_right_bound = tray->getRect().getWidth() / 2;  	p.channel_width = 0;  	p.align = NA_CENTRE; diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index cde7efe901..ad09f43c10 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -50,7 +50,7 @@ LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)  	mChiclet = tray->getSysWell();  	LLChannelManager::Params p;  	p.chiclet = mChiclet; -	p.channel_right_bound = tray->getRect().mRight - 10; //HACK: need to correctly resolve SysWell's position +	p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");  	p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");  	// Getting a Channel for our notifications @@ -74,7 +74,7 @@ void LLGroupHandler::processNotification(const LLSD& notify)  			toast = mChannel->addToast(notification->getID(), notify_box);  			if(!toast)  				return;			 -			toast->setAndStartTimer(5);  +			toast->setAndStartTimer(gSavedSettings.getS32("NotificationToastTime"));   			toast->setOnToastDestroyCallback((boost::bind(&LLGroupHandler::onToastDestroy, this, toast)));  			mChiclet->setCounter(mChiclet->getCounter() + 1);  	} diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index 7f53809c07..9037fc82ab 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -42,6 +42,8 @@  namespace LLNotificationsUI  { +// ID for channel that displays Alert Notifications +#define ALERT_CHANNEL_ID	"F3E07BC8-A973-476D-8C7F-F3B7293975D1"  // ENotificationType enumerates all possible types of notifications that could be met  //  diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h index f0cf480458..ffdbd96f60 100644 --- a/indra/newview/lloverlaybar.h +++ b/indra/newview/lloverlaybar.h @@ -85,7 +85,6 @@ public:  protected:	  	static void* createMediaRemote(void* userdata);  	static void* createVoiceRemote(void* userdata); -	static void* createChatBar(void* userdata);  	void enableMediaButtons(); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index bf6ecd6bf4..f57489934a 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -340,12 +340,17 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty  		if(avatar_groups)  		{  			std::string groups; -			LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); -			for(; avatar_groups->group_list.end() != it; ++it) -			{ +			if (!avatar_groups->group_list.empty()) { +				LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();  				LLAvatarGroups::LLGroupData group_data = *it; -				groups += group_data.group_name; -				groups += ", "; +				groups+= group_data.group_name; +				while (++it != avatar_groups->group_list.end()) +				{ +					group_data = *it;				 +					groups += ", "; +					groups += group_data.group_name; +					 +				}  			}  			childSetValue("sl_groups",groups);  		} diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 0cbf10f7c2..7bf7ceb6d2 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -200,6 +200,9 @@ void LLLandmarksPanel::onCopySLURL()  // virtual  void LLLandmarksPanel::updateVerbs()  { +	if (!isTabVisible())  +		return; +  	BOOL enabled = FALSE;  	LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem(); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index d947003109..92a8653252 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -436,11 +436,13 @@ bool LLPanelPeople::updateGroupList()  bool LLPanelPeople::filterFriendList()  { -	if (mFriendVec.size() > 0) -		return mFriendList->update(mFriendVec, mFilterSubString); +	// We must always update Friends list to clear the latest removed friend. +	bool have_names = mFriendList->update(mFriendVec, mFilterSubString); -	mFriendList->setCommentText(getString("no_friends")); -	return true; +	if (mFriendVec.size() == 0) +		mFriendList->setCommentText(getString("no_friends")); + +	return have_names;  }  bool LLPanelPeople::filterNearbyList() @@ -784,10 +786,22 @@ void LLPanelPeople::onMoreButtonClicked()  void	LLPanelPeople::onOpen(const LLSD& key)  { -	std::string tab_name = key.asString(); +	// Profile View is activated through LLSideTray::showPanel(),  +	// hide Profile View to be able to see Panel People content +	hideProfileView(); +	std::string tab_name = key.asString();  	if (!tab_name.empty())  		mTabContainer->selectTabByName(tab_name);  	else  		reSelectedCurrentTab();  } + +void LLPanelPeople::hideProfileView() +{ +	LLView* view = getChildView("panel_profile_view",true,false); +	if(view && view->getVisible()) +	{ +		view->setVisible(false); +	} +} diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 6c3b5e0664..2ac1bf424c 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -104,6 +104,8 @@ private:  								const std::vector<LLUUID>& ids,  								void*); +	void					hideProfileView(); +  	LLFilterEditor*			mFilterEditor;  	LLTabContainer*			mTabContainer;  	LLAvatarList*			mFriendList; diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 7bfe94043f..e8d6ff9ec9 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -45,6 +45,7 @@  #include "llpanelavatar.h"  #include "llpanelprofile.h"  #include "llpanelpick.h" +#include "llscrollcontainer.h"  static const std::string XML_BTN_NEW = "new_btn";  static const std::string XML_BTN_DELETE = "trash_btn"; @@ -203,7 +204,7 @@ void LLPanelPicks::reshapePicksList()  			last_bottom -= childp->getRect().getHeight();  			last_bottom -= PICK_ITEMS_BETWEEN;  		} -		reshapePickItem(childp, last_bottom); +		reshapePickItem(childp, last_bottom,pickList->getRect().getWidth());  	}  	S32 height = pickList->getChildCount() * ((*child_first_it)->getRect().getHeight() + PICK_ITEMS_BETWEEN); @@ -213,13 +214,13 @@ void LLPanelPicks::reshapePicksList()  	pickList->setRect(rc);  } -void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom) +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->reshape(rc.getWidth(), rc.getHeight());  	pick_item->setRect(rc); +	pick_item->reshape(newWidth, rc.getHeight());  }  LLView* LLPanelPicks::getPicksList() const @@ -402,7 +403,7 @@ void LLPanelPicks::setSelectedPickItem(LLPickItem* item)  BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y )  { -	LLView* scroll = getChild<LLView>("profile_scroll"); +	LLScrollContainer* scroll = getChild<LLScrollContainer>("profile_scroll");  	if (!scroll->parentPointInView(x, y)) return FALSE;  	S32 x_l = x; diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 3bc79daeb3..e0e7f69532 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -102,7 +102,7 @@ private:  	bool callbackTeleport(const LLSD& notification, const LLSD& response);  	void reshapePicksList(); -	void reshapePickItem(LLView* const pick_item, const S32 last_bottom); +	void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth);  	LLView* getPicksList() const;  	void updateButtons(); diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 590eae555e..ea05b666db 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -39,6 +39,7 @@  #include "llsecondlifeurls.h"  #include "llinventory.h" +#include "llparcel.h"  #include "llqueryflags.h" @@ -52,6 +53,7 @@  #include "llinventorymodel.h"  #include "lltexturectrl.h"  #include "llviewerinventory.h" +#include "llviewerparcelmgr.h"  #include "llviewerregion.h"  #include "llviewertexteditor.h"  #include "llworldmap.h" @@ -221,6 +223,8 @@ void LLPanelPlaceInfo::resetLocation()  	mCreated->setText(not_available);  	mTitleEditor->setText(LLStringUtil::null);  	mNotesEditor->setText(LLStringUtil::null); +	mSnapshotCtrl->setImageAssetID(LLUUID::null); +	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");  }  //virtual @@ -237,6 +241,12 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	switch(type)  	{ +		case CREATE_LANDMARK: +			mCurrentTitle = getString("title_create_landmark"); + +			toggleMediaPanel(FALSE); +		break; +  		case PLACE:  			mCurrentTitle = getString("title_place"); @@ -362,21 +372,33 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)  		region_z = llround(parcel_data.global_z);  	} +	std::string name;  	if (!parcel_data.sim_name.empty())  	{ -		std::string name = llformat("%s (%d, %d, %d)", -									parcel_data.sim_name.c_str(), region_x, region_y, region_z); +		name = llformat("%s (%d, %d, %d)", +						parcel_data.sim_name.c_str(), region_x, region_y, region_z);  		mRegionName->setText(name);  	} +	 +	if (mCurrentTitle != getString("title_landmark")) +	{ +		mTitleEditor->setText(parcel_data.name + "; " + name); +		mNotesEditor->setText(LLStringUtil::null); +	}  }  void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,  									 const LLUUID& region_id,  									 const LLVector3d& pos_global)  { -	LLSD body;  	mPosRegion = pos_region; -	std::string url = gAgent.getRegion()->getCapability("RemoteParcelRequest"); + +	LLViewerRegion* region = gAgent.getRegion(); +	if (!region) +		return; + +	LLSD body; +	std::string url = region->getCapability("RemoteParcelRequest");  	if (!url.empty())  	{  		body["location"] = ll_sd_from_vector3(pos_region); @@ -395,8 +417,29 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,  	{  		mDescEditor->setText(getString("server_update_text"));  	} -	mSnapshotCtrl->setImageAssetID(LLUUID::null); -	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); +} + +void LLPanelPlaceInfo::displayAgentParcelInfo() +{ +	mPosRegion = gAgent.getPositionAgent(); + +	LLViewerRegion* region = gAgent.getRegion(); +	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +	if (!region || !parcel) +		return; + +	LLParcelData parcel_data; +	parcel_data.desc = parcel->getDesc(); +	parcel_data.flags = parcel->getParcelFlags(); +	parcel_data.name = parcel->getName(); +	parcel_data.sim_name = gAgent.getRegion()->getName(); +	parcel_data.snapshot_id = parcel->getSnapshotID(); +	LLVector3d global_pos = gAgent.getPositionGlobal(); +	parcel_data.global_x = global_pos.mdV[0]; +	parcel_data.global_y = global_pos.mdV[1]; +	parcel_data.global_z = global_pos.mdV[2]; + +	processParcelInfo(parcel_data);  }  void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 7f98b6cb76..f06a2d1fb7 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -55,6 +55,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver  public:  	enum INFO_TYPE  	{ +		CREATE_LANDMARK,  		PLACE,  		LANDMARK,  		TELEPORT_HISTORY @@ -84,9 +85,17 @@ public:  	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);  	void sendParcelInfoRequest(); + +	// Displays information about a remote parcel. +	// Sends a request to the server.  	void displayParcelInfo(const LLVector3& pos_region,  						   const LLUUID& region_id,  						   const LLVector3d& pos_global); + +	// Displays information about the parcel the agent is currently on +	// without sending a request to the server. +	void displayAgentParcelInfo(); +  	void nameUpdatedCallback(LLTextBox* text,  							 const std::string& first,  							 const std::string& last); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 57c633dd74..b443cc4d5e 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -31,13 +31,16 @@  #include "llviewerprecompiledheaders.h" +#include "llassettype.h" + +#include "lllandmark.h" +  #include "llfloaterreg.h" +#include "llnotifications.h"  #include "llfiltereditor.h"  #include "lltabcontainer.h"  #include "lluictrlfactory.h" -#include "lllandmark.h" -  #include "llagent.h"  #include "lllandmarklist.h"  #include "llfloaterworldmap.h" @@ -48,18 +51,8 @@  #include "llviewerparcelmgr.h"  #include "llviewerregion.h" -LLPanelPlaces::LLParcelUpdateTimer::LLParcelUpdateTimer(F32 period) -:	LLEventTimer(period) -{ -}; - -// virtual -BOOL LLPanelPlaces::LLParcelUpdateTimer::tick() -{ -	LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent")); -	 -	return TRUE; -} +// Helper function to get local position from global +const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global);  static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places"); @@ -68,7 +61,9 @@ LLPanelPlaces::LLPanelPlaces()  		mFilterSubString(LLStringUtil::null),  		mActivePanel(NULL),  		mFilterEditor(NULL), -		mPlaceInfo(NULL) +		mPlaceInfo(NULL), +		mItem(NULL), +		mPosGlobal()  {  	gInventory.addObserver(this); @@ -86,6 +81,17 @@ LLPanelPlaces::~LLPanelPlaces()  BOOL LLPanelPlaces::postBuild()  { +	mTeleportBtn = getChild<LLButton>("teleport_btn"); +	mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this)); +	 +	mShowOnMapBtn = getChild<LLButton>("map_btn"); +	mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this)); +	 +	//mShareBtn = getChild<LLButton>("share_btn"); +	//mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this)); + +	mOverflowBtn = getChild<LLButton>("overflow_btn"); +  	mTabContainer = getChild<LLTabContainer>("Places Tabs");  	if (mTabContainer)  	{ @@ -108,13 +114,9 @@ BOOL LLPanelPlaces::postBuild()  		}  		// *TODO: Assign the action to an appropriate event. -		childSetAction("overflow_btn", boost::bind(&LLPanelPlaces::toggleMediaPanel, this), this); +		mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));  	} -	//childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this); -	childSetAction("teleport_btn", boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this), this); -	childSetAction("map_btn", boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this), this); -  	return TRUE;  } @@ -124,19 +126,23 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		return;  	mPlaceInfoType = key["type"].asString(); -	 +	mPosGlobal.setZero();  	togglePlaceInfoPanel(TRUE); +	updateVerbs();  	if (mPlaceInfoType == "agent")  	{ -		// We don't need to teleport to the current location so disable the button -		getChild<LLButton>("teleport_btn")->setEnabled(FALSE); -		getChild<LLButton>("map_btn")->setEnabled(TRUE); -  		mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); -		mPlaceInfo->displayParcelInfo(gAgent.getPositionAgent(), -									  gAgent.getRegion()->getRegionID(), -									  gAgent.getPositionGlobal()); +		mPlaceInfo->displayAgentParcelInfo(); +		 +		mPosGlobal = gAgent.getPositionGlobal(); +	} +	else if (mPlaceInfoType == "create_landmark") +	{ +		mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); +		mPlaceInfo->displayAgentParcelInfo(); +		 +		mPosGlobal = gAgent.getPositionGlobal();  	}  	else if (mPlaceInfoType == "landmark")  	{ @@ -144,27 +150,19 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		LLInventoryItem* item = gInventory.getItem(item_uuid);  		if (!item)  			return; +		 +		setItem(item); +	} +	else if (mPlaceInfoType == "remote_place") +	{ +		mPosGlobal = LLVector3d(key["x"].asReal(), +								key["y"].asReal(), +								key["z"].asReal()); -		mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); -		mPlaceInfo->displayItemInfo(item); - -		LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID()); -		if (!landmark) -			return; - -		// Select Landmarks tab and set selection to requested landmark so that -		// context dependent Verbs buttons update properly. -		mTabContainer->selectFirstTab(); // Assume that first tab is Landmarks tab. -		LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getCurrentPanel()); -		landmarks_panel->setSelectedItem(item_uuid); - -		LLUUID region_id; -		landmark->getRegionID(region_id); -		LLVector3d pos_global; -		landmark->getGlobalPos(pos_global); -		mPlaceInfo->displayParcelInfo(landmark->getRegionPos(), -									  region_id, -									  pos_global); +		mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); +		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal), +									  LLUUID(), +									  mPosGlobal);  	}  	else if (mPlaceInfoType == "teleport_history")  	{ @@ -175,18 +173,47 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		LLVector3d pos_global = hist_items[index].mGlobalPos; -		F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); -		F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); - -		LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); -  		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY); -		mPlaceInfo->displayParcelInfo(pos_local, +		mPlaceInfo->displayParcelInfo(get_pos_local_from_global(pos_global),  									  hist_items[index].mRegionID,  									  pos_global);  	}  } +void LLPanelPlaces::setItem(LLInventoryItem* item) +{ +	mItem = item; +	 +	// If the item is a link get a linked item +	if (mItem->getType() == LLAssetType::AT_LINK) +	{ +		mItem = gInventory.getItem(mItem->getAssetUUID()); +		if (mItem.isNull()) +			return; +	} + +	mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK); +	mPlaceInfo->displayItemInfo(mItem); + +	LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(), +											boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1)); +	if (lm) +	{ +		onLandmarkLoaded(lm); +	} +} + +void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) +{ +	LLUUID region_id; +	landmark->getRegionID(region_id); +	LLVector3d pos_global; +	landmark->getGlobalPos(pos_global); +	mPlaceInfo->displayParcelInfo(landmark->getRegionPos(), +								  region_id, +								  pos_global); +} +  void LLPanelPlaces::onFilterEdit(const std::string& search_string)  {  	if (mFilterSubString != search_string) @@ -212,12 +239,12 @@ void LLPanelPlaces::onTabSelected()  	mActivePanel->updateVerbs();  } +/*  void LLPanelPlaces::onShareButtonClicked()  {  	// TODO: Launch the "Things" Share wizard  } -/*  void LLPanelPlaces::onAddLandmarkButtonClicked()  {  	LLFloaterReg::showInstance("add_landmark"); @@ -231,24 +258,64 @@ void LLPanelPlaces::onCopySLURLButtonClicked()  void LLPanelPlaces::onTeleportButtonClicked()  { -	mActivePanel->onTeleport(); +	if (mPlaceInfo->getVisible()) +	{ +		if (mPlaceInfoType == "landmark") +		{ +			LLSD payload; +			payload["asset_id"] = mItem->getAssetUUID(); +			LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload); +		} +		else if (mPlaceInfoType == "remote_place") +		{ +			LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); +			if (!mPosGlobal.isExactlyZero() && worldmap_instance) +			{ +				gAgent.teleportViaLocation(mPosGlobal); +				worldmap_instance->trackLocation(mPosGlobal); +			} +		} +	} +	else +	{ +		mActivePanel->onTeleport(); +	}  }  void LLPanelPlaces::onShowOnMapButtonClicked()  { -	if (mPlaceInfoType == "agent") +	if (mPlaceInfo->getVisible())  	{ -		LLVector3d global_pos = gAgent.getPositionGlobal(); -		if (!global_pos.isExactlyZero()) -			{ -				LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); -				if(instance) -				{ -					instance->trackLocation(global_pos); -					LLFloaterReg::showInstance("world_map", "center"); +		LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); +		if(!worldmap_instance) +			return; -				} +		if (mPlaceInfoType == "agent" || +			mPlaceInfoType == "create_landmark" || +			mPlaceInfoType == "remote_place") +		{ +			if (!mPosGlobal.isExactlyZero()) +			{ +				worldmap_instance->trackLocation(mPosGlobal); +				LLFloaterReg::showInstance("world_map", "center");  			} +		} +		else if (mPlaceInfoType == "landmark") +		{ +			LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID()); +			if (!landmark) +				return; + +			LLVector3d landmark_global_pos; +			if (!landmark->getGlobalPos(landmark_global_pos)) +				return; +			 +			if (!landmark_global_pos.isExactlyZero()) +			{ +				worldmap_instance->trackLocation(landmark_global_pos); +				LLFloaterReg::showInstance("world_map", "center"); +			} +		}  	}  	else  	{ @@ -259,6 +326,11 @@ void LLPanelPlaces::onShowOnMapButtonClicked()  void LLPanelPlaces::onBackButtonClicked()  {  	togglePlaceInfoPanel(FALSE); + +	// Resetting mPlaceInfoType when Place Info panel is closed. +	mPlaceInfoType = LLStringUtil::null; +	 +	updateVerbs();  }  void LLPanelPlaces::toggleMediaPanel() @@ -268,6 +340,7 @@ void LLPanelPlaces::toggleMediaPanel()  	mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible());  } +  void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  {  	if (!mPlaceInfo) @@ -276,9 +349,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  	mPlaceInfo->setVisible(visible);  	mFilterEditor->setVisible(!visible);  	mTabContainer->setVisible(!visible); -	 -	// Enable overflow button only for the information about agent's current location. -	getChild<LLButton>("overflow_btn")->setEnabled(visible && mPlaceInfoType == "agent");  	if (visible)  	{ @@ -331,10 +401,48 @@ void LLPanelPlaces::changed(U32 mask)  void LLPanelPlaces::onAgentParcelChange()  { -	if (mPlaceInfo->getVisible() && mPlaceInfoType == "agent") +	if (mPlaceInfo->getVisible() && (mPlaceInfoType == "agent" || mPlaceInfoType == "create_landmark")) +	{ +		LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", mPlaceInfoType)); +	} +	else +	{ +		updateVerbs(); +	} +} + +void LLPanelPlaces::updateVerbs() +{ +	bool is_place_info_visible = mPlaceInfo->getVisible(); +	bool is_agent_place_info_visible = mPlaceInfoType == "agent"; +	if (is_place_info_visible) +	{ +		if (is_agent_place_info_visible || mPlaceInfoType == "create_landmark") +		{ +			// We don't need to teleport to the current location so disable the button +			mTeleportBtn->setEnabled(FALSE); +		} +		else if (mPlaceInfoType == "landmark" || mPlaceInfoType == "remote_place") +		{ +			mTeleportBtn->setEnabled(TRUE); +		} + +		mShowOnMapBtn->setEnabled(TRUE); +	} +	else  	{ -		// Using timer to delay obtaining agent's coordinates -		// not to get the coordinates of previous parcel. -		new LLParcelUpdateTimer(.5); +		mActivePanel->updateVerbs();  	} + +	// Enable overflow button only when showing the information about agent's current location. +	mOverflowBtn->setEnabled(is_place_info_visible && is_agent_place_info_visible);  } + +const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global) +{ +	F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS ); +	F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS ); + +	LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); +	return pos_local; +}	 diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index e2ba4f39cd..c100ace8cc 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -41,6 +41,8 @@  #include "llinventorymodel.h"  #include "llpanelplaceinfo.h" +class LLInventoryItem; +class LLLandmark;  class LLPanelPlacesTab;  class LLFilterEditor;  class LLTabContainer; @@ -55,38 +57,49 @@ public:  	/*virtual*/ void changed(U32 mask);  	/*virtual*/ void onOpen(const LLSD& key); +	void setItem(LLInventoryItem* item); + +private: +	void onLandmarkLoaded(LLLandmark* landmark);  	void onFilterEdit(const std::string& search_string);  	void onTabSelected(); +  	//void onAddLandmarkButtonClicked();  	//void onCopySLURLButtonClicked(); -	void onShareButtonClicked(); +	//void onShareButtonClicked();  	void onTeleportButtonClicked();  	void onShowOnMapButtonClicked();  	void onBackButtonClicked(); +  	void toggleMediaPanel();  	void togglePlaceInfoPanel(BOOL visible); +  	void onAgentParcelChange(); +	void updateVerbs(); -private: -	LLFilterEditor*			mFilterEditor; -	LLPanelPlacesTab*		mActivePanel; -	LLTabContainer*			mTabContainer; -	LLPanelPlaceInfo*		mPlaceInfo; -	std::string				mFilterSubString; - -	// Place information type currently shown in Information panel -	std::string				mPlaceInfoType; - -	// Helper class to delay the coordinates update  -	// when agent changes parcel -	class LLParcelUpdateTimer : public LLEventTimer -	{ -	public: -		LLParcelUpdateTimer(F32 period); -		virtual ~LLParcelUpdateTimer() {}; - -		virtual BOOL tick(); -	}; +	LLFilterEditor*				mFilterEditor; +	LLPanelPlacesTab*			mActivePanel; +	LLTabContainer*				mTabContainer; +	LLPanelPlaceInfo*			mPlaceInfo; + +	//LLButton*					mShareBtn; +	LLButton*					mTeleportBtn; +	LLButton*					mShowOnMapBtn; +	LLButton*					mOverflowBtn; + +	// Pointer to a landmark item or to a linked landmark +	LLPointer<LLInventoryItem>	mItem; +	 +	// Absolute position of the location for teleport, may not +	// be available (hence zero) +	LLVector3d					mPosGlobal; + +	// Search string for filtering landmarks and teleport +	// history locations +	std::string					mFilterSubString; + +	// Information type currently shown in Place Information panel +	std::string					mPlaceInfoType;  };  #endif //LL_LLPANELPLACES_H diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp index e5b1f04064..7c0a7b0cc4 100644 --- a/indra/newview/llpanelplacestab.cpp +++ b/indra/newview/llpanelplacestab.cpp @@ -41,6 +41,14 @@  #include "llslurl.h"  #include "llworldmap.h" +bool LLPanelPlacesTab::isTabVisible() +{ +	LLUICtrl* parent = getParentUICtrl(); +	if (!parent) return false; +	if (!parent->getVisible()) return false; +	return true; +} +  void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)  {  	//mShareBtn = panel->getChild<LLButton>("share_btn"); diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h index c098302d1a..1c70869414 100644 --- a/indra/newview/llpanelplacestab.h +++ b/indra/newview/llpanelplacestab.h @@ -49,6 +49,8 @@ public:  	virtual void onTeleport() = 0;  	//virtual void onCopySLURL() = 0; +	bool isTabVisible(); // Check if parent TabContainer is visible. +  	void setPanelPlacesButtons(LLPanelPlaces* panel);  	void onRegionResponse(const LLVector3d& landmark_global_pos,  										U64 region_handle, diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 77edae261b..51cd05376a 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -143,6 +143,9 @@ void LLTeleportHistoryPanel::onCopySLURL()  // virtual  void LLTeleportHistoryPanel::updateVerbs()  { +	if (!isTabVisible())  +		return; +  	S32 index = 0;  	S32 cur_item = 0; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 78091ef05b..5dca12e06b 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -37,31 +37,36 @@  #include "lltextbox.h"  #include "llscreenchannel.h" +#include "llviewercontrol.h" +  #include <algorithm>  using namespace LLNotificationsUI; -#define	TOAST_MARGIN		5 -#define	BOTTOMPANEL_MARGIN	35 -#define	NAVBAR_MARGIN		60 - +bool LLScreenChannel::mWasStartUpToastShown = false;  //--------------------------------------------------------------------------  LLScreenChannel::LLScreenChannel(): mUnreadToastsPanel(NULL),   									mToastAlignment(NA_BOTTOM),   									mStoreToasts(true), +									mHiddenToastsNum(0),  									mOverflowToastHidden(false),  									mIsHovering(false),  									mControlHovering(false)  {	  	setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP);   + +	//TODO: load as a resource string +	mOverflowFormatString = "You have %d more notification"; + +	setMouseOpaque( false );  } -void LLScreenChannel::init(S32 channel_position, LLView* root_view) +void LLScreenChannel::init(S32 channel_left, S32 channel_right)  { -	root_view->addChild(this); -	setRect( LLRect(channel_position, root_view->getRect().getHeight() - NAVBAR_MARGIN, -					channel_position, root_view->getRect().mBottom + BOTTOMPANEL_MARGIN)); +	S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin"); +	S32 channel_bottom = getRootView()->getRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin"); +	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));  } @@ -79,7 +84,7 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)  }  //-------------------------------------------------------------------------- -LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel) +LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel, bool is_not_tip)  {	  	ToastElem new_toast_elem(id, panel); @@ -92,7 +97,29 @@ LLToast* LLScreenChannel::addToast(LLUUID id, LLPanel* panel)  	{  		new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));  	} -	showToasts(); + +	// don't show toasts until StartUp toast will fade, but show alerts +	if(!mWasStartUpToastShown && mToastAlignment != NA_CENTRE) +	{ +		new_toast_elem.toast->stopTimer(); +		// Count and store only non tip notifications +		if(is_not_tip) +		{ +			mHiddenToastsNum++;			 +			storeToast(new_toast_elem); +		} +		else +		{ +			// destroy tip toasts at once +			new_toast_elem.toast->close();			 +		} +		// remove toast from channel +		mToastList.pop_back(); +	} +	else +	{ +		showToasts(); +	}  	return new_toast_elem.toast;  } @@ -213,10 +240,20 @@ void LLScreenChannel::showToastsBottom()  		}  		toast_rect = (*it).toast->getRect(); -		toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight()); +		toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());  		(*it).toast->setRect(toast_rect); -		if((*it).toast->getRect().mTop > getRect().getHeight()) +		bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().getHeight(); + +		if(!stop_showing_toasts) +		{ +			if( it != mToastList.rend()-1) +			{ +				stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().getHeight(); +			} +		}  + +		if(stop_showing_toasts)  			break;  		(*it).toast->setVisible(TRUE);	 @@ -243,7 +280,7 @@ void LLScreenChannel::showToastsCentre()  	for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)  	{  		toast_rect = (*it).toast->getRect(); -		toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight()); +		toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());  		(*it).toast->setRect(toast_rect);  		(*it).toast->setVisible(TRUE);	 @@ -256,7 +293,7 @@ void LLScreenChannel::showToastsTop()  }  //-------------------------------------------------------------------------- -void LLScreenChannel::createOverflowToast(S32 bottom) +void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)  {  	LLRect toast_rect;  	mUnreadToastsPanel = new LLToast(NULL); @@ -266,21 +303,29 @@ void LLScreenChannel::createOverflowToast(S32 bottom)  	mUnreadToastsPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this)); -	LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("text"); +	LLTextBox* text_box = mUnreadToastsPanel->getChild<LLTextBox>("toast_text");  	LLIconCtrl* icon = mUnreadToastsPanel->getChild<LLIconCtrl>("icon"); +	std::string	text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum); +	if(mHiddenToastsNum == 1) +	{ +		text += "."; +	} +	else +	{ +		text += "s."; +	} -	std::string toastsNumStr = llformat("%d", mHiddenToastsNum); -	std::string	text = "You have " + toastsNumStr + " new notifications."; +	toast_rect = mUnreadToastsPanel->getRect(); +	mUnreadToastsPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); +	toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());	 +	mUnreadToastsPanel->setRect(toast_rect); +	mUnreadToastsPanel->setAndStartTimer(timer ? timer : gSavedSettings.getS32("NotificationToastTime")); +	getRootView()->addChild(mUnreadToastsPanel); -	text_box->setText(text); +	text_box->setValue(text);  	text_box->setVisible(TRUE);  	icon->setVisible(TRUE); -	toast_rect = mUnreadToastsPanel->getRect(); -	toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+TOAST_MARGIN, toast_rect.getWidth() ,toast_rect.getHeight()); -	mUnreadToastsPanel->setRect(toast_rect); -	mUnreadToastsPanel->setAndStartTimer(5); -	getRootView()->addChild(mUnreadToastsPanel);  	mUnreadToastsPanel->setVisible(TRUE);  } @@ -288,6 +333,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom)  void LLScreenChannel::onOverflowToastHide()  {  	mOverflowToastHidden = true; +	onCommit();  }  //-------------------------------------------------------------------------- diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 5a9946f772..f05c205e2a 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -54,14 +54,15 @@ typedef enum e_notification_toast_alignment   */  class LLScreenChannel : public LLUICtrl  { +	friend class LLChannelManager;  public:  	LLScreenChannel();  	virtual ~LLScreenChannel();  	void		reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); -	LLToast*	addToast(LLUUID id, LLPanel* panel); -	void		init(S32 channel_position, LLView* root_view); +	LLToast*	addToast(LLUUID id, LLPanel* panel, bool is_not_tip = true); +	void		init(S32 channel_left, S32 channel_right);  	void		killToastByNotificationID(LLUUID id);  	void		modifyToastByNotificationID(LLUUID id, LLPanel* panel); @@ -79,8 +80,15 @@ public:  	void		showToasts(); +	S32			getNumberOfHiddenToasts() { return mHiddenToastsNum;} +	void		setNumberOfHiddenToasts(S32 num) { mHiddenToastsNum = num;} + +	static void	setStartUpToastShown() { mWasStartUpToastShown = true; } +  	e_notification_toast_alignment getToastAlignment() {return mToastAlignment;} +	void		setOverflowFormatString ( std::string str)  { mOverflowFormatString = str; } +  private:  	struct ToastElem  	{ @@ -117,9 +125,10 @@ private:  	void	showToastsCentre();  	void	showToastsTop(); -	void	createOverflowToast(S32 bottom); +	void	createOverflowToast(S32 bottom, F32 timer = 0);  	void	onOverflowToastHide(); +	static bool	mWasStartUpToastShown;  	bool		mControlHovering;  	bool		mIsHovering;  	bool		mStoreToasts; @@ -130,6 +139,8 @@ private:  	std::vector<ToastElem>	mStoredToastList;  	e_notification_toast_alignment	mToastAlignment;  	std::map<LLToast*, bool>	mToastEventStack; + +	std::string mOverflowFormatString;  };  } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index abcff7cfb1..2688399139 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -63,24 +63,11 @@ LLSideTray* LLSideTray::sInstance = 0;  class LLSideTrayInfoPanel: public LLPanel  { -protected: -	LLSideTrayInfoPanel(){} +	  public: -	static LLSideTrayInfoPanel* createInstance(const string& image, const string& name,const string& description) -	{ -		LLSideTrayInfoPanel* panel = new LLSideTrayInfoPanel(); -		LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_sidetray_tab_info.xml"); -		if(panel) -			panel->setData(image, name,description); -		panel->setBorderVisible(true); -		return panel; - -	} -	void setData(const string& image, const string& name,const string& description) +	LLSideTrayInfoPanel():LLPanel()  	{ -		getChild<LLTextBox>("tab_name",false,false)->setValue(name); -		getChild<LLTextBox>("tab_description",false,false)->setValue(description); -		getChild<LLIconCtrl>("tab_icon",false,false)->setValue(image); +		setBorderVisible(true);  	}  	BOOL handleHover(S32 x, S32 y, MASK mask) @@ -91,12 +78,19 @@ public:  	BOOL handleMouseUp(S32 x, S32 y, MASK mask)  	{ +		std::string name = getName();  		onCommit(); +		LLSideTray::getInstance()->selectTabByName(name);  		return LLPanel::handleMouseUp(x,y,mask);  	} +	void reshape		(S32 width, S32 height, BOOL called_from_parent ) +	{ +		return LLPanel::reshape(width, height, called_from_parent); +	}  }; +static LLRegisterPanelClassWrapper<LLSideTrayInfoPanel> t_people("panel_sidetray_home_info");  LLSideTray* LLSideTray::getInstance()  { @@ -113,7 +107,7 @@ bool	LLSideTray::instanceCreated	()  	return sInstance!=0;  } -LLSideTrayTab::LLSideTrayTab(const Params& params):mAccordionCtrl(0) +LLSideTrayTab::LLSideTrayTab(const Params& params):mMainPanel(0)  {  	mImagePath = params.image_path; @@ -124,30 +118,12 @@ LLSideTrayTab::~LLSideTrayTab()  {  } -void LLSideTrayTab::addPanel(LLPanel* panel) -{ -	//addChild(panel,false); -} -  bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)  { -	if(mAccordionCtrl == 0)		 -	{ -		mAccordionCtrl = new LLAccordionCtrl(); -		mAccordionCtrl->setVisible(TRUE); -		LLPanel::addChild(mAccordionCtrl,tab_group); -	} - -	 -	bool res = true; -	if(TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel -	{ -		mAccordionCtrl->addCollapsibleCtrl(view); -	} -	else -		res = LLPanel::addChild(view,tab_group); - -	return res; +	if(mMainPanel == 0 && TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel +		mMainPanel = view; +	return LLPanel::addChild(view,tab_group); +	//return res;  } @@ -185,17 +161,18 @@ void	LLSideTrayTab::arrange(S32 width, S32 height )  		offset = title_panel->getRect().getHeight();  	} -	LLRect sRect = mAccordionCtrl->getRect(); +	LLRect sRect = mMainPanel->getRect();  	sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin); -	mAccordionCtrl->setRect(sRect); +	mMainPanel->reshape(sRect.getWidth(),sRect.getHeight()); +	mMainPanel->setRect(sRect); +	 + -	mAccordionCtrl->setMaxWidth(sRect.getWidth()); -	mAccordionCtrl->arrange();  }  void LLSideTrayTab::reshape		(S32 width, S32 height, BOOL called_from_parent )  { -	if(!mAccordionCtrl) +	if(!mMainPanel)  		return;  	S32 offset = 0; @@ -210,12 +187,12 @@ void LLSideTrayTab::reshape		(S32 width, S32 height, BOOL called_from_parent ) -	LLRect sRect = mAccordionCtrl->getRect(); +	LLRect sRect = mMainPanel->getRect();  	sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin); -	mAccordionCtrl->setMaxWidth(sRect.getWidth()); -	mAccordionCtrl->reshape(sRect.getWidth(), sRect.getHeight()); +	//mMainPanel->setMaxWidth(sRect.getWidth()); +	mMainPanel->reshape(sRect.getWidth(), sRect.getHeight()); -	mAccordionCtrl->setRect(sRect); +	mMainPanel->setRect(sRect);  } @@ -231,7 +208,9 @@ void LLSideTrayTab::draw()  void	LLSideTrayTab::onOpen		(const LLSD& key)  { -	mAccordionCtrl->onOpen(key); +	LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel); +	if(panel) +		panel->onOpen(key);  }  LLSideTrayTab*  LLSideTrayTab::createInstance	() @@ -251,7 +230,6 @@ LLSideTray::LLSideTray(Params& params)  		,mCollapsed(false)  		,mCollapseButton(0)  	    ,mMaxBarWidth(params.rect.width) -		,mHomeTab(0)  {  	mCollapsed=params.collapsed;  } @@ -261,10 +239,8 @@ BOOL LLSideTray::postBuild()  {  	createButtons(); -	createHomeTab(); -  	arrange(); -	selectTabByName("home_tab"); +	selectTabByName("sidebar_home");  	if(mCollapsed)  		collapseSideBar(); @@ -333,8 +309,6 @@ bool LLSideTray::selectTabByIndex(size_t index)  bool LLSideTray::selectTabByName	(const std::string& name)  {  	LLSideTrayTab* side_bar = getTab(name); -	if(side_bar == 0 && name == "home_tab") -		side_bar = mHomeTab;  	if(side_bar == NULL || side_bar == mActiveTab)  		return false; @@ -416,9 +390,10 @@ void	LLSideTray::createButtons	()  	mCollapseButton = createButton(EXPANDED_NAME,"",boost::bind(&LLSideTray::onToggleCollapse, this));  	//create buttons for tabs -	child_vector_const_iter_t child_it; +	child_vector_const_iter_t child_it = mTabs.begin(); +	++child_it; -	for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) +	for ( ; child_it != mTabs.end(); ++child_it)  	{  		LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);  		if(sidebar_tab == NULL) @@ -445,7 +420,7 @@ void		LLSideTray::onToggleCollapse()  	if(mCollapsed)  	{  		expandSideBar(); -		selectTabByName("home_tab"); +		selectTabByName("sidebar_home");  	}  	else  		collapseSideBar(); @@ -517,10 +492,6 @@ void LLSideTray::arrange			()  		sidebar_tab->setRect(ctrl_rect);  		sidebar_tab->arrange(mMaxBarWidth,getRect().getHeight());  	} - -	mHomeTab->setRect(ctrl_rect); -	mHomeTab->arrange(mMaxBarWidth,getRect().getHeight()); -	  }  void LLSideTray::collapseSideBar	() @@ -619,19 +590,16 @@ void LLSideTray::reshape			(S32 width, S32 height, BOOL called_from_parent)  		sidebar_tab->setRect(ctrl_rect);  	} -	 -	mHomeTab->reshape(mMaxBarWidth,getRect().getHeight()); -	ctrl_rect.setLeftTopAndSize(sidetray_params.default_button_width,getRect().getHeight(),mMaxBarWidth,getRect().getHeight()); -	mHomeTab->setRect(ctrl_rect); - -	  }  /**   * Activate tab with "panel_name" panel - * if no such tab - return false, otherwise true + * if no such tab - return false, otherwise true. + * TODO* In some cases a pointer to a panel of + * a specific class may be needed so this method + * would need to use templates.   */ -bool		LLSideTray::showPanel		(const std::string& panel_name, const LLSD& params) +LLPanel*	LLSideTray::showPanel		(const std::string& panel_name, const LLSD& params)  {  	//arrange tabs  	child_vector_const_iter_t child_it; @@ -644,51 +612,12 @@ bool		LLSideTray::showPanel		(const std::string& panel_name, const LLSD& params)  			LLPanel* panel = dynamic_cast<LLPanel*>(view);  			if(panel)  				panel->onOpen(params); -			return true; +			return panel;  		}  	} -	return false; +	return NULL;  } -void LLSideTray::createHomeTab() -{ -	mHomeTab = LLSideTrayTab::createInstance(); -	child_vector_iter_t child_it; -	for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it) -	{ -		LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it); -		if(sidebar_tab == NULL) -			continue; -		 -		LLPanel* panel = LLSideTrayInfoPanel::createInstance(sidebar_tab->mImagePath,sidebar_tab->getTabTitle(),sidebar_tab->getDescription()); - -		panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName())); - -		LLAccordionCtrlTab::Params panel_params;  -		panel_params.display_children(true); -		panel_params.collapsible(false); -		panel_params.header_visible(false); -		panel_params.can_resize(false); -		panel_params.min_height(200); -		panel_params.padding_left(10); -		panel_params.padding_right(10); -		panel_params.padding_top(5); -		panel_params.padding_bottom(5); -		panel_params.name(sidebar_tab->getTabTitle()); - -		LLAccordionCtrlTab* ctrl = LLUICtrlFactory::create<LLAccordionCtrlTab>(panel_params); - -		 -		ctrl->setPanel(panel); -		ctrl->postBuild(); -		mHomeTab->addChild(ctrl,0); -	} - -	mHomeTab->setBackgroundVisible(true); -	mHomeTab->postBuild(); - -	LLUICtrl::addChild(mHomeTab, 0); -}  static const S32	fake_offset = 132;  static const S32	fake_top_offset = 78; diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 7b1f4aee04..99e84f8141 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -65,7 +65,6 @@ protected:  public:  	virtual ~LLSideTrayTab(); -	void			addPanel	(LLPanel* panel);      /*virtual*/ BOOL	postBuild	();  	/*virtual*/ bool	addChild	(LLView* view, S32 tab_group); @@ -87,7 +86,7 @@ private:  	std::string mImagePath;  	std::string	mDescription; -	LLAccordionCtrl*	mAccordionCtrl; +	LLView*	mMainPanel;  }; @@ -163,9 +162,9 @@ public:  	/**  	 * Activate tab with "panel_name" panel -	 * if no such tab - return false, otherwise true +	 * if no such tab - return NULL, otherwise a pointer to the panel  	 */ -	bool		showPanel		(const std::string& panel_name, const LLSD& params); +    LLPanel*	showPanel		(const std::string& panel_name, const LLSD& params);  	/*       * collapse SideBar, hiding visible tab and moving tab buttons @@ -209,7 +208,6 @@ protected:  	void		createButtons	();  	LLButton*	createButton	(const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback); -	void		createHomeTab	();  	void		arrange			();  	void		reflectCollapseChange(); @@ -223,7 +221,6 @@ private:  	std::map<std::string,LLButton*>	mTabButtons;  	child_vector_t					mTabs; -	LLSideTrayTab*					mHomeTab;  	LLSideTrayTab*					mActiveTab;	  	LLButton*						mCollapseButton; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d0432e7961..3410a1eb68 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -871,8 +871,6 @@ bool idle_startup()  		gDirUtilp->setLindenUserDir(firstname, lastname);      	LLFile::mkdir(gDirUtilp->getLindenUserDir()); -		LLLocationHistory::getInstance()->load(); -          // Set PerAccountSettingsFile to the default value.  		gSavedSettings.setString("PerAccountSettingsFile",  			gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,  @@ -2517,6 +2515,8 @@ bool idle_startup()  		// reset timers now that we are running "logged in" logic  		LLFastTimer::reset(); +		LLLocationHistory::getInstance()->load(); +  		return TRUE;  	} diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 9144f9c3e0..6f5b25214e 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -104,6 +104,7 @@ bool LLToast::timerHasExpired()  	if (mTimer.getStarted())  	{  		F32 elapsed_time = mTimer.getElapsedTimeF32(); +		// after 4 seconds a toast should start fade  		if (elapsed_time > 4)   		{  			setBackgroundOpaque(FALSE); @@ -119,7 +120,7 @@ bool LLToast::timerHasExpired()  //--------------------------------------------------------------------------  void LLToast::hide()  { -	setVisible(FALSE);			//TODO: store in Chiclet's history +	setVisible(FALSE);  	mIsViewed = false;  	mTimer.stop();  	mOnFade(this, LLSD()); diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 2e2ac5b36c..018664f3d1 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -68,6 +68,7 @@ public:  	void setAndStartTimer(F32 period);  	//  	void resetTimer() { mTimer.start(); } +	void stopTimer() { mTimer.stop(); }  	void close() { die(); }  	virtual void draw();  	virtual void setVisible(BOOL show); diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 83c25ddc77..f5ed7f8710 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -51,6 +51,8 @@  #include "llglheaders.h"  #include "llagent.h"  #include "llavatariconctrl.h" +#include "llfloaterinventory.h" +#include "llinventorytype.h"  LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)  :	LLToastPanel(notification), @@ -64,6 +66,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  		llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;  	} +	static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor"); +  	//group icon  	LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);  	pGroupIcon->setValue(groupData.mInsigniaID); @@ -76,11 +80,36 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  	pTitleText->setValue(from.str());  	//message body +	const std::string& subject = payload["subject"].asString();  	const std::string& message = payload["message"].asString(); +  	LLTextEditor* pMessageText = getChild<	LLTextEditor>("message", TRUE, FALSE); +	pMessageText->setValue("");  	pMessageText->setEnabled(FALSE);  	pMessageText->setTakesFocus(FALSE); -	pMessageText->setValue(message); + +	static const LLStyleSP headerstyle(new LLStyle(true, textColor, +			"SansSerifBig")); +	static const LLStyleSP datestyle(new LLStyle(true, textColor, "serif")); + +	pMessageText->appendStyledText(subject + "\n",false,false,headerstyle); + +	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],[" +							+LLTrans::getString("UTCTimeDay")+"] [" +							+LLTrans::getString("UTCTimeMth")+"] [" +							+LLTrans::getString("UTCTimeYr")+"] [" +							+LLTrans::getString("UTCTimeHr")+"]:[" +							+LLTrans::getString("UTCTimeMin")+"]:[" +							+LLTrans::getString("UTCTimeSec")+"] [" +							+LLTrans::getString("UTCTimeTimezone")+"]"; +	const LLDate timeStamp = notification->getDate(); +	LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now(); +	LLSD substitution; +	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch(); +	LLStringUtil::format(timeStr, substitution); +	pMessageText->appendStyledText(timeStr, false, false, datestyle); +	pMessageText->appendColoredText(std::string("\n\n") + message, false, +			false, textColor);  	//attachment  	BOOL hasInventory = payload["inventory_offer"].isDefined(); @@ -91,6 +120,13 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification  		mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);  		childSetActionTextbox("attachment", boost::bind(  				&LLToastGroupNotifyPanel::onClickAttachment, this)); + +		//attachment icon +		LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE); +		LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType, +												LLInventoryType::IT_TEXTURE, +												0, FALSE); +		pAttachIcon->setValue(attachIconImg->getName());  	}  	//ok button @@ -128,10 +164,43 @@ void LLToastGroupNotifyPanel::onClickOk()  void LLToastGroupNotifyPanel::onClickAttachment()  { -	mInventoryOffer->forceResponse(IOR_ACCEPT); +	if (mInventoryOffer != NULL) { +		mInventoryOffer->forceResponse(IOR_ACCEPT); -	mInventoryOffer = NULL; +		LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment", TRUE, +				FALSE); +		static const LLUIColor textColor = LLUIColorTable::instance().getColor( +				"GroupNotifyDimmedTextColor"); +		pAttachLink->setColor(textColor); -	LLTextBox * pAttachLink = getChild<LLTextBox>("attachment", TRUE, FALSE); -	pAttachLink->setVisible(FALSE); +		LLIconCtrl* pAttachIcon = +				getChild<LLIconCtrl> ("attachment_icon", TRUE); +		pAttachIcon->setEnabled(FALSE); + +		//if attachment isn't openable - notify about saving +		if (!isAttachmentOpenable(mInventoryOffer->mType)) { +			LLNotifications::instance().add("AttachmentSaved"); +		} + +		mInventoryOffer = NULL; +	}  } + +//static +bool LLToastGroupNotifyPanel::isAttachmentOpenable(LLAssetType::EType type) +{ +	switch(type) +	{ +	case LLAssetType::AT_LANDMARK: +	case LLAssetType::AT_FAVORITE: +	case LLAssetType::AT_NOTECARD: +	case LLAssetType::AT_IMAGE_JPEG: +	case LLAssetType::AT_IMAGE_TGA: +	case LLAssetType::AT_TEXTURE: +	case LLAssetType::AT_TEXTURE_TGA: +		return true; +	default: +		return false; +	} +} + diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h index f00f840e94..ba98531251 100644 --- a/indra/newview/lltoastgroupnotifypanel.h +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -66,6 +66,7 @@ protected:  	void onClickOk();  	void onClickAttachment();  private: +	static bool isAttachmentOpenable(LLAssetType::EType);  	LLButton* mSaveInventoryBtn; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index dd37d41ff5..72812d0bb9 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1606,6 +1606,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,  		gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);  	} +	// add buddy to recent people list +	LLRecentPeople::instance().add(to_agent);  }  void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent, @@ -1730,6 +1732,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,  	llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - "  			<< cat->getUUID() << llendl; +	// add buddy to recent people list +	LLRecentPeople::instance().add(to_agent); +  	// Test out how many items are being given.  	LLViewerInventoryCategory::cat_array_t cats;  	LLViewerInventoryItem::item_array_t items; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index acb7f927b6..9fb6d1c874 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -43,6 +43,7 @@  #include "llfloaterurldisplay.h"  #include "llfloaterworldmap.h"  #include "llpanellogin.h" +#include "llsidetray.h"  #include "llslurl.h"  #include "llstartup.h"			// gStartupState  #include "llurlsimstring.h" @@ -202,8 +203,9 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous  	S32 z = 0;  	LLURLSimString::parse(sim_string, ®ion_name, &x, &y, &z); -	LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); -	if(url_displayp) url_displayp->setName(region_name); +	// LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray. +	//LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); +	//if(url_displayp) url_displayp->setName(region_name);  	// Request a region handle by name  	LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, @@ -274,12 +276,11 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str  	local_pos.mV[VY] = (F32)local_y;  	local_pos.mV[VZ] = (F32)z; - +	LLVector3d global_pos = from_region_handle(region_handle); +	global_pos += LLVector3d(local_pos);  	if (teleport) -	{ -		LLVector3d global_pos = from_region_handle(region_handle); -		global_pos += LLVector3d(local_pos); +	{	  		gAgent.teleportViaLocation(global_pos);  		LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();  		if(instance) @@ -289,18 +290,28 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str  	}  	else  	{ -		// display informational floater, allow user to click teleport btn -		LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); -		if(url_displayp) -		{ -			url_displayp->displayParcelInfo(region_handle, local_pos); -			if(snapshot_id.notNull()) -			{ -				url_displayp->setSnapshotDisplay(snapshot_id); -			} -			std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); -			url_displayp->setLocationString(locationString); -		} +		LLSD key; +		key["type"] = "remote_place"; +		key["x"] = global_pos.mdV[VX]; +		key["y"] = global_pos.mdV[VY]; +		key["z"] = global_pos.mdV[VZ]; + +		LLSideTray::getInstance()->showPanel("panel_places", key); + +		// LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray. + +//		// display informational floater, allow user to click teleport btn +//		LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD()); +//		if(url_displayp) +//		{ +//			url_displayp->displayParcelInfo(region_handle, local_pos); +//			if(snapshot_id.notNull()) +//			{ +//				url_displayp->setSnapshotDisplay(snapshot_id); +//			} +//			std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z); +//			url_displayp->setLocationString(locationString); +//		}  	}  } diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index 62ed861c86..4155a87e14 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -46,7 +46,7 @@  #include "llviewermessage.h" // send_guid_sound_trigger  #include "llviewernetwork.h"  #include "llagent.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h"  // Globals  LLViewerGestureList gGestureList; @@ -136,7 +136,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )  	{  		// Don't play nodding animation, since that might not blend  		// with the gesture animation. -		LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); +		LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);  	}  } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 63234c2990..4e0c4023fd 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -36,7 +36,7 @@  #include "llviewerkeyboard.h"  #include "llmath.h"  #include "llagent.h" -#include "llbottomtray.h" +#include "llnearbychatbar.h"  #include "llviewercontrol.h"  #include "llfocusmgr.h"  #include "llmorphview.h" @@ -500,7 +500,7 @@ void stop_moving( EKeystate s )  void start_chat( EKeystate s )  {  	// start chat -	LLBottomTray::startChat(NULL); +	LLNearbyChatBar::startChat(NULL);  }  void start_gesture( EKeystate s ) @@ -508,15 +508,15 @@ void start_gesture( EKeystate s )  	if (KEYSTATE_UP == s &&  		!(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))  	{ - 		if (LLBottomTray::getInstance()->getCurrentChat().empty()) + 		if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())   		{   			// No existing chat in chat editor, insert '/' - 			LLBottomTray::getInstance()->startChat("/"); + 			LLNearbyChatBar::startChat("/");   		}   		else   		{   			// Don't overwrite existing text in chat editor - 			LLBottomTray::getInstance()->startChat(NULL); + 			LLNearbyChatBar::startChat(NULL);   		}  	}  } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e06e180ed5..7071b65228 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -132,6 +132,7 @@  #include "llfloatermemleak.h"  #include "llfasttimerview.h"  #include "llavataractions.h" +#include "lllandmarkactions.h"  #include "llmemoryview.h"  #include "llgivemoney.h"  #include "llgroupmgr.h" @@ -5270,24 +5271,6 @@ class LLWorldSetBusy : public view_listener_t  	}  }; -bool can_create_landmark() -{ -	BOOL can = FALSE; - -	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); -	if (agent_parcel) -{ - -		if (agent_parcel->getAllowLandmark() -			|| LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) -	{ -			can = TRUE; -		} -	} - -	return can; -} -  class LLWorldCreateLandmark : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -6675,9 +6658,7 @@ class LLWorldEnableCreateLandmark : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		bool new_value = can_create_landmark(); -		 -		return new_value; +		return !LLLandmarkActions::landmarkAlreadyExists();  	}  }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 74ded99124..25c00bb816 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -209,6 +209,10 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)  	LLUUID fid;  	LLMessageSystem* msg = gMessageSystem;  	const LLSD& payload = notification["payload"]; + +	// add friend to recent people list +	LLRecentPeople::instance().add(payload["from_id"]); +  	switch(option)  	{  	case 0: @@ -1180,6 +1184,9 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  			{  				opener = open_agent_offer;  			} + +			// add buddy to recent people list +			LLRecentPeople::instance().add(mFromID);  		}  			break;  		case IM_TASK_INVENTORY_OFFERED: diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 65f341627a..3aefa84295 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -765,13 +765,17 @@ BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const  BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const  {  	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global); -	if (region != gAgent.getRegion()) +	LLViewerRegion* agent_region = gAgent.getRegion(); +	if (!region || !agent_region) +		return FALSE; + +	if (region != agent_region)  	{  		// Can't be in the agent parcel if you're not in the same region.  		return FALSE;  	} -	LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global); +	LLVector3 pos_region = agent_region->getPosRegionFromGlobal(pos_global);  	S32 row =    S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);  	S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 902b59c732..0fadba1364 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -47,11 +47,13 @@  #include "llfloateravatarinfo.h"  #include "llfloaterworldmap.h"  #include "llnotify.h" +#include "llpanelplaces.h"  #include "llpreview.h"  #include "llpreviewtexture.h"  #include "llpreviewnotecard.h"  #include "llpreviewlandmark.h"  #include "llscrollbar.h" +#include "llsidetray.h"  #include "lltooldraganddrop.h"  #include "lltrans.h"  #include "llviewercontrol.h" @@ -1365,11 +1367,22 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc  {  	if (!item)  		return; -	LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance<LLPreviewLandmark>("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); -	if (preview) + +	LLSD key; +	key["type"] = "landmark"; +	key["id"] = item->getUUID(); + +	LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", key)); +	if (panel)  	{ -		preview->setItem( item ); +		panel->setItem(item);  	} + +//	LLPreviewLandmark* preview = LLFloaterReg::showTypedInstance<LLPreviewLandmark>("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); +//	if (preview) +//	{ +//		preview->setItem( item ); +//	}  }  void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc ) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index a949830dcf..533889b2f7 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -878,7 +878,10 @@ void LLViewerFetchedTexture::init(bool firstinit)  LLViewerFetchedTexture::~LLViewerFetchedTexture()  { -	if (mHasFetcher) +	//*NOTE getTextureFetch can return NULL when Viewer is shutting down. +	// This is due to LLWearableList is singleton and is destroyed after  +	// LLAppViewer::cleanup() was called. (see ticket EXT-177) +	if (mHasFetcher && LLAppViewer::getTextureFetch())  	{  		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);  	} diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 3e86f48cc5..f312cc0f63 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -184,6 +184,7 @@  #include "llviewernetwork.h"  #include "llpostprocess.h"  #include "llbottomtray.h" +#include "llnearbychatbar.h"  #include "llnotificationmanager.h" @@ -1559,10 +1560,12 @@ void LLViewerWindow::initWorldUI()  	getRootView()->sendChildToFront(gSnapshotFloaterView);  	// new bottom panel +	getRootView()->addChild(LLBottomTray::getInstance()); +	// Make sure Bottom Tray is behind Side Tray regardless "addChild" order. +	getRootView()->sendChildToBack(LLBottomTray::getInstance());  	LLRect rc = LLBottomTray::getInstance()->getRect();  	rc.mLeft = 0;  	rc.mRight = mRootView->getRect().getWidth(); -	mRootView->addChild(LLBottomTray::getInstance());  	LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE);  	LLBottomTray::getInstance()->setRect(rc); @@ -1646,12 +1649,10 @@ void LLViewerWindow::initWorldUI()  	getRootView()->sendChildToFront(gMenuHolder);  	//Channel Manager -	LLNotificationsUI::LLChannelManager * channel_manager -			= LLNotificationsUI::LLChannelManager::getInstance(); +	LLNotificationsUI::LLChannelManager* channel_manager = LLNotificationsUI::LLChannelManager::getInstance();  	getRootView()->addChild(channel_manager);  	//Notification Manager -	LLNotificationsUI::LLNotificationManager* notify_manager = -			LLNotificationsUI::LLNotificationManager::getInstance(); +	LLNotificationsUI::LLNotificationManager* notify_manager = LLNotificationsUI::LLNotificationManager::getInstance();  	getRootView()->addChild(notify_manager);  } @@ -2175,7 +2176,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();  	if( keyboard_focus )  	{ -		LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getChatBox() : NULL; +		LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL;  		// arrow keys move avatar while chatting hack  		if (chat_editor && chat_editor->hasFocus())  		{ diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index fc639fbb21..f1d4520370 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -67,6 +67,9 @@  #include "llfloaterfriends.h"  //VIVOX, inorder to refresh communicate panel  #include "llfloaterchat.h"		// for LLFloaterChat::addChat() +// for Talk Button's state updating +#include "llnearbychatbar.h" +  // for base64 decoding  #include "apr_base64.h" @@ -5783,6 +5786,7 @@ bool LLVoiceClient::getMuteMic() const  void LLVoiceClient::setUserPTTState(bool ptt)  {  	mUserPTTState = ptt; +	LLNearbyChatBar::getInstance()->setPTTState(ptt);  }  bool LLVoiceClient::getUserPTTState() @@ -5793,6 +5797,7 @@ bool LLVoiceClient::getUserPTTState()  void LLVoiceClient::toggleUserPTTState(void)  {  	mUserPTTState = !mUserPTTState; +	LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState);  }  void LLVoiceClient::setVoiceEnabled(bool enabled) diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 179c790aed..d55f9fa42f 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -304,7 +304,10 @@       value="0.3344 0.5456 0.5159 1" />      <color       name="GroupNotifyTextColor" -     value="0 0.12 0.24 1" /> +	 reference="White"/> +    <color +     name="GroupNotifyDimmedTextColor" +	 reference="DkGray"/>	       <color       name="GroupOverTierColor"       value="0.43 0.06 0.06 1" /> @@ -493,10 +496,10 @@       value="1 0.82 0.46 1" />      <color       name="NotifyCautionWarnColor" -     reference="Black" /> +     reference="White" />      <color       name="NotifyTextColor" -     reference="Black" /> +     reference="White" />      <color       name="ObjectChatColor"       reference="LtGray" /> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 3052571b1e..2d67e3d5a9 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -28,5 +28,21 @@        		color="1 1 1 1" enabled="true" image_name="closebox.tga"        		name="close_btn"/>  	</panel> -  <chat_items_container bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_history" /> +            <text_editor +             bg_readonly_color="ChatHistoryBgColor" +             bg_writeable_color="ChatHistoryBgColor" +             follows="left|top|right|bottom" +             font="SansSerif" +             layout="topleft" +			 height="320" +             max_length="2147483647" +             name="Chat History Editor" +             read_only="true" +             text_color="ChatHistoryTextColor" +             text_readonly_color="ChatHistoryTextColor" +             bottom="0" +             track_bottom="true" +             width="250" +             word_wrap="true" /> +  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml index 78dff0bd4a..013136a593 100644 --- a/indra/newview/skins/default/xui/en/menu_navbar.xml +++ b/indra/newview/skins/default/xui/en/menu_navbar.xml @@ -23,6 +23,9 @@          <menu_item_call.on_click           function="Navbar.Action"           parameter="landmark" /> +        <menu_item_call.on_enable +         function="Navbar.EnableMenuItem" +         parameter="can_landmark" />      </menu_item_call>      <menu_item_separator       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e922e3b743..fe1baf22d0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -181,22 +181,10 @@               function="World.Chat" />          </menu_item_call>          <menu_item_check -         label="Local Chat" -         layout="topleft" -         name="Chat History" -         shortcut="control|H"> -            <menu_item_check.on_check -             function="Floater.Visible" -             parameter="chat" /> -            <menu_item_check.on_click -             function="Floater.Toggle" -             parameter="chat" /> -        </menu_item_check> -        <menu_item_check           label="Nearby Chat"           layout="topleft"           name="Nearby Chat" -         shortcut="control|N"> +         shortcut="control|H">              <menu_item_check.on_check               function="Floater.Visible"               parameter="nearby_chat" /> @@ -204,29 +192,6 @@               function="Floater.Toggle"               parameter="nearby_chat" />          </menu_item_check> -        <menu_item_check -         label="Communicate" -         layout="topleft" -         name="Instant Message" -         shortcut="control|T"> -            <menu_item_check.on_check -             function="Floater.Visible" -             parameter="communicate" /> -            <menu_item_check.on_click -             function="Floater.Toggle" -             parameter="communicate" /> -        </menu_item_check> -        <menu_item_separator -         layout="topleft" /> -		<menu_item_call -         label="Media Remote Ctrl" -         layout="topleft" -         name="Preferences" -         shortcut="control|alt|M"> -            <menu_item_call.on_click -             function="Floater.Toggle" -             parameter="media_remote_ctrl" /> -        </menu_item_call>          <menu_item_separator           layout="topleft" />          <menu_item_check @@ -251,6 +216,29 @@               function="Floater.Toggle"               parameter="mute" />          </menu_item_check> +        <menu_item_separator +         layout="topleft" /> +        <menu_item_check +         label="(Legacy) Communicate" +         layout="topleft" +         name="Instant Message" +         shortcut="control|T"> +            <menu_item_check.on_check +             function="Floater.Visible" +             parameter="communicate" /> +            <menu_item_check.on_click +             function="Floater.Toggle" +             parameter="communicate" /> +        </menu_item_check> +		<menu_item_call +         label="(Temp) Media Remote Ctrl" +         layout="topleft" +         name="Preferences" +         shortcut="control|alt|M"> +            <menu_item_call.on_click +             function="Floater.Toggle" +             parameter="media_remote_ctrl" /> +        </menu_item_call>      </menu>      <menu       label="World" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c89eed37ab..17bb961308 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4191,6 +4191,7 @@ Are you sure you want to quit?       name="okcancelignore"       notext="Don't Quit"       yestext="Quit"/> +     <unique/>    </notification>    <notification @@ -6465,6 +6466,10 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block       yestext="Create group for L$100"/>    </notification> +  <notification icon="notifytip.tga" +		name="AttachmentSaved" type="notifytip"> +		Attachment has been saved. +  </notification>    <global name="UnsupportedCPU">  - Your CPU speed does not meet the minimum requirements. diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index bbef5a8892..d42943d225 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -39,105 +39,12 @@           layout="topleft"           left="5"           min_height="28" -         width="250" +         width="500"           top="0" -         min_width="100"> -            <line_editor -             border_style="line" -             border_thickness="1" -             follows="left|right" -             height="20" -             layout="topleft" -             left="0" -             name="chat_box" -             right="-39" -             top="3" -             width="250" /> -            <button follows="right" width="36" top="3" left="214" resize="false" -               label="Hx" height="20"> -              <button.commit_callback function="Floater.Toggle" parameter="chat"/> -          </button> -        </layout_panel> -        <icon -         auto_resize="false" -         color="0 0 0 0" -         follows="left|right" -         height="10" -         image_name="spacer24.tga" -         layout="topleft" -         left="0" -         top="0" -         width="5" -         min_width="5" /> -        <view_border -         auto_resize="false" -         bevel_style="in" -         follows="left|right" -         height="28" -         layout="topleft" -         left="270" -         top="0" -         width="1" /> -        <icon -         auto_resize="false" -         color="0 0 0 0" -         follows="left|right" -         height="10" -         image_name="spacer24.tga" -         layout="topleft" -         left="0" -         top="0" -         width="5"  -         min_width="5" /> -        <layout_panel -         auto_resize="false" -         follows="right" -         height="28" -         layout="topleft" -         min_height="28" -         width="100" -         top="0" -         min_width="100"> -            <chiclet_talk -             follows="right" -             height="20" -             layout="topleft" -             left="0" -             name="talk" -             top="3" -             width="100" /> -        </layout_panel> -        <icon -         auto_resize="false" -         color="0 0 0 0" -         follows="left|right" -         height="10" -         image_name="spacer24.tga" -         layout="topleft" -         left="0" -         name="DUMMY" -         top="0" -         width="5"  -         min_width="5"/> -        <layout_panel -         auto_resize="false" -         follows="right" -         height="28" -         layout="topleft" -         min_height="28" -         width="90" -         top="0" -         min_width="90"> -            <gesture_combo_box -             bottom="22" -             follows="right" -             height="20" -             label="Gestures" -             layout="topleft" -             name="Gesture" -             top="3" -             width="90" /> -        </layout_panel> +         min_width="305" +         name="chat_bar" +         user_resize="false" +         filename="panel_nearby_chat_bar.xml"/>  		 <icon           auto_resize="false"           color="0 0 0 0" @@ -159,7 +66,8 @@           min_height="28"           width="90"           top_delta="-10" -         min_width="90"> +         min_width="90" +         user_resize="false">              <button               bottom="22"               follows="right" @@ -190,7 +98,7 @@           top="0"           name="chiclet_list_panel"           width="150" -         min_width="70"> +         user_resize="false">              <chiclet_panel               follows="left|right"               height="25" @@ -222,14 +130,15 @@           name="im_well_panel"           width="40"           top="0" -         min_width="40" > +         min_width="40"  +         user_resize="false">              <chiclet_notification               follows="right"               height="25"               layout="topleft"               left="0"               name="im_well" -             top="1" +             top="2"               width="40">                <button                 image_selected="im_notifications.tga" @@ -285,14 +194,15 @@           top="0"           name="sys_well_panel"           width="48" -         min_width="48"> +         min_width="48" +         user_resize="false">              <chiclet_notification               follows="right"               height="25"               layout="topleft"               left="0"               name="sys_well" -             top="1" +             top="2"               width="48">                <button                 image_selected="bottom_tray_sys_notifications.tga" diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml index b628ee3aa1..713c3a41a2 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -15,7 +15,7 @@        		color="1 1 1 1" enabled="true" name="avatar_icon"  		  />      	<text -        	width="160" top="25" left="40" height="20" follows="left|right|top" +        	width="130" top="25" left="40" height="20" follows="left|right|top"          	font="SansSerifBigBold" text_color="white" word_wrap="true"          	mouse_opaque="true" name="sender_name" >  	      Jerry Knight diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml index 1757197372..a39a681f83 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml @@ -9,21 +9,23 @@  			top="5"  left="5" mouse_opaque="true" name="group_icon"/>  		<text type="string" length="1" follows="left|top|right|bottom"  			font="SansSerifBigBold" height="20" layout="topleft" left="60" name="title" -			text_color="white" top="20" width="300"> +			text_color="GroupNotifyTextColor" top="20" width="300">  			Sender Name / Group Name          </text>  	</panel>  	<text_editor type="string" length="1" bg_readonly_color="0 0 0 0"  		follows="left|top|right|bottom" height="70" hide_scrollbar="true"  		hide_border="true" layout="topleft" top="55" left="25" name="message" -		text_color="white" text_readonly_color="white" width="300" word_wrap="true"> +		text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true">  		Message  		Body      </text_editor> +	<icon follows="left|top|right|bottom" height="16" width="16" +		layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" />  	<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"  		type="string" length="1" follows="left|top|right|bottom" layout="topleft" -		left="25" top="135" height="15" width="300" name="attachment" -		text_color="white"> +		left="45" top="135" height="15" width="280" name="attachment" +		text_color="GroupNotifyTextColor">  		Attachment          </text>  	<button label="OK" layout="topleft" top="170" left="140" height="20" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml new file mode 100644 index 0000000000..8b19f9a515 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + default_tab_group="1" + follows="left|bottom|right" + height="25" + layout="topleft" + left="0" + name="chat_bar" + top="24" + width="500"> +    <line_editor +     border_style="line" +     border_thickness="1" +     follows="left|right" +     height="20" +     label="Click here to chat." +     layout="topleft" +     left_delta="7" +     left="0" +     name="chat_box" +     tool_tip="Press Enter to say, Ctrl-Enter to shout." +     top="3" +     width="250" /> +    <button  +	   follows="right"  +	   width="45"  +	   top="3"  +	   layout="topleft"  +	   left_pad="5" +       label="Log"  +	   height="20"> +      <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/> +    </button> +    <chiclet_talk +     follows="right" +     height="20" +     layout="topleft" +     left_pad="5" +     name="talk" +     top="3" +     width="100" /> +    <gesture_combo_box +     follows="right" +     height="20" +     label="Gestures" +     layout="topleft" +     name="Gesture" +     left_pad="5" +     top="3" +     width="90" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 686dc931d3..1a06e2bb06 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -9,7 +9,7 @@   left="0"   name="picture_item"   top="80" - width="310"> + width="245">      <texture_picker       allow_no_texture="true"       default_image_name="None" @@ -22,32 +22,31 @@       name="picture"       tab_stop="false"       top="7" -     width="90" /> +     width="70" />      <text -     follows="right" -     font="SansSerifBold" +     follows="top|left|right" +     font="SansSerif"       height="20"       layout="topleft" -     left="100" +     left="80"       name="picture_name"       text_color="black"       top="5"       use_ellipses="true" -     width="170"/> +     width="150"/>      <text -     follows="right" -     font="SansSerif" +     follows="top|left|right" +     font="SansSerifSmall"       height="40"       layout="topleft" -     left="100"       name="picture_descr"       text_color="white"       top="25"       use_ellipses="true" -     width="170" +     width="150"       word_wrap="true" />      <button -     follows="right" +     follows="top|right"       height="20"       image_disabled="navbar_bg_button.tga"       image_disabled_selected="navbar_bg_button.tga" diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index b746fcf84b..096b60adb1 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -8,6 +8,26 @@    collapsed="true"   >    <sidetray_tab 	 +    name="sidebar_home" +    tab_title="Home" +    description="Home." +    image="icn_voice-groupfocus.tga" +    mouse_opaque="false"  +    background_opaque="false"  +    background_visible="true"  +    bg_opaque_color="0.5 0.5 0.5 1.0" +  > +      <panel  +        name="panel_home"  +        filename="panel_sidetray_home_tab.xml"  +        width="355"  +        height="465"  +        label="home"  +        border="true"  +      /> +  </sidetray_tab> + +  <sidetray_tab 	      name="sidebar_people"      tab_title="People"      description="Find your friends, contacts and people nearby." @@ -17,15 +37,6 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <accordion_tab  -      name="people_accordion"  -      title="People"  -      collapsable="true"  -      min_width="200"  -      min_height="200"  -      expanded="true"  -      header_visible="false" -    >        <panel           class="panel_people"           name="panel_people"  @@ -35,7 +46,6 @@          label="People"           border="true"         /> -    </accordion_tab>    </sidetray_tab>    <!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->    <sidetray_tab  @@ -48,14 +58,6 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <accordion_tab  -      name="places_accordian"  -      title="Places"  -      collapsable="true"  -      min_width="355"  -      min_height="200"  -      header_visible="false" -    >        <panel           class="panel_places"           name="panel_places"  @@ -63,7 +65,6 @@          label="Places"           border="true"        /> -    </accordion_tab>    </sidetray_tab>    <sidetray_tab  @@ -75,14 +76,6 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <accordion_tab  -      name="me_accordion"  -      title="Me"  -      collapsable="false"  -      min_width="200"  -      min_height="200" -      header_visible="false" -    >        <panel           class="panel_me_profile"           name="panel_me_profile"  @@ -90,7 +83,6 @@          label="Me"           border="true"        /> -    </accordion_tab>    </sidetray_tab>    <!-- @@ -107,7 +99,7 @@        name="group_accordion"         title="Group General"        expanded="true" -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         header_visible="true" @@ -187,7 +179,7 @@      <accordion_tab         name="floater_preview_animation"         title="Preview Animation"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -206,7 +198,7 @@      <accordion_tab         name="floater_preview_gesture"         title="Preview Gesture"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -225,7 +217,7 @@      <accordion_tab         name="floater_preview_existing_landmark"         title="Preview Existing Landmark"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -244,7 +236,7 @@      <accordion_tab         name="floater_preview_sound"         title="Preview Sound"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -263,7 +255,7 @@      <accordion_tab         name="floater_preview_url"         title="Preview URL"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -282,7 +274,7 @@      <accordion_tab         name="floater_URL_entry"         title="URL Entry"  -      collapsable="true" +      collapsible="true"        expanded="false"        min_width="200"         min_height="200"  @@ -313,7 +305,7 @@      <accordion_tab         name="panel_region_covenant"         title="Region Covenant"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -332,7 +324,7 @@      <accordion_tab         name="panel_region_debug"         title="Region Debug"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -351,7 +343,7 @@    <accordion_tab         name="panel_region_estate"         title="Region Estate"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -370,7 +362,7 @@    <accordion_tab         name="panel_region_general"         title="Region General"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -389,7 +381,7 @@    <accordion_tab         name="panel_region_terrain"         title="Region Terrain"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -408,7 +400,7 @@    <accordion_tab         name="panel_region_texture"         title="Region Texture"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -427,7 +419,7 @@    <accordion_tab         name="floater_region_info"         title="Region Info"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -458,7 +450,7 @@      <accordion_tab         name="floater_tools"         title="Tools"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -477,7 +469,7 @@      <accordion_tab         name="floater_bulk_perms"         title="Bulk Perms"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -496,7 +488,7 @@      <accordion_tab         name="floater_build_options"         title="Build Options"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -528,7 +520,7 @@      <accordion_tab         name="floater_gesture"         title="Gestures"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -548,7 +540,7 @@      <accordion_tab         name="floater_buy_contents"         title="Buy Contents"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -567,7 +559,7 @@      <accordion_tab         name="floater_buy_object"         title="Buy Object"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -586,7 +578,7 @@      <accordion_tab         name="floater_inventory_view_finder"         title="Inventory View Finder"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -605,7 +597,7 @@      <accordion_tab         name="floater_mute"         title="Mute"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -624,7 +616,7 @@       <accordion_tab         name="floater_sell_land"         title="Sell Land"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  @@ -643,7 +635,7 @@       <accordion_tab         name="floater_telehub"         title="Telehub"  -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         expanded="false"  diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml new file mode 100644 index 0000000000..a85662603d --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- All our XML is utf-8 encoded. --> + +<panel +  name="home_tab" +  title="home_tab" +  visible="true" +  width="300" +  height="420" +  background_opaque="false" +  background_visible="true" +  bevel_style="in" +  follows="left|top|right|bottom"> +		<panel  +			left="10" width="280" height="130"  +			background_visible="true"  +			background_opaque="false"  +			bg_alpha_color="0.3 0.3 0.3 1.0"  +			name="sidebar_people" +			follows="left|top|right" +			class="panel_sidetray_home_info"> +    			<text +        			top="-10" width="200" left="5" height="30" follows="left|right|top" +        			font="SansSerifHugeBold" text_color="white" word_wrap="true" +        			mouse_opaque="false" name="tab_name" > +					People +    			</text> +    			<icon +      				top="-10" right="-10" width="20" height="20" follows="top|right" +      				color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga" +      				mouse_opaque="false" name="tab_icon"/> +  				<text +      				top="-40" left="10" right="-10" height="120" follows="left|right|bottom" +      				font="SansSerifBig" text_color="white" word_wrap="true" +      				mouse_opaque="false" name="tab_description" >     +					Find your friends, contacts and people nearby. +  				</text> +		</panel>  +		<panel  +			left="10" width="280" height="130"  +			background_visible="true"  +			background_opaque="false"  +			bg_alpha_color="0.3 0.3 0.3 1.0"  +			name="sidebar_places" +			follows="left|top|right" +			class="panel_sidetray_home_info"> +    			<text +        			top="-10" width="200" left="5" height="30" follows="left|right|top" +        			font="SansSerifHugeBold" text_color="white" word_wrap="true" +        			mouse_opaque="false" name="tab_name" > +					Places +    			</text> +    			<icon +      				top="-10" right="-10" width="20" height="20" follows="top|right" +      				color="1 1 1 1" enabled="true" image_name="inv_item_landmark.tga" +      				mouse_opaque="false" name="tab_icon"/> +  				<text +      				top="-40" left="10" right="-10" height="120" follows="left|right|bottom|top" +      				font="SansSerifBig" text_color="white" word_wrap="true" +      				mouse_opaque="false" name="tab_description" >     +					Find your friends, contacts and people nearby. +  				</text> +		</panel>  +		<panel  +			left="10" width="280" height="130"  +			background_visible="true"  +			background_opaque="false"  +			bg_alpha_color="0.3 0.3 0.3 1.0"  +			name="sidebar_me" +			follows="left|top|right" +			class="panel_sidetray_home_info"> +    			<text +        			top="-10" width="200" left="5" height="30" follows="left|right|top" +        			font="SansSerifHugeBold" text_color="white" word_wrap="true" +        			mouse_opaque="false" name="tab_name" > +					Me +    			</text> +    			<icon +      				top="-10" right="-10" width="20" height="20" follows="top|right" +      				color="1 1 1 1" enabled="true" image_name="icn_voice-pvtfocus.tga" +      				mouse_opaque="false" name="tab_icon"/> +  				<text +      				top="-40" left="10" right="-10" height="120" follows="left|right|bottom" +      				font="SansSerifBig" text_color="white" word_wrap="true" +      				mouse_opaque="false" name="tab_description" >     +					Change your profile, your look and quick links to your outfits. +  				</text> +		</panel>  +</panel>  +  
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml index 8952ea1307..ba4915e074 100644 --- a/indra/newview/skins/default/xui/en/panel_toast.xml +++ b/indra/newview/skins/default/xui/en/panel_toast.xml @@ -17,16 +17,16 @@    bg_alpha_color="0.3 0.3 0.3 1.0">    <text -   type="string"     visible="false"     follows="left|top|right|bottom"     font="SansSerifBold"     height="40"     layout="topleft"     left="60" -   name="text" +   name="toast_text" +   word_wrap="true"     text_color="white" -   top="30" +   top="20"     width="290">      Toast text;    </text> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 149da313a2..e5665b0194 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -652,6 +652,7 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh  	<string name="Stage">Stage</string>	  	<string name="Other">Other</string>	  	<string name="Any">Any</string>	 +	<string name="You">You</string>							  	<!-- puncutations -->  	<string name=":">:</string>			 @@ -785,4 +786,6 @@ If you continue to receive this message, contact customer support.  	<string name="UTCTimeMin">min,datetime,utc</string>  	<string name="UTCTimeSec">second,datetime,utc</string>  	<string name="UTCTimeTimezone">timezone,datetime,utc</string>							 +	 +	  </strings> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index efb9a89c6a..eb9bb99b20 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -10,16 +10,13 @@                  add_landmark_image_enabled="Favorite_Star_Active"                  add_landmark_image_disabled="Favorite_Star_Off"                  hover_glow_amount="0.15" -                add_landmark_width="20" -                add_landmark_height="20"                  add_landmark_hpad="2"                  allow_text_entry="true" -                arrow_image="Combobox_Selected"                  list_position="below"        	        show_text_as_tentative="false"                  max_chars="20"                  follows="left|top" -                background="TextField_Off"> +                >    <info_button name="Place Information"                            label=""                            tool_tip="About current location" diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml index 7004de8475..b33acf81cc 100644 --- a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml +++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml @@ -3,6 +3,5 @@              thumb_outline_color="SliderThumbOutlineColor"              thumb_center_color="SliderThumbCenterColor"              thumb_image="SliderThumb_Off" -            hover_glow_amount="0.15"              track_image="SliderTrack_Horiz"              track_highlight_image="SliderTrack_Horiz" /> | 
