Stinson Linden avatar Stinson Linden committed 39c5204 Merge

Pull and merge from ssh://hg@bitbucket.org/lindenlab/viewer-beta.

Comments (0)

Files changed (19)

 e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
 73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
 5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
+f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
+4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
+94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1

indra/llmessage/llavatarnamecache.cpp

 	// http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
 	//
 	// Apache can handle URLs of 4096 chars, but let's be conservative
-	const U32 NAME_URL_MAX = 4096;
-	const U32 NAME_URL_SEND_THRESHOLD = 3000;
+	static const U32 NAME_URL_MAX = 4096;
+	static const U32 NAME_URL_SEND_THRESHOLD = 3500;
+
 	std::string url;
 	url.reserve(NAME_URL_MAX);
 
 	agent_ids.reserve(128);
 	
 	U32 ids = 0;
-	ask_queue_t::const_iterator it = sAskQueue.begin();
-	for ( ; it != sAskQueue.end(); ++it)
+	ask_queue_t::const_iterator it;
+	while(!sAskQueue.empty())
 	{
+		it = sAskQueue.begin();
 		const LLUUID& agent_id = *it;
+		sAskQueue.erase(it);
 
 		if (url.empty())
 		{
 
 		if (url.size() > NAME_URL_SEND_THRESHOLD)
 		{
-			LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
-									 << ids << " ids"
-									 << LL_ENDL;
-			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
-			url.clear();
-			agent_ids.clear();
+			break;
 		}
 	}
 
 	if (!url.empty())
 	{
-		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
+		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
 								 << ids << " ids"
 								 << LL_ENDL;
 		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
-		url.clear();
-		agent_ids.clear();
 	}
-
-	// We've moved all asks to the pending request queue
-	sAskQueue.clear();
 }
 
 void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
 
 void LLAvatarNameCache::requestNamesViaLegacy()
 {
+	static const S32 MAX_REQUESTS = 100;
 	F64 now = LLFrameTimer::getTotalSeconds();
 	std::string full_name;
-	ask_queue_t::const_iterator it = sAskQueue.begin();
-	for (; it != sAskQueue.end(); ++it)
+	ask_queue_t::const_iterator it;
+	for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
 	{
+		it = sAskQueue.begin();
 		const LLUUID& agent_id = *it;
+		sAskQueue.erase(it);
 
 		// Mark as pending first, just in case the callback is immediately
 		// invoked below.  This should never happen in practice.
 			boost::bind(&LLAvatarNameCache::legacyNameCallback,
 				_1, _2, _3));
 	}
-
-	// We've either answered immediately or moved all asks to the
-	// pending queue
-	sAskQueue.clear();
 }
 
 void LLAvatarNameCache::initClass(bool running)
 	// *TODO: Possibly re-enabled this based on People API load measurements
 	// 100 ms is the threshold for "user speed" operations, so we can
 	// stall for about that long to batch up requests.
-	//const F32 SECS_BETWEEN_REQUESTS = 0.1f;
-	//if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
-	//{
-	//	return;
-	//}
+	const F32 SECS_BETWEEN_REQUESTS = 0.1f;
+	if (!sRequestTimer.hasExpired())
+	{
+		return;
+	}
 
 	if (!sAskQueue.empty())
 	{
         }
 	}
 
+	if (sAskQueue.empty())
+	{
+		// cleared the list, reset the request timer.
+		sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS);
+	}
+
     // erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
     eraseUnrefreshed();
 }
 	sCache.erase(agent_id);
 }
 
-void LLAvatarNameCache::fetch(const LLUUID& agent_id)
-{
-	// re-request, even if request is already pending
-	sAskQueue.insert(agent_id);
-}
-
 void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
 	// *TODO: update timestamp if zero?

indra/llmessage/llavatarnamecache.h

     /// Provide some fallback for agents that return errors
 	void handleAgentError(const LLUUID& agent_id);
 
