diff options
| -rw-r--r-- | indra/llui/llflatlistview.cpp | 88 | ||||
| -rw-r--r-- | indra/llui/llflatlistview.h | 11 | ||||
| -rw-r--r-- | indra/newview/llimview.cpp | 63 | ||||
| -rw-r--r-- | indra/newview/llimview.h | 22 | ||||
| -rw-r--r-- | indra/newview/llpanelteleporthistory.cpp | 223 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_incoming_call.xml | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_outgoing_call.xml | 4 | 
7 files changed, 379 insertions, 36 deletions
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 7b7a3139a4..3754d155cf 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -66,7 +66,7 @@ const LLRect& LLFlatListView::getItemsRect() const  	return mItemsPanel->getRect();   } -bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/) +bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*/, EAddPosition pos /*= ADD_BOTTOM*/,bool rearrange /*= true*/)  {  	if (!item) return false;  	if (value.isUndefined()) return false; @@ -97,8 +97,11 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*  	// Children don't accept the focus  	item->setTabStop(false); -	rearrangeItems(); -	notifyParentItemsRectChanged(); +	if (rearrange) +	{ +		rearrangeItems(); +		notifyParentItemsRectChanged(); +	}  	return true;  } @@ -980,7 +983,86 @@ S32 LLFlatListView::notify(const LLSD& info)  			return 1;  		}  	} +	else if (info.has("rearrange")) +	{ +		rearrangeItems(); +		notifyParentItemsRectChanged(); +		return 1; +	}  	return 0;  } +void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items) +{ +	LLSD action; +	action.with("detach", LLSD()); +	// Clear detached_items list +	detached_items.clear(); +	// Go through items and detach valid items, remove them from items panel +	// and add to detached_items. +	for (pairs_iterator_t +			 iter = mItemPairs.begin(), +			 iter_end = mItemPairs.end(); +		 iter != iter_end; ++iter) +	{ +		LLPanel* pItem = (*iter)->first; +		if (1 == pItem->notify(action)) +		{ +			selectItemPair((*iter), false); +			mItemsPanel->removeChild(pItem); +			detached_items.push_back(pItem); +		} +	} +	if (!detached_items.empty()) +	{ +		// Some items were detached, clean ourself from unusable memory +		if (detached_items.size() == mItemPairs.size()) +		{ +			// This way will be faster if all items were disconnected +			for (pairs_iterator_t +					 iter = mItemPairs.begin(), +					 iter_end = mItemPairs.end(); +				 iter != iter_end; ++iter) +			{ +				(*iter)->first = NULL; +				delete *iter; +			} +			mItemPairs.clear(); +			// Also set items panel height to zero. +			// Reshape it to allow reshaping of non-item children. +			LLRect rc = mItemsPanel->getRect(); +			rc.mBottom = rc.mTop; +			mItemsPanel->reshape(rc.getWidth(), rc.getHeight()); +			mItemsPanel->setRect(rc); +			setNoItemsCommentVisible(true); +		} +		else +		{ +			for (std::vector<LLPanel*>::const_iterator +					 detached_iter = detached_items.begin(), +					 detached_iter_end = detached_items.end(); +				 detached_iter != detached_iter_end; ++detached_iter) +			{ +				LLPanel* pDetachedItem = *detached_iter; +				for (pairs_iterator_t +						 iter = mItemPairs.begin(), +						 iter_end = mItemPairs.end(); +					 iter != iter_end; ++iter) +				{ +					item_pair_t* item_pair = *iter; +					if (item_pair->first == pDetachedItem) +					{ +						mItemPairs.erase(iter); +						item_pair->first = NULL; +						delete item_pair; +						break; +					} +				} +			} +			rearrangeItems(); +		} +		notifyParentItemsRectChanged(); +	} +} +  //EOF diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index a488b00854..5999e79f61 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -133,7 +133,7 @@ public:  	 * Adds and item and LLSD value associated with it to the list at specified position  	 * @return true if the item was added, false otherwise   	 */ -	virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM); +	virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM, bool rearrange = true);  	/**  	 * Insert item_to_add along with associated value to the list right after the after_item. @@ -271,6 +271,15 @@ public:  	virtual void clear();  	/** +	 * Removes all items that can be detached from the list but doesn't destroy +	 * them, caller responsible to manage items after they are detached. +	 * Detachable item should accept "detach" action via notify() method, +	 * where it disconnect all callbacks, does other valuable routines and +	 * return 1. +	 */ +	void detachItems(std::vector<LLPanel*>& detached_items); + +	/**  	 * Set comparator to use for future sorts.  	 *   	 * This class does NOT manage lifetime of the comparator diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 3345f7d0bf..e2e3524f74 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1511,7 +1511,7 @@ bool LLOutgoingCallDialog::lifetimeHasExpired()  	if (mLifetimeTimer.getStarted())  	{  		F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32(); -		if (elapsed_time > LIFETIME)  +		if (elapsed_time > mLifetime)   		{  			return true;  		} @@ -1532,6 +1532,13 @@ void LLOutgoingCallDialog::show(const LLSD& key)  	// hide all text at first  	hideAllText(); +	// init notification's lifetime +	std::istringstream ss( getString("lifetime") ); +	if (!(ss >> mLifetime)) +	{ +		mLifetime = DEFAULT_LIFETIME; +	} +  	// customize text strings  	// tell the user which voice channel they are leaving  	if (!mPayload["old_channel_name"].asString().empty()) @@ -1641,6 +1648,43 @@ LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :  LLCallDialog(payload)  {  } +void LLIncomingCallDialog::draw() +{ +	if (lifetimeHasExpired()) +	{ +		onLifetimeExpired(); +	} +	LLDockableFloater::draw(); +} + +bool LLIncomingCallDialog::lifetimeHasExpired() +{ +	if (mLifetimeTimer.getStarted()) +	{ +		F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32(); +		if (elapsed_time > mLifetime)  +		{ +			return true; +		} +	} +	return false; +} + +void LLIncomingCallDialog::onLifetimeExpired() +{ +	// check whether a call is valid or not +	if (LLVoiceClient::getInstance()->findSession(mPayload["caller_id"].asUUID())) +	{ +		// restart notification's timer if call is still valid +		mLifetimeTimer.start(); +	} +	else +	{ +		// close invitation if call is already not valid +		mLifetimeTimer.stop(); +		closeFloater(); +	} +}  BOOL LLIncomingCallDialog::postBuild()  { @@ -1650,6 +1694,13 @@ BOOL LLIncomingCallDialog::postBuild()  	LLSD caller_id = mPayload["caller_id"];  	std::string caller_name = mPayload["caller_name"].asString(); +	// init notification's lifetime +	std::istringstream ss( getString("lifetime") ); +	if (!(ss >> mLifetime)) +	{ +		mLifetime = DEFAULT_LIFETIME; +	} +  	std::string call_type;  	if (gAgent.isInGroup(session_id))  	{ @@ -1687,6 +1738,16 @@ BOOL LLIncomingCallDialog::postBuild()  	childSetAction("Start IM", onStartIM, this);  	childSetFocus("Accept"); +	if(mPayload["notify_box_type"] != "VoiceInviteGroup" && mPayload["notify_box_type"] != "VoiceInviteAdHoc") +	{ +		// starting notification's timer for P2P and AVALINE invitations +		mLifetimeTimer.start(); +	} +	else +	{ +		mLifetimeTimer.stop(); +	} +  	return TRUE;  } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 92caf0af9a..d0ac819161 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -489,6 +489,14 @@ public:  	virtual BOOL postBuild();  protected: +	// lifetime timer for a notification +	LLTimer	mLifetimeTimer; +	// notification's lifetime in seconds +	S32		mLifetime; +	static const S32 DEFAULT_LIFETIME = 5; +	virtual bool lifetimeHasExpired() {return false;}; +	virtual void onLifetimeExpired() {}; +  	virtual void getAllowedRect(LLRect& rect);  	LLSD mPayload;  }; @@ -501,11 +509,16 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); +	// check timer state +	/*virtual*/ void draw(); +  	static void onAccept(void* user_data);  	static void onReject(void* user_data);  	static void onStartIM(void* user_data);  private: +	/*virtual*/ bool lifetimeHasExpired(); +	/*virtual*/ void onLifetimeExpired();  	void processCallResponse(S32 response);  }; @@ -524,15 +537,10 @@ public:  	/*virtual*/ void draw();  private: -  	// hide all text boxes  	void hideAllText(); -	// lifetime timer for NO_ANSWER notification -	LLTimer	mLifetimeTimer; -	// lifetime duration for NO_ANSWER notification -	static const S32 LIFETIME = 5; -	bool lifetimeHasExpired(); -	void onLifetimeExpired(); +	/*virtual*/ bool lifetimeHasExpired(); +	/*virtual*/ void onLifetimeExpired();  };  // Globals diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 596bd2909a..3eb90e919c 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -60,13 +60,18 @@ class LLTeleportHistoryFlatItem : public LLPanel  {  public:  	LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, const std::string &hl); -	virtual ~LLTeleportHistoryFlatItem() {}; +	virtual ~LLTeleportHistoryFlatItem();  	virtual BOOL postBuild(); +	/*virtual*/ S32 notify(const LLSD& info); +  	S32 getIndex() { return mIndex; }  	void setIndex(S32 index) { mIndex = index; }  	const std::string& getRegionName() { return mRegionName;} +	void setRegionName(const std::string& name); +	void setHighlightedText(const std::string& text); +	void updateTitle();  	/*virtual*/ void setValue(const LLSD& value); @@ -75,18 +80,51 @@ public:  	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);  	static void showPlaceInfoPanel(S32 index); + +	LLHandle<LLTeleportHistoryFlatItem> getItemHandle()	{ mItemHandle.bind(this); return mItemHandle; } +  private:  	void onProfileBtnClick();  	LLButton* mProfileBtn; +	LLTextBox* mTitle;  	LLTeleportHistoryPanel::ContextMenu *mContextMenu;  	S32 mIndex;  	std::string mRegionName;  	std::string mHighlight; +	LLRootHandle<LLTeleportHistoryFlatItem> mItemHandle; +}; + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlatItemStorage> { +protected: +	typedef std::vector< LLHandle<LLTeleportHistoryFlatItem> > flat_item_list_t; + +public: +	LLTeleportHistoryFlatItem* getFlatItemForPersistentItem ( +		LLTeleportHistoryPanel::ContextMenu *context_menu, +		const LLTeleportHistoryPersistentItem& persistent_item, +		const S32 cur_item_index, +		const std::string &hl); + +	void removeItem(LLTeleportHistoryFlatItem* item); + +	void purge(); + +private: + +	flat_item_list_t mItems;  }; +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +  LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, const std::string &hl)  :	LLPanel(),  	mIndex(index), @@ -97,18 +135,37 @@ LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistor  	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history_item.xml");  } +LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem() +{ +} +  //virtual  BOOL LLTeleportHistoryFlatItem::postBuild()  { -	LLTextUtil::textboxSetHighlightedVal(getChild<LLTextBox>("region"), LLStyle::Params(), mRegionName, mHighlight); +	mTitle = getChild<LLTextBox>("region");  	mProfileBtn = getChild<LLButton>("profile_btn");  	mProfileBtn->setClickedCallback(boost::bind(&LLTeleportHistoryFlatItem::onProfileBtnClick, this)); +	updateTitle(); +  	return true;  } +S32 LLTeleportHistoryFlatItem::notify(const LLSD& info) +{ +	if(info.has("detach")) +	{ +		delete mMouseDownSignal; +		mMouseDownSignal = NULL; +		delete mRightMouseDownSignal; +		mRightMouseDownSignal = NULL; +		return 1; +	} +	return 0; +} +  void LLTeleportHistoryFlatItem::setValue(const LLSD& value)  {  	if (!value.isMap()) return;; @@ -116,6 +173,25 @@ void LLTeleportHistoryFlatItem::setValue(const LLSD& value)  	childSetVisible("selected_icon", value["selected"]);  } +void LLTeleportHistoryFlatItem::setHighlightedText(const std::string& text) +{ +	mHighlight = text; +} + +void LLTeleportHistoryFlatItem::setRegionName(const std::string& name) +{ +	mRegionName = name; +} + +void LLTeleportHistoryFlatItem::updateTitle() +{ +	LLTextUtil::textboxSetHighlightedVal( +		mTitle, +		LLStyle::Params(), +		mRegionName, +		mHighlight); +} +  void LLTeleportHistoryFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)  {  	childSetVisible("hovered_icon", true); @@ -155,6 +231,82 @@ void LLTeleportHistoryFlatItem::onProfileBtnClick()  	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);  } +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +LLTeleportHistoryFlatItem* +LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem ( +	LLTeleportHistoryPanel::ContextMenu *context_menu, +	const LLTeleportHistoryPersistentItem& persistent_item, +	const S32 cur_item_index, +	const std::string &hl) +{ +	LLTeleportHistoryFlatItem* item = NULL; +	if ( cur_item_index < mItems.size() ) +	{ +		item = mItems[cur_item_index].get(); +		if (item->getParent() == NULL) +		{ +			item->setIndex(cur_item_index); +			item->setRegionName(persistent_item.mTitle); +			item->setHighlightedText(hl); +			item->setVisible(TRUE); +			item->updateTitle(); +		} +		else +		{ +			// Item already added to parent +			item = NULL; +		} +	} + +	if ( !item ) +	{ +		item = new LLTeleportHistoryFlatItem(cur_item_index, +											 context_menu, +											 persistent_item.mTitle, +											 hl); +		mItems.push_back(item->getItemHandle()); +	} + +	return item; +} + +void LLTeleportHistoryFlatItemStorage::removeItem(LLTeleportHistoryFlatItem* item) +{ +	if (item) +	{ +		flat_item_list_t::iterator item_iter = std::find(mItems.begin(), +														 mItems.end(), +														 item->getItemHandle()); +		if (item_iter != mItems.end()) +		{ +			mItems.erase(item_iter); +		} +	} +} + +void LLTeleportHistoryFlatItemStorage::purge() +{ +	for ( flat_item_list_t::iterator +			  it = mItems.begin(), +			  it_end = mItems.end(); +		  it != it_end; ++it ) +	{ +		LLHandle <LLTeleportHistoryFlatItem> item_handle = *it; +		if ( !item_handle.isDead() && item_handle.get()->getParent() == NULL ) +		{ +			item_handle.get()->die(); +		} +	} +	mItems.clear(); +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +  LLTeleportHistoryPanel::ContextMenu::ContextMenu() :  	mMenu(NULL)  { @@ -236,6 +388,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()  LLTeleportHistoryPanel::~LLTeleportHistoryPanel()  { +	LLTeleportHistoryFlatItemStorage::instance().purge();  	LLView::deleteViewByHandle(mGearMenuHandle);  } @@ -319,8 +472,11 @@ void LLTeleportHistoryPanel::draw()  // virtual  void LLTeleportHistoryPanel::onSearchEdit(const std::string& string)  { -	sFilterSubString = string; -	showTeleportHistory(); +	if (sFilterSubString != string) +	{ +		sFilterSubString = string; +		showTeleportHistory(); +	}  }  // virtual @@ -478,16 +634,15 @@ void LLTeleportHistoryPanel::refresh()  	while (mCurrentItem >= 0)  	{  		// Filtering -		std::string landmark_title = items[mCurrentItem].mTitle; -		LLStringUtil::toUpper(landmark_title); - -		std::string::size_type match_offset = sFilterSubString.size() ? landmark_title.find(sFilterSubString) : std::string::npos; -		bool passed = sFilterSubString.size() == 0 || match_offset != std::string::npos; - -		if (!passed) +		if (!sFilterSubString.empty())  		{ -			mCurrentItem--; -			continue; +			std::string landmark_title(items[mCurrentItem].mTitle); +			LLStringUtil::toUpper(landmark_title); +			if( std::string::npos == landmark_title.find(sFilterSubString) ) +			{ +				mCurrentItem--; +				continue; +			}  		}  		// Checking whether date of item is earlier, than tab_boundary_date. @@ -521,9 +676,14 @@ void LLTeleportHistoryPanel::refresh()  		if (curr_flat_view)  		{ -			LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(mCurrentItem, &mContextMenu, items[mCurrentItem].mTitle, sFilterSubString); -			curr_flat_view->addItem(item); - +			LLTeleportHistoryFlatItem* item = +				LLTeleportHistoryFlatItemStorage::instance() +				.getFlatItemForPersistentItem(&mContextMenu, +											  items[mCurrentItem], +											  mCurrentItem, +											  sFilterSubString); +			if ( !curr_flat_view->addItem(item, LLUUID::null, ADD_BOTTOM, false) ) +				llerrs << "Couldn't add flat item to teleport history." << llendl;  			if (mLastSelectedItemIndex == mCurrentItem)  				curr_flat_view->selectItem(item, true);  		} @@ -534,6 +694,16 @@ void LLTeleportHistoryPanel::refresh()  			break;  	} +	for (S32 n = mItemContainers.size() - 1; n >= 0; --n) +	{ +		LLAccordionCtrlTab* tab = mItemContainers.get(n); +		LLFlatListView* fv = getFlatListViewFromTab(tab); +		if (fv) +		{ +			fv->notify(LLSD().with("rearrange", LLSD())); +		} +	} +  	mHistoryAccordion->arrange();  	updateVerbs(); @@ -566,11 +736,12 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)  	}  	const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems(); -	LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(history_items.size(), // index will be decremented inside loop below -									&mContextMenu, -									history_items[history_items.size() - 1].mTitle, // Most recent item, it was -									sFilterSubString); -															 // added instead of removed +	LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() +		.getFlatItemForPersistentItem(&mContextMenu, +									  history_items[history_items.size() - 1], // Most recent item, it was added instead of removed +									  history_items.size(), // index will be decremented inside loop below +									  sFilterSubString); +  	fv->addItem(item, LLUUID::null, ADD_TOP);  	// Index of each item, from last to removed item should be decremented @@ -598,6 +769,8 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)  			if (item->getIndex() == removed_index)  			{ +				LLTeleportHistoryFlatItemStorage::instance().removeItem(item); +  				fv->removeItem(item);  				// If flat list becames empty, then accordion tab should be hidden @@ -629,10 +802,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()  		LLFlatListView* fv = getFlatListViewFromTab(tab);  		if (fv) -			fv->clear(); +		{ +			// Detached panels are managed by LLTeleportHistoryFlatItemStorage +			std::vector<LLPanel*> detached_items; +			fv->detachItems(detached_items); +		}  	} - -	refresh();  }  void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected) diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml index 81c54ae55e..b9ce11600f 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -11,6 +11,10 @@   title="UNKNOWN PERSON IS CALLING"   width="410">      <floater.string +     name="lifetime"> +        5 +    </floater.string> +    <floater.string       name="localchat">          Nearby Voice Chat      </floater.string> diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml index c6bc093c6c..104ac2143f 100644 --- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml +++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml @@ -11,6 +11,10 @@   title="CALLING"   width="410">      <floater.string +     name="lifetime"> +        5 +    </floater.string> +    <floater.string       name="localchat">          Nearby Voice Chat      </floater.string>  | 
