diff options
| author | Oz Linden <oz@lindenlab.com> | 2013-03-28 13:46:25 -0400 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2013-03-28 13:46:25 -0400 | 
| commit | effaca51841d6f07403b196a8d972861bb7e0f05 (patch) | |
| tree | 9bebc2e9327bcdeb43b0651fdae6c889eb71a8f9 | |
| parent | f9ef7ba13a3ee008cb958c2852dff6c8f1073ee0 (diff) | |
| parent | 130e4e510198147664a2377b62b22d8e42f00f04 (diff) | |
merge changes for 3.5.0-beta6
| -rw-r--r-- | .hgtags | 2 | ||||
| -rw-r--r-- | indra/llui/llscrolllistctrl.cpp | 27 | ||||
| -rw-r--r-- | indra/llui/llscrolllistctrl.h | 3 | ||||
| -rw-r--r-- | indra/llui/lltextbase.cpp | 18 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings_per_account.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llchiclet.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/lldonotdisturbnotificationstorage.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/llfloaterimcontainer.h | 1 | ||||
| -rw-r--r-- | indra/newview/llfloaterimnearbychat.cpp | 24 | ||||
| -rw-r--r-- | indra/newview/llfloaterimnearbychathandler.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsession.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.cpp | 30 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.h | 1 | ||||
| -rw-r--r-- | indra/newview/llimview.cpp | 221 | ||||
| -rw-r--r-- | indra/newview/llnotificationstorage.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llpersistentnotificationstorage.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 2 | ||||
| -rw-r--r-- | indra/newview/llvoicevivox.cpp | 69 | ||||
| -rw-r--r-- | indra/newview/llvoicevivox.h | 1 | 
21 files changed, 271 insertions, 201 deletions
| @@ -430,3 +430,5 @@ f6ca5bb75bca975ff0bc77e71e615f6478c4559c 3.5.0-beta3  53cffdde0b3cc367ba9bb6abd5c83ae14df5e882 3.5.0-beta4  4d5f6234dc59a0fb6ead5e02c7d343a0610e0488 DRTVWR-304  dd058a6093c493120d67c8e02c812c0f7b2d3db0 3.5.0-beta5 +fd6b510e83f56830e45670c428653134899d3e25 DRTVWR-305 +55339537d99afc394d1bb7fdb7d074bf321ca62f 3.5.0-beta6 diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 8b9fb47d5c..7f04c92b27 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1801,6 +1801,9 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  			// (N.B. callbacks don't take const refs as id is local scope)  			bool is_group = (mContextMenuType == MENU_GROUP);  			LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +			registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group)); +			registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id)); +			registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));  			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));  			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));  			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group)); @@ -1821,11 +1824,33 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  	return FALSE;  } -void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) +void LLScrollListCtrl::showProfile(std::string id, bool is_group)  {  	// show the resident's profile or the group profile  	std::string sltype = is_group ? "group" : "agent";  	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about"; +	LLUrlAction::showProfile(slurl); +} + +void LLScrollListCtrl::sendIM(std::string id) +{ +	// send im to the resident +	std::string slurl = "secondlife:///app/agent/" + id + "/about"; +	LLUrlAction::sendIM(slurl); +} + +void LLScrollListCtrl::addFriend(std::string id) +{ +	// add resident to friends list +	std::string slurl = "secondlife:///app/agent/" + id + "/about"; +	LLUrlAction::addFriend(slurl); +} + +void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) +{ +	// open the resident's details or the group details +	std::string sltype = is_group ? "group" : "agent"; +	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";  	LLUrlAction::clickAction(slurl);  } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 38450b6313..8fa06cc499 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -430,6 +430,9 @@ private:  	BOOL			setSort(S32 column, BOOL ascending);  	S32				getLinesPerPage(); +	static void		showProfile(std::string id, bool is_group); +	static void		sendIM(std::string id); +	static void		addFriend(std::string id);  	static void		showNameDetails(std::string id, bool is_group);  	static void		copyNameToClipboard(std::string id, bool is_group);  	static void		copySLURLToClipboard(std::string id, bool is_group); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ebc9ee244e..270d5294f9 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -3201,7 +3201,23 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin  	LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0)   		? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE   		: LLFontGL::ONLY_WORD_BOUNDARIES; -	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart,  +	 +	 +	LLWString offsetString(text.c_str() + segment_offset + mStart); + +	if(getLength() < segment_offset + mStart) +	{ +		llerrs << "getLength() < segment_offset + mStart\t getLength()\t" << getLength() << "\tsegment_offset:\t"  +						<< segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl; +	} + +	if(offsetString.length() + 1 < max_chars) +	{ +		llerrs << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetString.length():\t" << offsetString.length() +			<< getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl; +	} +	 +	S32 num_chars = mStyle->getFont()->maxDrawableChars(offsetString.c_str(),   												(F32)num_pixels,  												max_chars,   												word_wrap_style); diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index ada374f892..590f41283b 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -292,6 +292,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>NearbyChatIsNotCollapsed</key> +    <map> +      <key>Comment</key> +      <string>Saving expanded/collapsed state of the nearby chat between sessions</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>ShowFavoritesOnLogin</key>          <map>          <key>Comment</key> diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index b221daf936..43c6b558bc 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -174,6 +174,7 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)  	if("close all" == action)  	{  		LLNotificationWellWindow::getInstance()->closeAll(); +		LLIMWellWindow::getInstance()->closeAll();  	}  } diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index be20adeb8a..82affcf068 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -132,6 +132,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()  {  	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS); +	LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL; +  	LLSD input;  	if (!readNotifications(input) ||input.isUndefined())  	{ @@ -225,6 +227,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()      //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)  	saveNotifications(); + +	LL_INFOS("LLDoNotDisturbNotificationStorage") << "finished loading notifications" << LL_ENDL;  }  void LLDoNotDisturbNotificationStorage::updateNotifications() diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 5e0cd8ef78..7296ec3ced 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -626,6 +626,12 @@ void LLFloaterIMContainer::setVisible(BOOL visible)  	LLMultiFloater::setVisible(visible);  } +void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key) +{ +	LLMultiFloater::setVisibleAndFrontmost(take_focus, key); +    selectConversationPair(getSelectedSession(), false, take_focus); +} +  void LLFloaterIMContainer::updateResizeLimits()  {  	LLMultiFloater::updateResizeLimits(); @@ -1331,7 +1337,10 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)      selectConversationPair(session_id, true);      LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id); -    session_floater->restoreFloater(); +    if (session_floater) +    { +        session_floater->restoreFloater(); +    }  }  void LLFloaterIMContainer::clearAllFlashStates() @@ -1963,10 +1972,13 @@ bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bo  void LLFloaterIMContainer::expandConversation()  { -	LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession())); -	if (widget) +	if(!mConversationsPane->isCollapsed())  	{ -		widget->setOpen(!widget->isOpen()); +		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession())); +		if (widget) +		{ +			widget->setOpen(!widget->isOpen()); +		}  	}  } diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 2cbc1e99f9..52b672241f 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -60,6 +60,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& key);  	/*virtual*/ void draw();  	/*virtual*/ void setVisible(BOOL visible); +	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());  	/*virtual*/ void updateResizeLimits();  	void onCloseFloater(LLUUID& id); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index b287950c21..d86e1b3fd7 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -283,6 +283,11 @@ void LLFloaterIMNearbyChat::onTearOffClicked()  void LLFloaterIMNearbyChat::onOpen(const LLSD& key)  {  	LLFloaterIMSessionTab::onOpen(key); +	if(!isMessagePaneExpanded()) +	{ +		restoreFloater(); +		onCollapseToLine(this); +	}  	showTranslationCheckbox(LLTranslate::isTranslationConfigured());  } @@ -322,11 +327,8 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)  void LLFloaterIMNearbyChat::show()  { -	if (isChatMultiTab()) -	{  		openFloater(getKey());  	} -}  bool LLFloaterIMNearbyChat::isChatVisible() const  { @@ -480,11 +482,14 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke()  		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))  		{  			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -			mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part +			if (!rest_of_match.empty()) +			{ +				mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part -			// Select to end of line, starting from the character -			// after the last one the user typed. -			mInputEditor->selectNext(rest_of_match, false); +				// Select to end of line, starting from the character +				// after the last one the user typed. +				mInputEditor->selectNext(rest_of_match, false); +			}  		}  		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))  		{ @@ -741,15 +746,14 @@ void LLFloaterIMNearbyChat::startChat(const char* line)  	{  		if(!nearby_chat->isTornOff())  		{ -			nearby_chat->show(); +			LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));  		}  		if(nearby_chat->isMinimized())  		{  			nearby_chat->setMinimized(false);  		} -		nearby_chat->setVisible(TRUE); +		nearby_chat->show();  		nearby_chat->setFocus(TRUE); -		nearby_chat->mInputEditor->setFocus(TRUE);  		if (line)  		{ diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index 7afcf288ce..0824b26406 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -559,9 +559,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,      LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); -	if(( nearby_chat->hasFocus() -        || im_box->hasFocus() -		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT +	if((  ( chat_msg.mSourceType == CHAT_SOURCE_AGENT  			&& gSavedSettings.getBOOL("UseChatBubbles") )  		|| mChannel.isDead()  		|| !mChannel.get()->getShowToasts() ) @@ -606,17 +604,16 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,  			toast_msg = chat_msg.mText;  		} -		//Don't show nearby toast, if conversation is visible but not focused -		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID()); -		if (session_floater && session_floater->isMessagePaneExpanded() -		    && session_floater->isInVisibleChain() && !session_floater->isMinimized() -		    && !(session_floater->getHost() && session_floater->getHost()->isMinimized())) +		//Don't show nearby toast, if conversation is visible and selected +		if (im_box->getSelectedSession().isNull() && +				((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost()) +						|| (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))  		{  			return;  		}          //Will show toast when chat preference is set         -        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !session_floater->isMessagePaneExpanded()) +        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !nearby_chat->isMessagePaneExpanded())          {              // Add a nearby chat toast.              LLUUID id; diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 73adfd0eda..6d5145f205 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -618,6 +618,8 @@ void LLFloaterIMSession::onClose(bool app_quitting)  	// Last change:  	// EXT-3516 X Button should end IM session, _ button should hide  	gIMMgr->leaveSession(mSessionID); +    // *TODO: Study why we need to restore the floater before we close it. +    // Might be because we want to save some state data in some clean open state.  	LLFloaterIMSessionTab::restoreFloater();  	// Clean up the conversation *after* the session has been ended  	LLFloaterIMSessionTab::onClose(app_quitting); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index eab2ce7798..5083331167 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -132,6 +132,12 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)  			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);  		}  		LLFloaterIMSessionTab::addToHost(mSessionID); +		LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID); + +		if (conversp && conversp->isNearbyChat() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotCollapsed")) +		{ +			onCollapseToLine(this); +		}  		mInputButtonPanel->setVisible(isTornOff());  	} @@ -356,7 +362,7 @@ void LLFloaterIMSessionTab::draw()  		// Restart the refresh timer  		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);  	} -	 +  	LLTransientDockableFloater::draw();  } @@ -698,10 +704,12 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()  			&& !mIsP2PChat;  	mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible); +    mParticipantListPanel->setVisible(is_participant_list_visible);  	// Display collapse image (<<) if the floater is hosted  	// or if it is torn off but has an open control panel.  	bool is_expanded = is_not_torn_off || is_participant_list_visible; +      	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));  	mExpandCollapseBtn->setToolTip(  			is_not_torn_off? @@ -818,14 +826,15 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)  	{  		if (!self->mIsP2PChat)  		{ +            // The state must toggle the collapsed state of the panel              bool should_be_expanded = self->mParticipantListPanel->isCollapsed(); -			// Expand/collapse the participant list panel -            self->mParticipantListAndHistoryStack->collapsePanel(self->mParticipantListPanel, !should_be_expanded); -            self->mParticipantListPanel->setVisible(should_be_expanded); +			// Update the expand/collapse flag of the participant list panel and save it              gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);              self->mIsParticipantListExpanded = should_be_expanded; -			self->mExpandCollapseBtn->setImageOverlay(self->getString(should_be_expanded ? "collapse_icon" : "expand_icon")); +             +            // Refresh for immediate feedback +            self->refreshConversation();  		}  	} @@ -863,7 +872,7 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse)  		enableResizeCtrls(true, true, true);  	} - +	saveCollapsedState();  	setShape(floater_rect, true);  	mBodyStack->updateLayout(); @@ -885,6 +894,7 @@ void LLFloaterIMSessionTab::restoreFloater()  		mBodyStack->updateLayout();  		mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));  		setMessagePaneExpanded(true); +		saveCollapsedState();  		enableResizeCtrls(true, true, true);  	}  } @@ -1060,6 +1070,14 @@ LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()  	return conversationItem;  } +void LLFloaterIMSessionTab::saveCollapsedState() +{ +	LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID); +	if(conversp->isNearbyChat()) +	{ +		gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded()); +	} +}  BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )  {  	if(mask == MASK_ALT) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index f0899a3c09..c7e73bd70d 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -101,6 +101,7 @@ public:  	bool isMessagePaneExpanded(){return mMessagePaneExpanded;}  	void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}  	void restoreFloater(); +	void saveCollapsedState();  protected: diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8c862548bb..76a314f807 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -160,163 +160,150 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,  void on_new_message(const LLSD& msg)  { -    std::string action; +    std::string user_preferences;      LLUUID participant_id = msg["from_id"].asUUID();      LLUUID session_id = msg["session_id"].asUUID();      LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); -    //  determine action for this session +    // do not show notification which goes from agent +    if (gAgent.getID() == participant_id) +    { +        return; +    } + +    // determine state of conversations floater +    enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status; + +    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); +	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); + +	if (!LLFloater::isVisible(im_box) || im_box->isMinimized()) +	{ +		conversations_floater_status = CLOSED; +	} +	else if ( !im_box->hasFocus() && +			(!session_floater || !LLFloater::isVisible(session_floater) +	            || session_floater->isMinimized() || !session_floater->hasFocus())) +	{ +		conversations_floater_status = NOT_ON_TOP; +	} +	else if (im_box->getSelectedSession() != session_id) +	{ +		conversations_floater_status = ON_TOP; +    } +	else +	{ +		conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED; +	} +    //  determine user prefs for this session      if (session_id.isNull())      { -        action = gSavedSettings.getString("NotificationNearbyChatOptions"); +    	user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");      }      else if(session->isP2PSessionType())      {          if (LLAvatarTracker::instance().isBuddy(participant_id))          { -            action = gSavedSettings.getString("NotificationFriendIMOptions"); +        	user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");          }          else          { -            action = gSavedSettings.getString("NotificationNonFriendIMOptions"); +        	user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");          }      }      else if(session->isAdHocSessionType())      { -        action = gSavedSettings.getString("NotificationConferenceIMOptions"); +    	user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");      }      else if(session->isGroupSessionType())      { -        action = gSavedSettings.getString("NotificationGroupChatOptions"); +    	user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");      } -    // do not show notification which goes from agent -    if (gAgent.getID() == participant_id) -    { -        return; -    } - -    // execution of the action - -    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"); -	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); -	 -	if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id -		&& !(session_floater->getHost() ? im_box->isMinimized() : session_floater->isMinimized())) -	{ -		return; -	} -	 -    //session floater not focused (visible or not) -    bool session_floater_not_focused = session_floater && !session_floater->hasFocus(); - -    //conv. floater is closed -    bool conversation_floater_is_closed = -    		!(  im_box -    		    && im_box->isInVisibleChain() -                && !im_box->isMinimized()); - -    //conversation floater not focused (visible or not) -    bool conversation_floater_not_focused = -    		conversation_floater_is_closed || !im_box->hasFocus(); -    // sess. floater is open -    bool session_floater_is_open = -            session_floater -            && session_floater->isInVisibleChain() -            && !session_floater->isMinimized() -            && !(session_floater->getHost() && session_floater->getHost()->isMinimized()); - -    bool conversation_floater_collapsed = !session_floater->isMessagePaneExpanded(); -    if (("toast" == action && !session_floater_is_open) || conversation_floater_collapsed) -    { -        //User is not focused on conversation containing the message -        if(session_floater_not_focused || conversation_floater_collapsed) -        { -        	if(!LLMuteList::getInstance()->isMuted(participant_id)) -        	{ -        		im_box->flashConversationItemWidget(session_id, true); -        	} -            //The conversation floater isn't focused/open -            if(conversation_floater_not_focused || conversation_floater_collapsed) -            { -            	if(!LLMuteList::getInstance()->isMuted(participant_id)  -                    && !gAgent.isDoNotDisturb()) -            	{ -            		gToolBarView->flashCommand(LLCommandId("chat"), true); -            	} - -                //Show IM toasts (upper right toasts) -                // Skip toasting for system messages and for nearby chat -                if(session_id.notNull() && participant_id.notNull()) -                { -                    LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -                } -            } -		} -    } +    // actions: -    else if ("flash" == action) +    // 0. nothing - exit +    if (("none" == user_preferences || +    		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status) +    	&& session_floater->isMessagePaneExpanded())      { -    	if (!gAgent.isDoNotDisturb()) -    	{ -			im_box->flashConversationItemWidget(session_id, true); -			if(conversation_floater_not_focused) -			{ -				//User is not focused on conversation containing the message -				gToolBarView->flashCommand(LLCommandId("chat"), true); -			} -		} -		else if(session_id.notNull() && participant_id.notNull()) -		{ -			//If a DND message, allow notification to be stored so upon DND exit  -			//useMostItrusiveIMNotification will be called to notify user a message exists -			LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -		} +    	return;      } -    else if("openconversations" == action) +    // 1. open floater and [optional] surface it +    if ("openconversations" == user_preferences && +    		(CLOSED == conversations_floater_status +    				|| NOT_ON_TOP == conversations_floater_status))      { -        //User is not focused on conversation containing the message -        if(session_floater_not_focused) +    	if(!gAgent.isDoNotDisturb())          { -            //Flash line item -            im_box->flashConversationItemWidget(session_id, true); - -            if(!gAgent.isDoNotDisturb()) -            { -				//Surface conversations floater -				LLFloaterReg::showInstance("im_container"); -				im_box->collapseMessagesPane(false); -				if (session_floater) +			// Open conversations floater +			LLFloaterReg::showInstance("im_container"); +			im_box->collapseMessagesPane(false); +			if (session_floater) +			{ +				if (session_floater->getHost())  				{ -					if (session_floater->getHost()) +					if (NULL != im_box && im_box->isMinimized())  					{ -						if (NULL != im_box && im_box->isMinimized()) -						{ -							LLFloater::onClickMinimize(im_box); -						} +						LLFloater::onClickMinimize(im_box);  					} -					else +				} +				else +				{ +					if (session_floater->isMinimized())  					{ -						if (session_floater->isMinimized()) -						{ -							LLFloater::onClickMinimize(session_floater); -						} +						LLFloater::onClickMinimize(session_floater);  					}  				}  			} - -            //If in DND mode, allow notification to be stored so upon DND exit  +		} +        else +        { +            //If in DND mode, allow notification to be stored so upon DND exit              //useMostItrusiveIMNotification will be called to notify user a message exists -            if(session_id.notNull()  -                && participant_id.notNull() -                && gAgent.isDoNotDisturb() -				&& !session_floater_is_open) +            if(session_id.notNull() +               && participant_id.notNull() +		       && !session_floater->isShown())              {                  LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); -			} -		} +	        } +        } +    } + +    // 2. Flash line item +    if ("openconversations" == user_preferences +    		|| ON_TOP == conversations_floater_status) +    { +    	if(!LLMuteList::getInstance()->isMuted(participant_id)) +    	{ +    		im_box->flashConversationItemWidget(session_id, true); +    	} +    } + +    // 3. Flash FUI button +    if (("toast" == user_preferences || "flash" == user_preferences) && +    		(CLOSED == conversations_floater_status +    		    || NOT_ON_TOP == conversations_floater_status)) +    { +    	if(!LLMuteList::getInstance()->isMuted(participant_id) +            && !gAgent.isDoNotDisturb()) +    	{ +    		gToolBarView->flashCommand(LLCommandId("chat"), true); +    	} +    } + +    // 4. Toast +    if ("toast" == user_preferences +    		    || !session_floater->isMessagePaneExpanded()) +    { +        //Show IM toasts (upper right toasts) +        // Skip toasting for system messages and for nearby chat +        if(session_id.notNull() && participant_id.notNull()) +        { +            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg)); +        }      }  } diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp index b6184f09bf..2923221c90 100644 --- a/indra/newview/llnotificationstorage.cpp +++ b/indra/newview/llnotificationstorage.cpp @@ -105,6 +105,8 @@ bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) co  bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const  { +	LL_INFOS("LLNotificationStorage") << "starting read '" << mFileName << "'" << LL_ENDL; +  	bool didFileRead;  	pNotificationData.clear(); @@ -126,6 +128,8 @@ bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const  		}  	} +	LL_INFOS("LLNotificationStorage") << "ending read '" << mFileName << "'" << LL_ENDL; +  	return didFileRead;  } diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 11c12e6c10..666f10df96 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -87,6 +87,8 @@ void LLPersistentNotificationStorage::loadNotifications()  {  	LLFastTimer _(FTM_LOAD_NOTIFICATIONS); +	LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL; +  	LLNotifications::instance().getChannel("Persistent")->  		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); @@ -129,6 +131,8 @@ void LLPersistentNotificationStorage::loadNotifications()  			notification_channel->hideToast(notification->getID());  		}  	} + +	LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;  }  bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d295fc60cd..a3093f069d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -675,7 +675,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mBelowWater(FALSE),  	mLastAppearanceBlendTime(0.f),  	mAppearanceAnimating(FALSE), -	mNameString(), +    mNameIsSet(false),  	mTitle(),  	mNameAway(false),  	mNameDoNotDisturb(false), @@ -3096,8 +3096,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  	}  	// Rebuild name tag if state change detected -	if (mNameString.empty() -		|| (mNameString.size() == 2 && mNameString[0] == 10 && mNameString[1] == 10) // *TODO : find out why mNameString is sometimes "" +	if (!mNameIsSet  		|| new_name  		|| (!title && !mTitle.empty())  		|| (title && mTitle != title->getString()) @@ -3292,17 +3291,16 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,  	{  		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);  	} -	mNameString += line; -	mNameString += '\n'; +    mNameIsSet |= !line.empty();  }  void LLVOAvatar::clearNameTag()  { -	mNameString.clear(); +    mNameIsSet = false;  	if (mNameText)  	{  		mNameText->setLabel(""); -		mNameText->setString( "" ); +		mNameText->setString("");  	}  	mTimeVisible.reset();  } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index c59a3a150c..9f1f209920 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -939,7 +939,7 @@ protected:  	static void		getAnimLabels(LLDynamicArray<std::string>* labels);  	static void		getAnimNames(LLDynamicArray<std::string>* names);	  private: -	std::string		mNameString;		// UTF-8 title + name + status +    bool            mNameIsSet;  	std::string  	mTitle;  	bool	  		mNameAway;  	bool	  		mNameDoNotDisturb; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index f3342b7ff1..c3cc90f040 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1258,7 +1258,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateCreatingSessionGroup  		case stateCreatingSessionGroup: -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// *TODO: Question: is this the right way out of this state  				setState(stateSessionTerminated); @@ -1274,7 +1274,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateRetrievingParcelVoiceInfo  		case stateRetrievingParcelVoiceInfo:   			// wait until parcel voice info is received. -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// if a terminate request has been received,  				// bail and go to the stateSessionTerminated @@ -1294,7 +1294,7 @@ void LLVivoxVoiceClient::stateMachine()  			// Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.  			sendFriendsListUpdates(); -			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized) +			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))  			{  				// TODO: Question: Is this the right way out of this state?  				setState(stateSessionTerminated); @@ -1442,7 +1442,7 @@ void LLVivoxVoiceClient::stateMachine()  		//MARK: stateRunning  		case stateRunning:				// steady state  			// Disabling voice or disconnect requested. -			if(!mVoiceEnabled && mIsInitialized || mSessionTerminateRequested) +			if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested)  			{  				leaveAudioSession();  			} @@ -2671,33 +2671,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)  {  	buddyListEntry *buddy = findBuddy(id); -	// Make sure we don't add a name before it's been looked up. +	// Make sure we don't add a name before it's been looked up in the avatar name cache  	LLAvatarName av_name; -	if(LLAvatarNameCache::get(id, &av_name)) +	if (LLAvatarNameCache::get(id, &av_name))  	{ -		// *NOTE: For now, we feed legacy names to Vivox because I don't know -		// if their service can support a mix of new and old clients with -		// different sorts of names. +		// *NOTE: We feed legacy names to Vivox because we don't know if their service +		// can support a mix of new and old clients with different sorts of names.  		std::string name = av_name.getAccountName(); - -		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); -		bool canSeeMeOnline = false; -		if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) -			canSeeMeOnline = true; -		 -		// When we get here, mNeedsSend is true and mInSLFriends is false.  Change them as necessary. -		if(buddy) +		if (buddy)  		{ -			// This buddy is already in both lists. - -			if(name != buddy->mDisplayName) -			{ -				// The buddy is in the list with the wrong name.  Update it with the correct name. -				LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL; -				buddy->mDisplayName = name; -				buddy->mNeedsNameUpdate = true;		// This will cause the buddy to be resent. -			} +			// This buddy is already in both lists (vivox buddies and avatar cache). +            // Trust the avatar cache more for the display name (vivox display name are notoriously wrong) +            buddy->mDisplayName = name;  		}  		else  		{ @@ -2706,20 +2692,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)  			buddy->mUUID = id;  		} -		// In all the above cases, the buddy is in the SL friends list (which is how we got here). -		buddy->mInSLFriends = true; -		buddy->mCanSeeMeOnline = canSeeMeOnline; +		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); +		buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); +		// In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here).  		buddy->mNameResolved = true; -		 +		buddy->mInSLFriends = true;  	}  	else  	{ -		// This name hasn't been looked up yet.  Don't do anything with this buddy list entry until it has. -		if(buddy) +		// This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has. +		if (buddy)  		{  			buddy->mNameResolved = false;  		} -		  		// Initiate a lookup.  		// The "lookup completed" callback will ensure that the friends list is rechecked after it completes.  		lookupName(id); @@ -2827,13 +2812,12 @@ void LLVivoxVoiceClient::sendFriendsListUpdates()  			{  				std::ostringstream stream; -				if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate)) +				if(buddy->mInSLFriends && !buddy->mInVivoxBuddies)  				{					  					if(mNumberOfAliases > 0)  					{  						// Add (or update) this entry in the vivox buddy list  						buddy->mInVivoxBuddies = true; -						buddy->mNeedsNameUpdate = false;  						LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;  						stream   							<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">" @@ -5859,7 +5843,6 @@ LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :  	mNameResolved = false;  	mInVivoxBuddies = false;  	mInSLFriends = false; -	mNeedsNameUpdate = false;  }  void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName) @@ -5884,25 +5867,21 @@ LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::stri  	buddyListEntry *result = NULL;  	buddyListMap::iterator iter = mBuddyListMap.find(uri); -	if(iter != mBuddyListMap.end()) +	if (iter != mBuddyListMap.end())  	{  		// Found a matching buddy already in the map.  		LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;  		result = iter->second;  	} -	if(!result) +	if (!result)  	{  		// participant isn't already in one list or the other.  		LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;  		result = new buddyListEntry(uri);  		result->mDisplayName = displayName; -		if(IDFromName(uri, result->mUUID))  -		{ -			// Extracted UUID from name successfully. -		} -		else +		if (!IDFromName(uri, result->mUUID))  		{  			LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;  		} @@ -7272,7 +7251,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)  void LLVivoxProtocolParser::EndTag(const char *tag)  {  	const std::string& string = textBuffer; -	 +  	responseDepth--;  	if (ignoringTags) @@ -7371,6 +7350,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)  		}  		else if (!stricmp("Buddy", tag))  		{ +            // NOTE : Vivox does *not* give reliable display name for Buddy tags +            // We don't take those very seriously as a result...  			LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);  		}  		else if (!stricmp("BlockRule", tag)) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 574027de42..a6f40eb3e9 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -584,7 +584,6 @@ protected:  		bool mNameResolved;  		bool mInSLFriends;  		bool mInVivoxBuddies; -		bool mNeedsNameUpdate;  	};  	typedef std::map<std::string, buddyListEntry*> buddyListMap; | 