-	// Force a re-fetch of the most recent data, but keep the current
-	// data in cache
-	void fetch(const LLUUID& agent_id);
-
 	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 
 	// Compute name expiration time from HTTP Cache-Control header,

indra/llui/llcombobox.cpp

 	S32 min_width = getRect().getWidth();
 	S32 max_width = llmax(min_width, MAX_COMBO_WIDTH);
 	// make sure we have up to date content width metrics
-	mList->calcColumnWidths();
-	S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width);
+	S32 list_width = llclamp(mList->calcMaxContentWidth(), min_width, max_width);
 
 	if (mListPosition == BELOW)
 	{

indra/llui/llscrolllistcolumn.cpp

 	if (canResize() && mResizeBar->getRect().pointInRect(x, y))
 	{
 		// reshape column to max content width
+		mColumn->mParentCtrl->calcMaxContentWidth();
 		LLRect column_rect = getRect();
 		column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth;
 		setShape(column_rect, true);
 
 	LLRect snap_rect = getSnapRect();
 
+	mColumn->mParentCtrl->calcMaxContentWidth();
+
 	S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth();
 
 	// x coord growing means column growing, so same signs mean we're going in right direction

indra/llui/llscrolllistctrl.cpp

 #include "llboost.h"
 //#include "indra_constants.h"
 
+#include "llavatarnamecache.h"
 #include "llcheckboxctrl.h"
 #include "llclipboard.h"
 #include "llfocusmgr.h"
 	mMouseWheelOpaque(p.mouse_wheel_opaque),
 	mPageLines(p.page_lines),
 	mMaxSelectable(0),
-	mAllowKeyboardMovement(TRUE),
+	mAllowKeyboardMovement(true),
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
-	mCommitOnSelectionChange(FALSE),
-	mSelectionChanged(FALSE),
-	mNeedsScroll(FALSE),
-	mCanSelect(TRUE),
-	mColumnsDirty(FALSE),
+	mCommitOnSelectionChange(false),
+	mSelectionChanged(false),
+	mNeedsScroll(false),
+	mCanSelect(true),
+	mColumnsDirty(false),
 	mMaxItemCount(INT_MAX), 
-	mMaxContentWidth(0),
 	mBorderThickness( 2 ),
 	mOnDoubleClickCallback( NULL ),
 	mOnMaximumSelectCallback( NULL ),
 	mTotalStaticColumnWidth(0),
 	mTotalColumnPadding(0),
 	mSorted(false),
-	mDirty(FALSE),
+	mDirty(false),
 	mOriginalSelection(-1),
 	mLastSelected(NULL),
 	mHeadingHeight(p.heading_height),
 	mScrollLines = 0;
 	mLastSelected = NULL;
 	updateLayout();
-	mDirty = FALSE; 
+	mDirty = false; 
 }
 
 
 // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame
 //  while receiving a long list of names.
 // *TODO: Use bookkeeping to make this an incramental cost with item additions
-void LLScrollListCtrl::calcColumnWidths()
+S32 LLScrollListCtrl::calcMaxContentWidth()
 {
 	const S32 HEADING_TEXT_PADDING = 25;
 	const S32 COLUMN_TEXT_PADDING = 10;
 
-	mMaxContentWidth = 0;
-
 	S32 max_item_width = 0;
 
 	ordered_columns_t::iterator column_itor;
 		LLScrollListColumn* column = *column_itor;
 		if (!column) continue;
 
+		if (mColumnWidthsDirty)
+		{
+			mColumnWidthsDirty = false;
+			// update max content width for this column, by looking at all items
+			column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
+			item_list::iterator iter;
+			for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+			{
+				LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
+				if (!cellp) continue;
+
+				column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+			}
+		}
+		max_item_width += column->mMaxContentWidth;
+	}
+
+	return max_item_width;
+}
+
+bool LLScrollListCtrl::updateColumnWidths()
+{
+	bool width_changed = false;
+	ordered_columns_t::iterator column_itor;
+	for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor)
+	{
+		LLScrollListColumn* column = *column_itor;
+		if (!column) continue;
+
 		// update column width
 		S32 new_width = column->getWidth();
 		if (column->mRelWidth >= 0)
 			new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
 		}
 
