summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llflatlistview.cpp88
-rw-r--r--indra/llui/llflatlistview.h11
-rw-r--r--indra/newview/llimview.cpp63
-rw-r--r--indra/newview/llimview.h22
-rw-r--r--indra/newview/llpanelteleporthistory.cpp223
-rw-r--r--indra/newview/skins/default/xui/en/floater_incoming_call.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_outgoing_call.xml4
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 &region_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 &region_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>