summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llaccordionctrltab.cpp51
-rw-r--r--indra/llui/llaccordionctrltab.h6
-rw-r--r--indra/newview/llavatarlist.cpp4
-rw-r--r--indra/newview/llavatarlistitem.cpp7
-rw-r--r--indra/newview/llchiclet.cpp35
-rw-r--r--indra/newview/llcofwearables.cpp25
-rw-r--r--indra/newview/llcofwearables.h47
-rw-r--r--indra/newview/llgrouplist.cpp2
-rw-r--r--indra/newview/llimfloater.cpp17
-rw-r--r--indra/newview/llimfloater.h2
-rw-r--r--indra/newview/llinventoryitemslist.cpp32
-rw-r--r--indra/newview/llinventoryitemslist.h23
-rw-r--r--indra/newview/lloutfitslist.cpp131
-rw-r--r--indra/newview/lloutfitslist.h11
-rw-r--r--indra/newview/llpanelteleporthistory.cpp2
-rw-r--r--indra/newview/llparticipantlist.cpp35
-rw-r--r--indra/newview/llparticipantlist.h2
-rw-r--r--indra/newview/llviewermessage.cpp15
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml17
20 files changed, 376 insertions, 90 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 3ecab90756..88a1652671 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -101,6 +101,7 @@ set(llui_SOURCE_FILES
lluictrlfactory.cpp
lluiimage.cpp
lluistring.cpp
+ lluitextutil.cpp
llundo.cpp
llurlaction.cpp
llurlentry.cpp
@@ -197,6 +198,7 @@ set(llui_HEADER_FILES
llui.h
lluiimage.h
lluistring.h
+ lluitextutil.h
llundo.h
llurlaction.h
llurlentry.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 596da782ce..0db2dca615 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -32,12 +32,13 @@
#include "linden_common.h"
-#include "lluictrl.h"
-#include "llscrollbar.h"
#include "llaccordionctrltab.h"
-#include "lllocalcliprect.h"
+#include "lllocalcliprect.h"
+#include "llscrollbar.h"
#include "lltextbox.h"
+#include "lluictrl.h"
+#include "lluitextutil.h"
static const std::string DD_BUTTON_NAME = "dd_button";
static const std::string DD_TEXTBOX_NAME = "dd_textbox";
@@ -72,7 +73,8 @@ public:
virtual BOOL postBuild();
- void setTitle(const std::string& title);
+ std::string getTitle();
+ void setTitle(const std::string& title, const std::string& hl);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
@@ -146,10 +148,28 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::postBuild()
return TRUE;
}
-void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title)
+std::string LLAccordionCtrlTab::LLAccordionCtrlTabHeader::getTitle()
{
if(mHeaderTextbox)
- mHeaderTextbox->setText(title);
+ {
+ return mHeaderTextbox->getText();
+ }
+ else
+ {
+ return LLStringUtil::null;
+ }
+}
+
+void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title, const std::string& hl)
+{
+ if(mHeaderTextbox)
+ {
+ LLTextUtil::textboxSetHighlightedVal(
+ mHeaderTextbox,
+ LLStyle::Params(),
+ title,
+ hl);
+ }
}
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
@@ -436,12 +456,25 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
addChild(panel,0);
}
-void LLAccordionCtrlTab::setTitle(const std::string& title)
+std::string LLAccordionCtrlTab::getTitle()
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ return header->getTitle();
+ }
+ else
+ {
+ return LLStringUtil::null;
+ }
+}
+
+void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& hl)
{
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
if (header)
{
- header->setTitle(title);
+ header->setTitle(title, hl);
}
}
@@ -903,5 +936,3 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
}
return LLUICtrl::handleToolTip(x, y, mask);
}
-
-
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index de254ed3eb..f5b7fd0af6 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -113,8 +113,10 @@ public:
void setAccordionView(LLView* panel);
LLView* getAccordionView() { return mContainerPanel; };
- // Set text in LLAccordionCtrlTabHeader
- void setTitle(const std::string& title);
+ std::string getTitle();
+
+ // Set text and highlight substring in LLAccordionCtrlTabHeader
+ void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null);
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb);
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index dfb213716c..47ec5270c3 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -316,9 +316,7 @@ void LLAvatarList::refresh()
}
// Send refresh_complete signal.
- std::vector<LLSD> cur_values;
- getValues(cur_values);
- mRefreshCompleteSignal(this, LLSD((S32)cur_values.size()));
+ mRefreshCompleteSignal(this, LLSD((S32)size(false)));
}
// Commit if we've added/removed items.
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 2a51eeacfc..656274cb7a 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -36,12 +36,13 @@
#include "llavataractions.h"
#include "llavatarlistitem.h"
+#include "llbutton.h"
#include "llfloaterreg.h"
+#include "lluitextutil.h"
+
#include "llagent.h"
-#include "lloutputmonitorctrl.h"
#include "llavatariconctrl.h"
-#include "lltextutil.h"
-#include "llbutton.h"
+#include "lloutputmonitorctrl.h"
bool LLAvatarListItem::sStaticInitialized = false;
S32 LLAvatarListItem::sLeftPadding = 0;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 9c4aa7b964..6897f4ee8e 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -183,20 +183,6 @@ void LLSysWellChiclet::setCounter(S32 counter)
mButton->setLabel(s_count);
- setNewMessagesState(counter > mCounter);
-
- // we have to flash to 'Lit' state each time new unread message is coming.
- if (counter > mCounter)
- {
- mFlashToLitTimer->flash();
- }
- else if (counter == 0)
- {
- // if notification is resolved while well is flashing it can leave in the 'Lit' state
- // when flashing finishes itself. Let break flashing here.
- mFlashToLitTimer->stopFlashing();
- }
-
mCounter = counter;
}
@@ -316,7 +302,26 @@ void LLIMWellChiclet::createMenu()
void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
{
- setCounter(LLBottomTray::getInstance()->getTotalUnreadIMCount());
+ const LLUUID& session_id = session_data["session_id"];
+ const S32 counter = LLBottomTray::getInstance()->getTotalUnreadIMCount();
+ const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container")
+ && !LLFloaterReg::instanceVisible("impanel", session_id);
+
+ setNewMessagesState(counter > mCounter && im_not_visible);
+
+ // we have to flash to 'Lit' state each time new unread message is coming.
+ if (counter > mCounter && im_not_visible)
+ {
+ mFlashToLitTimer->flash();
+ }
+ else if (counter == 0)
+ {
+ // if notification is resolved while well is flashing it can leave in the 'Lit' state
+ // when flashing finishes itself. Let break flashing here.
+ mFlashToLitTimer->stopFlashing();
+ }
+
+ setCounter(counter);
}
/************************************************************************/
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 498aeec682..8d4430a9ea 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -46,6 +46,20 @@ static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearable
const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
+static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
+
+
+bool LLWearableItemNameComparator::doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const
+{
+ std::string name1 = wearable_item1->getItemName();
+ std::string name2 = wearable_item2->getItemName();
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+}
+
LLCOFWearables::LLCOFWearables() : LLPanel(),
mAttachments(NULL),
@@ -73,6 +87,10 @@ BOOL LLCOFWearables::postBuild()
mClothing->setCommitOnSelectionChange(true);
mBodyParts->setCommitOnSelectionChange(true);
+ //clothing is sorted according to its position relatively to the body
+ mAttachments->setComparator(&WEARABLE_NAME_COMPARATOR);
+ mBodyParts->setComparator(&WEARABLE_NAME_COMPARATOR);
+
return LLPanel::postBuild();
}
@@ -164,16 +182,15 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel
if (mAttachments->size())
{
- mAttachments->sort(); //*TODO by Name
+ mAttachments->sort();
mAttachments->notify(REARRANGE); //notifying the parent about the list's size change (cause items were added with rearrange=false)
}
if (mBodyParts->size())
{
- mBodyParts->sort(); //*TODO by name
+ mBodyParts->sort();
+ mBodyParts->notify(REARRANGE);
}
-
- mBodyParts->notify(REARRANGE);
}
//create a clothing list item, update verbs and show/hide line separator
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 32acba5a3e..612bb103d2 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -40,6 +40,53 @@
class LLFlatListView;
+
+/** Abstract comparator of wearable list items */
+class LLWearableListItemComparator : public LLFlatListView::ItemComparator
+{
+ LOG_CLASS(LLWearableListItemComparator);
+
+public:
+ LLWearableListItemComparator() {};
+ virtual ~LLWearableListItemComparator() {};
+
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLPanelWearableListItem* wearable_item1 = dynamic_cast<const LLPanelWearableListItem*>(item1);
+ const LLPanelWearableListItem* wearable_item2 = dynamic_cast<const LLPanelWearableListItem*>(item2);
+
+ if (!wearable_item1 || !wearable_item2)
+ {
+ llwarning("item1 and item2 cannot be null", 0);
+ return true;
+ }
+
+ return doCompare(wearable_item1, wearable_item2);
+ }
+
+protected:
+
+ /**
+ * Returns true if wearable_item1 < wearable_item2, false otherwise
+ * Implement this method in your particular comparator.
+ */
+ virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const = 0;
+};
+
+
+class LLWearableItemNameComparator : public LLWearableListItemComparator
+{
+ LOG_CLASS(LLWearableItemNameComparator);
+
+public:
+ LLWearableItemNameComparator() {};
+ virtual ~LLWearableItemNameComparator() {};
+
+protected:
+ virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const;
+};
+
+
/**
* Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them
* (notify, notifyParent) regarding size changes of a list and selection changes across accordion tabs.
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 5efd99b939..3224ac6d9b 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -40,12 +40,12 @@
#include "llmenugl.h"
#include "lltextbox.h"
#include "lltrans.h"
+#include "lluitextutil.h"
// newview
#include "llagent.h"
#include "llgroupactions.h"
#include "llfloaterreg.h"
-#include "lltextutil.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#include "llvoiceclient.h"
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index d25aa37e16..3aa9d75bc0 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -1104,6 +1104,21 @@ void LLIMFloater::closeHiddenIMToasts()
channel->closeHiddenToasts(IMToastMatcher());
}
}
+// static
+void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ const LLSD& payload = notification["payload"];
+ LLUUID session_id = payload["session_id"];
+
+ LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id);
+ if (option == 0 && im_floater != NULL)
+ {
+ im_floater->closeFloater();
+ }
+
+ return;
+}
// static
bool LLIMFloater::isChatMultiTab()
@@ -1176,7 +1191,7 @@ void LLIMFloater::onClickCloseBtn()
{
LLSD payload;
payload["session_id"] = mSessionID;
- LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload);
+ LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
return;
}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index d63246a5cd..fef178e3a2 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -155,6 +155,8 @@ private:
static void closeHiddenIMToasts();
+ static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
+
LLPanelChatControlPanel* mControlPanel;
LLUUID mSessionID;
S32 mLastMessageIndex;
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index f48e7b3966..2d1d401cd4 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -40,11 +40,13 @@
// llcommon
#include "llcommonutils.h"
+// llui
#include "lliconctrl.h"
+#include "lluitextutil.h"
+#include "llcallbacklist.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
-#include "lltextutil.h"
#include "lltrans.h"
////////////////////////////////////////////////////////////////////////////////
@@ -320,6 +322,7 @@ LLInventoryItemsList::Params::Params()
LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p)
: LLFlatListViewEx(p)
, mNeedsRefresh(false)
+, mPrevVisibility(false)
{
// TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView
// but reset to true in all derived classes. This settings might need to
@@ -327,6 +330,8 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p
setCommitOnSelectionChange(true);
setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems"));
+
+ gIdleCallbacks.addFunction(idle, this);
}
// virtual
@@ -344,12 +349,31 @@ void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item
mNeedsRefresh = true;
}
-void LLInventoryItemsList::draw()
+boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb)
{
- LLFlatListViewEx::draw();
- if(mNeedsRefresh)
+ return mRefreshCompleteSignal.connect(cb);
+}
+
+void LLInventoryItemsList::doIdle()
+{
+ bool cur_visibility = getVisible();
+ if(cur_visibility != mPrevVisibility || mNeedsRefresh)
{
refresh();
+
+ mRefreshCompleteSignal(this, LLSD());
+
+ mPrevVisibility = getVisible();
+ }
+}
+
+//static
+void LLInventoryItemsList::idle(void* user_data)
+{
+ LLInventoryItemsList* self = static_cast<LLInventoryItemsList*>(user_data);
+ if ( self )
+ { // Do the real idle
+ self->doIdle();
}
}
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index bc04eb6f5b..60cccc0f4f 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -42,6 +42,7 @@
// newview
#include "llflatlistview.h"
+#include "llviewerinventory.h"
class LLIconCtrl;
class LLTextBox;
@@ -120,6 +121,9 @@ public:
/* Removes item highlight */
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+ /** Get the name of a corresponding inventory item */
+ const std::string& getItemName() const { return mItem->getName(); }
+
virtual ~LLPanelInventoryListItemBase(){}
protected:
@@ -208,14 +212,23 @@ public:
void refreshList(const LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array);
+ boost::signals2::connection setRefreshCompleteCallback(const commit_signal_t::slot_type& cb);
+
/**
- * Let list know items need to be refreshed in next draw()
+ * Let list know items need to be refreshed in next doIdle()
*/
void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
bool getNeedsRefresh(){ return mNeedsRefresh; }
- /*virtual*/ void draw();
+ /**
+ * Idle routine used to refresh the list regardless of the current list
+ * visibility, unlike draw() which is called only for the visible list.
+ * This is needed for example to filter items of the list hidden by closed
+ * accordion tab.
+ */
+ void doIdle(); // Real idle routine
+ static void idle(void* user_data); // static glue to doIdle()
protected:
friend class LLUICtrlFactory;
@@ -225,7 +238,7 @@ protected:
/**
* Refreshes list items, adds new items and removes deleted items.
- * Called from draw() until all new items are added, ,
+ * Called from doIdle() until all new items are added,
* maximum 50 items can be added during single call.
*/
void refresh();
@@ -245,6 +258,10 @@ private:
uuid_vec_t mIDs; // IDs of items that were added in refreshList().
// Will be used in refresh() to determine added and removed ids
bool mNeedsRefresh;
+
+ bool mPrevVisibility;
+
+ commit_signal_t mRefreshCompleteSignal;
};
#endif //LL_LLINVENTORYITEMSLIST_H
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 18bd610dd9..12d5203429 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -169,6 +169,9 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
// Setting list commit callback to monitor currently selected wearable item.
list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
+ // Setting list refresh callback to apply filter on list change.
+ list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onWearableItemsListRefresh, this, _1));
+
// Fetch the new outfit contents.
cat->fetch();
@@ -244,35 +247,9 @@ void LLOutfitsList::performAction(std::string action)
void LLOutfitsList::setFilterSubString(const std::string& string)
{
- mFilterSubString = string;
+ applyFilter(string);
- for (outfits_map_t::iterator
- iter = mOutfitsMap.begin(),
- iter_end = mOutfitsMap.end();
- iter != iter_end; ++iter)
- {
- LLAccordionCtrlTab* tab = iter->second;
- if (tab)
- {
- LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*> (tab->getAccordionView());
- if (list)
- {
- list->setFilterSubString(mFilterSubString);
- }
-
- if(!mFilterSubString.empty())
- {
- //store accordion tab state when filter is not empty
- tab->notifyChildren(LLSD().with("action","store_state"));
- tab->setDisplayChildren(true);
- }
- else
- {
- //restore accordion state after all those accodrion tab manipulations
- tab->notifyChildren(LLSD().with("action","restore_state"));
- }
- }
- }
+ mFilterSubString = string;
}
//////////////////////////////////////////////////////////////////////////
@@ -350,4 +327,102 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI
mSelectedOutfitUUID = category_id;
}
+void LLOutfitsList::onWearableItemsListRefresh(LLUICtrl* ctrl)
+{
+ if (!ctrl || mFilterSubString.empty())
+ return;
+
+ for (outfits_map_t::iterator
+ iter = mOutfitsMap.begin(),
+ iter_end = mOutfitsMap.end();
+ iter != iter_end; ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if (tab) continue;
+
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (list != ctrl) continue;
+
+ std::string title = tab->getTitle();
+ LLStringUtil::toUpper(title);
+
+ std::string cur_filter = mFilterSubString;
+ LLStringUtil::toUpper(cur_filter);
+
+ if (std::string::npos == title.find(cur_filter))
+ {
+ // hide tab if its title doesn't pass filter
+ // and it has no visible items
+ tab->setVisible(list->size() != 0);
+ }
+ else
+ {
+ tab->setTitle(tab->getTitle(), cur_filter);
+ }
+ }
+}
+
+void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
+{
+ for (outfits_map_t::iterator
+ iter = mOutfitsMap.begin(),
+ iter_end = mOutfitsMap.end();
+ iter != iter_end; ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if (!tab) continue;
+
+ bool more_restrictive = mFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, mFilterSubString.size()).compare(mFilterSubString);
+
+ // Restore tab visibility in case of less restrictive filter
+ // to compare it with updated string if it was previously hidden.
+ if (!more_restrictive)
+ {
+ tab->setVisible(TRUE);
+ }
+
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (list)
+ {
+ list->setFilterSubString(new_filter_substring);
+ }
+
+ if(mFilterSubString.empty() && !new_filter_substring.empty())
+ {
+ //store accordion tab state when filter is not empty
+ tab->notifyChildren(LLSD().with("action","store_state"));
+ }
+
+ if (!new_filter_substring.empty())
+ {
+ tab->setDisplayChildren(true);
+
+ std::string title = tab->getTitle();
+ LLStringUtil::toUpper(title);
+
+ std::string cur_filter = new_filter_substring;
+ LLStringUtil::toUpper(cur_filter);
+
+ if (std::string::npos == title.find(cur_filter))
+ {
+ // hide tab if its title doesn't pass filter
+ // and it has no visible items
+ tab->setVisible(list->size() != 0);
+ }
+ else
+ {
+ tab->setTitle(tab->getTitle(), cur_filter);
+ }
+ }
+ else
+ {
+ // restore tab title when filter is empty
+ tab->setTitle(tab->getTitle());
+
+ //restore accordion state after all those accodrion tab manipulations
+ tab->notifyChildren(LLSD().with("action","restore_state"));
+ }
+ }
+}
+
// EOF
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index d86cf5a703..bcb393b12a 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -94,6 +94,17 @@ private:
*/
void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
+ /**
+ * Called upon list refresh event to update tab visibility depending on
+ * the results of applying filter to the title and list items of the tab.
+ */
+ void onWearableItemsListRefresh(LLUICtrl* ctrl);
+
+ /**
+ * Highlights filtered items and hides tabs which haven't passed filter.
+ */
+ void applyFilter(const std::string& new_filter_substring);
+
LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index e8b6c6bfe5..4dd03e04a9 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -38,7 +38,7 @@
#include "llsidetray.h"
#include "llworldmap.h"
#include "llteleporthistorystorage.h"
-#include "lltextutil.h"
+#include "lluitextutil.h"
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index feaf7335c0..daf116d255 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -37,6 +37,8 @@
#include "llavataractions.h"
#include "llagent.h"
+#include "llimview.h"
+#include "llnotificationsutil.h"
#include "llparticipantlist.h"
#include "llspeakers.h"
#include "llviewercontrol.h"
@@ -809,10 +811,43 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(co
LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
if (mgr)
{
+ if (!unmute)
+ {
+ LLSD payload;
+ payload["session_id"] = mgr->getSessionID();
+ payload["excluded_avatar_id"] = excluded_avatar_id;
+ LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
+ return;
+ }
+
mgr->moderateVoiceOtherParticipants(excluded_avatar_id, unmute);
}
}
+// static
+void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 1)
+ {
+ return;
+ }
+
+ const LLSD& payload = notification["payload"];
+ const LLUUID& session_id = payload["session_id"];
+ const LLUUID& excluded_avatar_id = payload["excluded_avatar_id"];
+
+ LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
+ LLIMModel::getInstance()->getSpeakerManager(session_id));
+ if (speaker_manager)
+ {
+ speaker_manager->moderateVoiceOtherParticipants(excluded_avatar_id, false);
+ }
+
+ return;
+}
+
+
bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
{
std::string item = userdata.asString();
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index bbef8baaac..abaf503868 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -216,6 +216,8 @@ class LLParticipantList
* @see moderateVoiceParticipant()
*/
void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute);
+
+ static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
};
/**
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 4b7c7f297b..86e040692c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6474,18 +6474,3 @@ void LLOfferInfo::forceResponse(InventoryOfferResponse response)
LLNotifications::instance().forceResponse(params, response);
}
-static bool confirm_leave_call_callback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- const LLSD& payload = notification["payload"];
- LLUUID session_id = payload["session_id"];
-
- LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id);
- if (option == 0 && im_floater != NULL)
- {
- im_floater->closeFloater();
- }
-
- return false;
-}
-static LLNotificationFunctorRegistration confirm_leave_call_cb("ConfirmLeaveCall", confirm_leave_call_callback);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4f46e34520..cde1e47747 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6139,6 +6139,23 @@ Are you sure you want to leave this call?
<unique/>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmMuteAll"
+ type="alert">
+You have selected to mute all participants in a group call.
+This will also cause all residents that later join the call to be
+muted, even after you have left the call.
+
+Mute everyone?
+ <usetemplate
+ ignoretext="Confirm before I mute all participants in a group call"
+ name="okcancelignore"
+ notext="Ok"
+ yestext="Cancel"/>
+ <unique/>
+ </notification>
+
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
</global>