-		column->setWidth(new_width);
-
-		// update max content width for this column, by looking at all items
-		column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
-		item_list::iterator iter;
-		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+		if (column->getWidth() != new_width)
 		{
-			LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
-			if (!cellp) continue;
-
-			column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+			column->setWidth(new_width);
+			width_changed = true;
 		}
-
-		max_item_width += column->mMaxContentWidth;
 	}
-
-	mMaxContentWidth = max_item_width;
+	return width_changed;
 }
 
 const S32 SCROLL_LIST_ROW_PAD = 2;
 
 void LLScrollListCtrl::updateColumns()
 {
-	calcColumnWidths();
+	if (!mColumnsDirty)
+		return;
+
+	mColumnsDirty = false;
+
+	bool columns_changed_width = updateColumnWidths();
 
 	// update column headers
 	std::vector<LLScrollListColumn*>::iterator column_ordered_it;
 	}
 
 	// propagate column widths to individual cells
-	item_list::iterator iter;
-	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+	if (columns_changed_width)
 	{
-		LLScrollListItem *itemp = *iter;
-		S32 num_cols = itemp->getNumColumns();
-		S32 i = 0;
-		for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+		item_list::iterator iter;
+		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
 		{
-			if (i >= (S32)mColumnsIndexed.size()) break;
-
-			cell->setWidth(mColumnsIndexed[i]->getWidth());
+			LLScrollListItem *itemp = *iter;
+			S32 num_cols = itemp->getNumColumns();
+			S32 i = 0;
+			for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+			{
+				if (i >= (S32)mColumnsIndexed.size()) break;
+
+				cell->setWidth(mColumnsIndexed[i]->getWidth());
+			}
 		}
 	}
-
 }
 
 void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
 		{
 			deselectItem(itemp);
 		}
-		first_item = FALSE;
+		first_item = false;
 	}
 	if (mCommitOnSelectionChange)
 	{
 
 		S32 cur_y = y;
 		
-		S32 line = 0;
 		S32 max_columns = 0;
 
 		LLColor4 highlight_color = LLColor4::white;
 		static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
 		highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f);
 
+		S32 first_line = mScrollLines;
+		S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage());
+
+		if (first_line >= mItemList.size())
+		{
+			return;
+		}
 		item_list::iterator iter;
-		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+		for (S32 line = first_line; line <= last_line; line++)
 		{
-			LLScrollListItem* item = *iter;
+			LLScrollListItem* item = mItemList[line];
 			
 			item_rect.setOriginAndSize( 
 				x, 
 
 				cur_y -= mLineHeight;
 			}
-			line++;
 		}
 	}
 }
 	if (mNeedsScroll)
 	{
 		scrollToShowSelected();
-		mNeedsScroll = FALSE;
+		mNeedsScroll = false;
 	}
 	LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
 	// Draw background
 		gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha );
 	}
 
-	if (mColumnsDirty)
-	{
-		updateColumns();
-		mColumnsDirty = FALSE;
-	}
+	updateColumns();
 
 	getChildView("comment_text")->setVisible(mItemList.empty());
 
 		setFocus(TRUE);
 
 		// clear selection changed flag because user is starting a selection operation
-		mSelectionChanged = FALSE;
+		mSelectionChanged = false;
 
 		handleClick(x, y, mask);
 	}
 		if(mask == MASK_NONE)
 		{
 			selectItemAt(x, y, mask);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 	}
 
 	// always commit when mouse operation is completed inside list
 	if (mItemListRect.pointInRect(x,y))
 	{
-		mDirty |= mSelectionChanged;
-		mSelectionChanged = FALSE;
+		mDirty = mDirty || mSelectionChanged;
+		mSelectionChanged = false;
 		onCommit();
 	}
 
 	}
 	else
 	{
-		gCacheName->getFullName(LLUUID(id), name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(LLUUID(id), &av_name);
+		name = av_name.getLegacyName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
 }
 		{
 			selectItemAt(x, y, mask);
 			gFocusMgr.setMouseCapture(this);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 		
 		// propagate state of cell to rest of selected column
 		// treat this as a normal single item selection
 		selectItemAt(x, y, mask);
 		gFocusMgr.setMouseCapture(this);
-		mNeedsScroll = TRUE;
+		mNeedsScroll = true;
 		// do not eat click (allow double click callback)
 		return FALSE;
 	}
 		if(mask == MASK_NONE)
 		{
 			selectItemAt(x, y, mask);
-			mNeedsScroll = TRUE;
+			mNeedsScroll = true;
 		}
 	}
 	else 
 				{
 					// commit implicit in call
 					selectPrevItem(FALSE);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					handled = TRUE;
 				}
 				break;
 				{
 					// commit implicit in call
 					selectNextItem(FALSE);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					handled = TRUE;
 				}
 				break;
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1));
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1));
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectFirstItem();
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
 				if (mAllowKeyboardMovement || hasFocus())
 				{
 					selectNthItem(getItemCount() - 1);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					if (mCommitOnKeyboardMovement
 						&& !mCommitOnSelectionChange) 
 					{
 				}
 				else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE))
 				{
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					// update search string only on successful match
 					mSearchTimer.reset();
 
 	if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE))
 	{
 		// update search string only on successful match
-		mNeedsScroll = TRUE;
+		mNeedsScroll = true;
 		mSearchString += uni_char;
 		mSearchTimer.reset();
 
 				if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
 				{
 					selectItem(item);
-					mNeedsScroll = TRUE;
+					mNeedsScroll = true;
 					cellp->highlightText(0, 1);
 					mSearchTimer.reset();
 
 		}
 		itemp->setSelected(TRUE);
 		mLastSelected = itemp;
-		mSelectionChanged = TRUE;
+		mSelectionChanged = true;
 	}
 }
 
 		{
 			cellp->highlightText(0, 0);	
 		}
-		mSelectionChanged = TRUE;
+		mSelectionChanged = true;
 	}
 }
 
 {
 	if (mSelectionChanged)
 	{
-		mDirty = TRUE;
+		mDirty = true;
 		mSelectionChanged = FALSE;
 		onCommit();
 	}
 
 void LLScrollListCtrl::dirtyColumns() 
 { 
-	mColumnsDirty = TRUE; 
+	mColumnsDirty = true; 
+	mColumnWidthsDirty = true;
 
 	// need to keep mColumnsIndexed up to date
 	// just in case someone indexes into it immediately
 void LLScrollListCtrl::onFocusReceived()
 {
 	// forget latent selection changes when getting focus
-	mSelectionChanged = FALSE;
+	mSelectionChanged = false;
 	LLUICtrl::onFocusReceived();
 }
 

indra/llui/llscrolllistctrl.h

 	static void onClickColumn(void *userdata);
 
 	virtual void updateColumns();
-	void calcColumnWidths();
-	S32 getMaxContentWidth() { return mMaxContentWidth; }
+	S32 calcMaxContentWidth();
+	bool updateColumnWidths();
 
 	void setHeadingHeight(S32 heading_height);
 	/**
 	S32				mHeadingHeight;	// the height of the column header buttons, if visible
 	U32				mMaxSelectable; 
 	LLScrollbar*	mScrollbar;
-	BOOL 			mAllowMultipleSelection;
-	BOOL			mAllowKeyboardMovement;
-	BOOL			mCommitOnKeyboardMovement;
-	BOOL			mCommitOnSelectionChange;
-	BOOL			mSelectionChanged;
-	BOOL			mNeedsScroll;
-	BOOL			mMouseWheelOpaque;
-	BOOL			mCanSelect;
-	const BOOL		mDisplayColumnHeaders;
-	BOOL			mColumnsDirty;
+	bool 			mAllowMultipleSelection;
+	bool			mAllowKeyboardMovement;
+	bool			mCommitOnKeyboardMovement;
+	bool			mCommitOnSelectionChange;
+	bool			mSelectionChanged;
+	bool			mNeedsScroll;
+	bool			mMouseWheelOpaque;
+	bool			mCanSelect;
+	bool			mDisplayColumnHeaders;
+	bool			mColumnsDirty;
+	bool			mColumnWidthsDirty;
 
 	mutable item_list	mItemList;
 
 	S32				mMaxItemCount; 
 
 	LLRect			mItemListRect;
-	S32				mMaxContentWidth;
 	S32             mColumnPadding;
 
 	BOOL			mBackgroundVisible;
 	typedef std::map<std::string, LLScrollListColumn*> column_map_t;
 	column_map_t mColumns;
 
-	BOOL			mDirty;
+	bool			mDirty;
 	S32				mOriginalSelection;
 
 	ContextMenuType mContextMenuType;

indra/llui/llview.cpp

 
 void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const
 {
-	*screen_x = local_x + getRect().mLeft;
-	*screen_y = local_y + getRect().mBottom;
+	*screen_x = local_x;
+	*screen_y = local_y;
 
 	const LLView* cur = this;
-	while( cur->mParentView )
+	do
 	{
+		LLRect cur_rect = cur->getRect();
+		*screen_x += cur_rect.mLeft;
+		*screen_y += cur_rect.mBottom;
 		cur = cur->mParentView;
-		*screen_x += cur->getRect().mLeft;
-		*screen_y += cur->getRect().mBottom;
 	}
+	while( cur );
 }
 
 void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const

indra/newview/llnamelistctrl.cpp

 {}
 
 // public
-void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
+LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
 								 BOOL enabled, const std::string& suffix)
 {
 	//llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
 	item.enabled = enabled;
 	item.target = INDIVIDUAL;
 
-	addNameItemRow(item, pos, suffix);
+	return addNameItemRow(item, pos, suffix);
 }
 
 // virtual, public
 {
 	BOOL handled = FALSE;
 	S32 column_index = getColumnIndexFromOffset(x);
-	LLScrollListItem* hit_item = hitItem(x, y);
+	LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
 	if (hit_item
 		&& column_index == mNameColumnIndex)
 	{
 				LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
 
 				// Should we show a group or an avatar inspector?
-				bool is_group = hit_item->getValue()["is_group"].asBoolean();
+				bool is_group = hit_item->isGroup();
 
 				LLToolTip::Params params;
 				params.background_visible( false );
 	addNameItemRow(item, pos);
 }
 
-void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
+LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
 {
 	item.target = INDIVIDUAL;
-	addNameItemRow(item, pos);
+	return addNameItemRow(item, pos);
 }
 
 LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
 	const std::string& suffix)
 {
 	LLUUID id = name_item.value().asUUID();
-	LLNameListItem* item = NULL;
-
-	// Store item type so that we can invoke the proper inspector.
-	// *TODO Vadim: Is there a more proper way of storing additional item data?
-	{
-		LLNameListCtrl::NameItem item_p(name_item);
-		item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
-		item = new LLNameListItem(item_p);
-		LLScrollListCtrl::addRow(item, item_p, pos);
-	}
+	LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP);
 
 	if (!item) return NULL;
 
+	LLScrollListCtrl::addRow(item, name_item, pos);
+
 	// use supplied name by default
 	std::string fullname = name_item.name;
 	switch(name_item.target)
 			setNeedsSort();
 		}
 	}
-
+	
 	dirtyColumns();
 }
 

indra/newview/llnamelistctrl.h

 class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem>
 {
 public:
-	LLUUID	getUUID() const		{ return getValue()["uuid"].asUUID(); }
+	bool isGroup() const { return mIsGroup; }
+	void setIsGroup(bool is_group) { mIsGroup = is_group; }
+
 protected:
 	friend class LLNameListCtrl;
 
 	LLNameListItem( const LLScrollListItem::Params& p )
-	:	LLScrollListItem(p)
+	:	LLScrollListItem(p), mIsGroup(false)
 	{
 	}
+
+	LLNameListItem( const LLScrollListItem::Params& p, bool is_group )
+	:	LLScrollListItem(p), mIsGroup(is_group)
+	{
+	}
+
+private:
+	bool mIsGroup;
 };
 
 
 public:
 	// Add a user to the list by name.  It will be added, the name
 	// requested from the cache, and updated as necessary.
-	void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
+	LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
 					 BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null);
-	void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
+	LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
 
 	/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
 	LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null);

indra/newview/llpanelgroup.h

 
 class LLOfferInfo;
 
-const S32 UPDATE_MEMBERS_PER_FRAME = 500;
+const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms
 
 // Forward declares
 class LLPanelGroupTab;

indra/newview/llpanelgroupgeneral.cpp

 
 #include "llpanelgroupgeneral.h"
 
+#include "llavatarnamecache.h"
+#include "llagent.h"
+#include "llsdparam.h"
 #include "lluictrlfactory.h"
-#include "llagent.h"
 #include "roles_constants.h"
 
 // UI elements
 		{
 			mMemberProgress = gdatap->mMembers.begin();
 			mPendingMemberUpdate = TRUE;
+			mUdpateSessionID.generate();
 
 			sSDTime = 0.0f;
 			sElementTime = 0.0f;
 
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 
-	if (!mListVisibleMembers || !gdatap 
+	if (!mListVisibleMembers 
+		|| !gdatap 
 		|| !gdatap->isMemberDataComplete()
 		|| gdatap->mMembers.empty())
 	{
 		return;
 	}
 
-	static LLTimer all_timer;
-	static LLTimer sd_timer;
-	static LLTimer element_timer;
+	LLTimer update_time;
+	update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
 
-	all_timer.reset();
-	S32 i = 0;
+	LLAvatarName av_name;
 
-	for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; 
-			++mMemberProgress, ++i)
+	for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired(); 
+			++mMemberProgress)
 	{
-		lldebugs << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl;
 		LLGroupMemberData* member = mMemberProgress->second;
 		if (!member)
 		{
 			continue;
 		}
-		// Owners show up in bold.
-		std::string style = "NORMAL";
-		sd_timer.reset();
-		LLSD row;
-		row["id"] = member->getID();
 
-		row["columns"][0]["column"] = "name";
-		row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][0]["font"]["style"] = style;
-		// value is filled in by name list control
+		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
+		{
+			addMember(mMemberProgress->second);
+		}
+		else
+		{
+			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
+			LLAvatarNameCache::get(mMemberProgress->first, 
+									boost::bind(&LLPanelGroupGeneral::onNameCache,
+												this, mUdpateSessionID, member, _1, _2));
+		}
+	}
 
-		row["columns"][1]["column"] = "title";
-		row["columns"][1]["value"] = member->getTitle();
-		row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][1]["font"]["style"] = style;
-
-		std::string status = member->getOnlineStatus();
-		
-		row["columns"][2]["column"] = "status";
-		row["columns"][2]["value"] = status;
-		row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL";
-		row["columns"][2]["font"]["style"] = style;
-
-		sSDTime += sd_timer.getElapsedTimeF32();
-
-		element_timer.reset();
-		LLScrollListItem* member_row = mListVisibleMembers->addElement(row);
-		
-		if ( member->isOwner() )
-		{
-			LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
-			if (name_textp)
-				name_textp->setFontStyle(LLFontGL::BOLD);
-		}
-		sElementTime += element_timer.getElapsedTimeF32();
-	}
-	sAllTime += all_timer.getElapsedTimeF32();
-
-	lldebugs << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
 	if (mMemberProgress == gdatap->mMembers.end())
 	{
 		lldebugs << "   member list completed." << llendl;
 		mListVisibleMembers->setEnabled(TRUE);
-
-		lldebugs << "All Time: " << sAllTime << llendl;
-		lldebugs << "SD Time: " << sSDTime << llendl;
-		lldebugs << "Element Time: " << sElementTime << llendl;
 	}
 	else
 	{
 	}
 }
 
+void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
+{
+	LLNameListCtrl::NameItem item_params;
+	item_params.value = member->getID();
+
+	LLScrollListCell::Params column;
+	item_params.columns.add().column("name").font.name("SANSSERIF_SMALL");
+
+	item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL");
+
+	item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL");
+
+	LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params);
+
+	if ( member->isOwner() )
+	{
+		LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
+		if (name_textp)
+			name_textp->setFontStyle(LLFontGL::BOLD);
+	}
+}
+
+void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
+{
+	if (!member 
+		|| update_id != mUdpateSessionID)
+	{
+		return;
+	}
+
+	addMember(member);
+}
+
 void LLPanelGroupGeneral::updateChanged()
 {
 	// List all the controls we want to check for changes...

indra/newview/llpanelgroupgeneral.h

 class LLCheckBoxCtrl;
 class LLComboBox;
 class LLSpinCtrl;
+class LLAvatarName;
 
 class LLPanelGroupGeneral : public LLPanelGroupTab
 {
 
 	virtual void setupCtrls	(LLPanel* parent);
 
+	void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
 private:
 	void	reset();
 
 	static void onReceiveNotices(LLUICtrl* ctrl, void* data);
 	static void openProfile(void* data);
 
-	S32		sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+	S32	 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+	void addMember(LLGroupMemberData* member);
 
     static bool joinDlgCB(const LLSD& notification, const LLSD& response);
 
 	BOOL			mChanged;
 	BOOL			mFirstUse;
 	std::string		mIncompleteMemberDataStr;
+	LLUUID			mUdpateSessionID;
 
 	// Group information (include any updates in updateChanged)
 	LLLineEditor		*mGroupNameEditor;

indra/newview/llpanelgroupinvite.cpp

 			//so we need to do this additional search in avatar tracker, see EXT-4732
 			if (LLAvatarTracker::instance().isBuddy(agent_id))
 			{
-				if (!gCacheName->getFullName(agent_id, fullname))
+				LLAvatarName av_name;
+				if (!LLAvatarNameCache::get(agent_id, &av_name))
 				{
 					// actually it should happen, just in case
-					gCacheName->get(LLUUID(agent_id), false, boost::bind(
+					LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(
 							&LLPanelGroupInvite::addUserCallback, this, _1, _2));
 					// for this special case!
 					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
 				}
 				else
 				{
-					names.push_back(fullname);
+					names.push_back(av_name.getLegacyName());
 				}
 			}
 		}
 	mImplementation->addUsers(names, agent_ids);
 }
 
-void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name)
+void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name)
 {
 	std::vector<std::string> names;
 	uuid_vec_t agent_ids;
 	agent_ids.push_back(id);
-	names.push_back(full_name);
+	names.push_back(av_name.getLegacyName());
 
 	mImplementation->addUsers(names, agent_ids);
 }

indra/newview/llpanelgroupinvite.h

 #include "llpanel.h"
 #include "lluuid.h"
 
+class LLAvatarName;
+
 class LLPanelGroupInvite
 : public LLPanel
 {
 	/**
 	 * this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers().
 	 */  
-	void addUserCallback(const LLUUID& id, const std::string& full_name);
+	void addUserCallback(const LLUUID& id, const LLAvatarName& av_name);
 	void clear();
 	void update();
 

indra/newview/llpanelgrouplandmoney.cpp

 			
 			row["columns"][3]["column"] = "type";
 			row["columns"][3]["value"] = land_type;
-			row["columns"][3]["font"] = "SANSSERIFSMALL";
+			row["columns"][3]["font"] = "SANSSERIF_SMALL";
 			
 			// hidden is always last column
 			row["columns"][4]["column"] = "hidden";

indra/newview/llpanelgrouproles.cpp

 #include "llcheckboxctrl.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llbutton.h"
 #include "llfiltereditor.h"
 #include "llfloatergroupinvite.h"
 	LLUIString donated = getString("donation_area");
 	donated.setArg("[AREA]", llformat("%d", data->getContribution()));
 
-	LLSD row;
-	row["id"] = id;
-
-	row["columns"][0]["column"] = "name";
-	// value is filled in by name list control
-
-	row["columns"][1]["column"] = "donated";
-	row["columns"][1]["value"] = donated.getString();
-
-	row["columns"][2]["column"] = "online";
-	row["columns"][2]["value"] = data->getOnlineStatus();
-	row["columns"][2]["font"] = "SANSSERIF_SMALL";
-
-	mMembersList->addElement(row);
+	LLNameListCtrl::NameItem item_params;
+	item_params.value = id;
+
+	item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL");
+
+	item_params.columns.add().column("donated").value(donated.getString())
+			.font.name("SANSSERIF_SMALL").style("NORMAL");
+
+	item_params.columns.add().column("online").value(data->getOnlineStatus())
+			.font.name("SANSSERIF_SMALL").style("NORMAL");
+	mMembersList->addNameItemRow(item_params);
 
 	mHasMatch = TRUE;
 }
 
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
 {
 	// Update ID is used to determine whether member whose id is passed
 	// into onNameCache() was passed after current or previous user-initiated update.
 	// we do nothing.
 	if (mUdpateSessionID != update_id) return;
 	
-	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
-		if (!gdatap) 
+	if (!member)
 	{
-		llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl;
 		return;
 	}
 	
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
-
-	LLGroupMemberData* data;
 	// trying to avoid unnecessary hash lookups
-	if (matchesSearchFilter(fullname) && ((data = gdatap->mMembers[id]) != NULL))
+	if (matchesSearchFilter(av_name.getLegacyName()))
 	{
-		addMemberToList(id, data);
+		addMemberToList(id, member);
 		if(!mMembersList->getEnabled())
 		{
 			mMembersList->setEnabled(TRUE);
 
 
 	LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
-	
-	S32 i = 0;
-	for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; 
-			++mMemberProgress, ++i)
+
+	LLTimer update_time;
+	update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
+
+	for( ; mMemberProgress != end && !update_time.hasExpired(); ++mMemberProgress)
 	{
 		if (!mMemberProgress->second)
 			continue;
+
 		// Do filtering on name if it is already in the cache.
-		std::string fullname;
-		if (gCacheName->getFullName(mMemberProgress->first, fullname))
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
 		{
-			if (matchesSearchFilter(fullname))
+			if (matchesSearchFilter(av_name.getLegacyName()))
 			{
 				addMemberToList(mMemberProgress->first, mMemberProgress->second);
 			}
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			gCacheName->get(mMemberProgress->first, FALSE, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
-																	   this, mUdpateSessionID, _1));
+			LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
+																	   this, mUdpateSessionID, mMemberProgress->second, _1, _2));
 		}
 	}
 

indra/newview/llpanelgrouproles.h

 	virtual void setGroupID(const LLUUID& id);
 
 	void addMemberToList(LLUUID id, LLGroupMemberData* data);
-	void onNameCache(const LLUUID& update_id, const LLUUID& id);
+	void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
 
 protected:
 	typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;

indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml

    layout="topleft"
    name="take_copy">
     <menu_item_call.on_click
-     function="InspectObject.TakeFreeCopy"/>
+     function="Tools.TakeCopy"/>
     <menu_item_call.on_visible
       function="Tools.EnableTakeCopy"/>
   </menu_item_call>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.