From b31631934a7caa0fe331cd25e745e8b9c9485798 Mon Sep 17 00:00:00 2001
From: pavelk_productengine <none@none>
Date: Tue, 3 Feb 2015 19:44:25 +0200
Subject: [PATCH] MAINT-4734 (Separate transaction notices from group
 notice/invites)  - added code to sort notifications between tabs: Invites,
 Transactions, System  messages  - made cosmetic changes according to comment
 from 27/Jan/15 in Jira  - added code to show correct number of notifications
 on each tab  - added code to close all notifications on current tab via
 "Delete all" button

---
 indra/newview/CMakeLists.txt                  |   4 +
 indra/newview/llchiclet.cpp                   |   2 +-
 .../newview/llfloaternotificationstabbed.cpp  | 300 +++++++++++++-----
 indra/newview/llfloaternotificationstabbed.h  |  75 +++--
 indra/newview/llnotificationlistitem.cpp      | 196 ++++++++++++
 indra/newview/llnotificationlistitem.h        | 136 ++++++++
 indra/newview/llnotificationlistview.cpp      |  44 +++
 indra/newview/llnotificationlistview.h        |  49 +++
 indra/newview/llsyswellitem.cpp               |  83 +----
 indra/newview/llsyswellitem.h                 |  52 ---
 .../xui/en/floater_notifications_tabbed.xml   |  53 +++-
 .../xui/en/panel_notification_tabbed_item.xml |  16 +-
 .../xui/en/widgets/notification_list_view.xml |  18 ++
 13 files changed, 777 insertions(+), 251 deletions(-)
 create mode 100644 indra/newview/llnotificationlistitem.cpp
 create mode 100644 indra/newview/llnotificationlistitem.h
 create mode 100644 indra/newview/llnotificationlistview.cpp
 create mode 100644 indra/newview/llnotificationlistview.h
 create mode 100644 indra/newview/skins/default/xui/en/widgets/notification_list_view.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b17811d6448..4bf92f0f4e4 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -397,6 +397,8 @@ set(viewer_SOURCE_FILES
     llnotificationgrouphandler.cpp
     llnotificationhandlerutil.cpp
     llnotificationhinthandler.cpp
+    llnotificationlistitem.cpp
+    llnotificationlistview.cpp
     llnotificationmanager.cpp
     llnotificationofferhandler.cpp
     llnotificationscripthandler.cpp
@@ -999,6 +1001,8 @@ set(viewer_HEADER_FILES
     llnavigationbar.h
     llnetmap.h
     llnotificationhandler.h
+    llnotificationlistitem.h
+    llnotificationlistview.h
     llnotificationmanager.h
     llnotificationstorage.h
     lloutfitslist.h
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 6435c934b98..33cb0551b4a 100755
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -228,7 +228,7 @@ bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNo
 	if (   (notification->getName() == "ScriptDialog") // special case for scripts
 		// if there is no toast window for the notification, filter it
 		//|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
-        || (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID()))
+        || (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName()))
 		)
 	{
 		displayNotification = false;
diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp
index bdc10cfa63e..b05ea6aa384 100644
--- a/indra/newview/llfloaternotificationstabbed.cpp
+++ b/indra/newview/llfloaternotificationstabbed.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llfloaternotificationstabbed.cpp
- * @brief                                    // TODO
+ * @brief                                  
  * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
@@ -40,8 +40,12 @@
 //---------------------------------------------------------------------------------
 LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
     mChannel(NULL),
-    mMessageList(NULL),
     mSysWellChiclet(NULL),
+    mInviteMessageList(NULL),
+    mTransactionMessageList(NULL),
+    mSystemMessageList(NULL),
+    mNotificationsSeparator(NULL),
+    mNotificationsTabContainer(NULL),
     NOTIFICATION_TABBED_ANCHOR_NAME("notification_well_panel"),
     IM_WELL_ANCHOR_NAME("im_well_panel"),
     mIsReshapedByUser(false)
@@ -49,19 +53,27 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
 {
 	setOverlapsScreenChannel(true);
     mNotificationUpdates.reset(new NotificationTabbedChannel(this));
+    mNotificationsSeparator = new LLNotificationSeparator();
 }
 
 //---------------------------------------------------------------------------------
 BOOL LLFloaterNotificationsTabbed::postBuild()
 {
-    mMessageList = getChild<LLFlatListView>("notification_list");
+    mInviteMessageList = getChild<LLNotificationListView>("invite_notification_list");
+    mTransactionMessageList = getChild<LLNotificationListView>("transaction_notification_list");
+    mSystemMessageList = getChild<LLNotificationListView>("system_notification_list");
+    mNotificationsSeparator->initTaggedList(LLNotificationListItem::getInviteTypes(), mInviteMessageList);
+    mNotificationsSeparator->initTaggedList(LLNotificationListItem::getTransactionTypes(), mTransactionMessageList);
+    mNotificationsSeparator->initUnTaggedList(mSystemMessageList);
+    mNotificationsTabContainer = getChild<LLTabContainer>("notifications_tab_container");
+
+    mDeleteAllBtn = getChild<LLButton>("delete_all_button");
+    mDeleteAllBtn->setClickedCallback(boost::bind(&LLFloaterNotificationsTabbed::onClickDeleteAllBtn,this));
 
     // get a corresponding channel
     initChannel();
     BOOL rv = LLTransientDockableFloater::postBuild();
     
-    //LLNotificationWellWindow::postBuild()
-    //--------------------------
     setTitle(getString("title_notification_tabbed_window"));
 	return rv;
 }
@@ -101,15 +113,16 @@ LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed()
 }
 
 //---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::removeItemByID(const LLUUID& id)
+void LLFloaterNotificationsTabbed::removeItemByID(const LLUUID& id, std::string type)
 {
-    if(mMessageList->removeItemByValue(id))
+    if(mNotificationsSeparator->removeItemByID(type, id))
     {
         if (NULL != mSysWellChiclet)
         {
             mSysWellChiclet->updateWidget(isWindowEmpty());
         }
         reshapeWindow();
+        updateNotificationCounters();
     }
     else
     {
@@ -125,9 +138,9 @@ void LLFloaterNotificationsTabbed::removeItemByID(const LLUUID& id)
 }
 
 //---------------------------------------------------------------------------------
-LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id)
+LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id, std::string type)
 {
-    return mMessageList->getItemByValue(id);
+    return mNotificationsSeparator->findItemByID(type, id);
 }
 
 //---------------------------------------------------------------------------------
@@ -141,8 +154,6 @@ void LLFloaterNotificationsTabbed::initChannel()
         LL_WARNS() << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << LL_ENDL;
     }
 
-    //LLSysWellWindow::initChannel();
-    //---------------------------------------------------------------------------------
     if(mChannel)
     {
         mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2));
@@ -152,14 +163,11 @@ void LLFloaterNotificationsTabbed::initChannel()
 //---------------------------------------------------------------------------------
 void LLFloaterNotificationsTabbed::setVisible(BOOL visible)
 {
-    //LLNotificationWellWindow::setVisible
-    //--------------------------
     if (visible)
     {
         // when Notification channel is cleared, storable toasts will be added into the list.
         clearScreenChannels();
     }
-    //--------------------------
     if (visible)
     {
         if (NULL == getDockControl() && getDockTongue().notNull())
@@ -171,7 +179,7 @@ void LLFloaterNotificationsTabbed::setVisible(BOOL visible)
     }
 
     // do not show empty window
-    if (NULL == mMessageList || isWindowEmpty()) visible = FALSE;
+    if (NULL == mNotificationsSeparator || isWindowEmpty()) visible = FALSE;
 
     LLTransientDockableFloater::setVisible(visible);
 
@@ -202,26 +210,26 @@ void LLFloaterNotificationsTabbed::reshapeWindow()
 {
     // save difference between floater height and the list height to take it into account while calculating new window height
     // it includes height from floater top to list top and from floater bottom and list bottom
-    static S32 parent_list_delta_height = getRect().getHeight() - mMessageList->getRect().getHeight();
+    //static S32 parent_list_delta_height = getRect().getHeight() - mInviteMessageList->getRect().getHeight();
 
-    if (!mIsReshapedByUser) // Don't reshape Well window, if it ever was reshaped by user. See EXT-5715.
-    {
-        S32 notif_list_height = mMessageList->getItemsRect().getHeight() + 2 * mMessageList->getBorderWidth();
+    //if (!mIsReshapedByUser) // Don't reshape Well window, if it ever was reshaped by user. See EXT-5715.
+    //{
+    //    S32 notif_list_height = mInviteMessageList->getItemsRect().getHeight() + 2 * mInviteMessageList->getBorderWidth();
 
-        LLRect curRect = getRect();
+    //    LLRect curRect = getRect();
 
-        S32 new_window_height = notif_list_height + parent_list_delta_height;
+    //    S32 new_window_height = notif_list_height + parent_list_delta_height;
 
-        if (new_window_height > MAX_WINDOW_HEIGHT)
-        {
-            new_window_height = MAX_WINDOW_HEIGHT;
-        }
-        S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH	: curRect.getWidth();
+    //    if (new_window_height > MAX_WINDOW_HEIGHT)
+    //    {
+    //        new_window_height = MAX_WINDOW_HEIGHT;
+    //    }
+    //    S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH	: curRect.getWidth();
 
-        curRect.setLeftTopAndSize(curRect.mLeft, curRect.mTop, newWidth, new_window_height);
-        reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
-        setRect(curRect);
-    }
+    //    curRect.setLeftTopAndSize(curRect.mLeft, curRect.mTop, newWidth, new_window_height);
+    //    reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
+    //    setRect(curRect);
+    //}
 
     // update notification channel state
     // update on a window reshape is important only when a window is visible and docked
@@ -234,7 +242,7 @@ void LLFloaterNotificationsTabbed::reshapeWindow()
 //---------------------------------------------------------------------------------
 bool LLFloaterNotificationsTabbed::isWindowEmpty()
 {
-    return mMessageList->size() == 0;
+    return mNotificationsSeparator->size() == 0;
 }
 
 LLFloaterNotificationsTabbed::NotificationTabbedChannel::NotificationTabbedChannel(LLFloaterNotificationsTabbed* notifications_tabbed_window)
@@ -246,74 +254,98 @@ LLFloaterNotificationsTabbed::NotificationTabbedChannel::NotificationTabbedChann
     connectToChannel("Offer");
 }
 
-/*
-LLFloaterNotificationsTabbed::LLNotificationWellWindow(const LLSD& key)
-    :	LLSysWellWindow(key)
-{
-    mNotificationUpdates.reset(new NotificationTabbedChannel(this));
-}
-*/
-
 // static
 LLFloaterNotificationsTabbed* LLFloaterNotificationsTabbed::getInstance(const LLSD& key /*= LLSD()*/)
 {
     return LLFloaterReg::getTypedInstance<LLFloaterNotificationsTabbed>("notification_well_window", key);
 }
 
+void LLFloaterNotificationsTabbed::updateNotificationCounter(S32 panelIndex, S32 counterValue, std::string stringName)
+{
+    LLStringUtil::format_map_t string_args;
+    string_args["[COUNT]"] = llformat("%d", counterValue);
+    std::string label = getString(stringName, string_args);
+    mNotificationsTabContainer->setPanelTitle(panelIndex, label);
+}
+
+void LLFloaterNotificationsTabbed::updateNotificationCounters()
+{
+    updateNotificationCounter(0, mSystemMessageList->size(), "system_tab_title");
+    updateNotificationCounter(1, mTransactionMessageList->size(), "transactions_tab_title");
+    updateNotificationCounter(2, mInviteMessageList->size(), "invitations_tab_title");
+}
+
 //---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::addItem(LLNotificationTabbedItem::Params p)
+void LLFloaterNotificationsTabbed::addItem(LLNotificationListItem::Params p)
 {
-    LLSD value = p.notification_id;
     // do not add clones
-    if( mMessageList->getItemByValue(value))
+    if (mNotificationsSeparator->findItemByID(p.notification_name, p.notification_id))
         return;
-
-    LLNotificationTabbedItem* new_item = new LLNotificationTabbedItem(p);
-    if (mMessageList->addItem(new_item, value, ADD_TOP))
+    LLNotificationListItem* new_item = LLNotificationListItem::create(p);
+    if (new_item == NULL)
+    {
+        return;
+    }
+    if (mNotificationsSeparator->addItem(new_item->getNotificationName(), new_item))
     {
         mSysWellChiclet->updateWidget(isWindowEmpty());
         reshapeWindow();
+        updateNotificationCounters();
         new_item->setOnItemCloseCallback(boost::bind(&LLFloaterNotificationsTabbed::onItemClose, this, _1));
         new_item->setOnItemClickCallback(boost::bind(&LLFloaterNotificationsTabbed::onItemClick, this, _1));
     }
     else
     {
         LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id
-            << ", title: " << p.title
+            << ", title: " << new_item->getTitle()
             << LL_ENDL;
 
         new_item->die();
     }
 }
 
-//---------------------------------------------------------------------------------
 void LLFloaterNotificationsTabbed::closeAll()
 {
     // Need to clear notification channel, to add storable toasts into the list.
     clearScreenChannels();
-    std::vector<LLPanel*> items;
-    mMessageList->getItems(items);
-    for (std::vector<LLPanel*>::iterator
-        iter = items.begin(),
-        iter_end = items.end();
-    iter != iter_end; ++iter)
+
+    std::vector<LLNotificationListItem*> items;
+    mNotificationsSeparator->getItems(items);
+    std::vector<LLNotificationListItem*>::iterator iter = items.begin();
+    for (; iter != items.end(); ++iter)
     {
-        LLNotificationTabbedItem* sys_well_item = dynamic_cast<LLNotificationTabbedItem*>(*iter);
-        if (sys_well_item)
-            onItemClose(sys_well_item);
+        onItemClose(*iter);
     }
 }
 
-//////////////////////////////////////////////////////////////////////////
-// PRIVATE METHODS
-//void LLFloaterNotificationsTabbed::initChannel() 
-//{
-//    LLFloaterNotificationsTabbed::initChannel();
-//    if(mChannel)
-//    {
-//        mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2));
-//    }
-//}
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::closeAllOnCurrentTab()
+{
+    // Need to clear notification channel, to add storable toasts into the list.
+    clearScreenChannels();
+    std::vector<LLPanel*> items;
+    switch (mNotificationsTabContainer->getCurrentPanelIndex())
+    {
+    case 0:
+        mSystemMessageList->getItems(items);
+        break;
+    case 1:
+        mTransactionMessageList->getItems(items);
+        break;
+    case 2:
+        mInviteMessageList->getItems(items);
+        break;
+    default:
+        return;
+    }
+    std::vector<LLPanel*>::iterator iter = items.begin();
+    for (; iter != items.end(); ++iter)
+    {
+        LLNotificationListItem* notify_item = dynamic_cast<LLNotificationListItem*>(*iter);
+        if (notify_item)
+            onItemClose(notify_item);
+    }
+}
 
 //---------------------------------------------------------------------------------
 void LLFloaterNotificationsTabbed::clearScreenChannels()
@@ -334,27 +366,27 @@ void LLFloaterNotificationsTabbed::clearScreenChannels()
 //---------------------------------------------------------------------------------
 void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id)
 {
-    LLNotificationTabbedItem::Params p;	
+    LLNotificationListItem::Params p;	
     p.notification_id = id;
     p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
-    LLNotificationsUI::LLToast* toast = mChannel->getToastByNotificationID(id);
-    LLSD payload = toast->getNotification()->getPayload();
-    LLDate time_stamp = toast->getNotification()->getDate();
+    LLNotificationPtr notify = mChannel->getToastByNotificationID(id)->getNotification();
+    LLSD payload = notify->getPayload();
+    p.notification_name = notify->getName();
     p.group_id = payload["group_id"];
     p.sender = payload["name"].asString();
-    p.time_stamp = time_stamp;
+    p.time_stamp = notify->getDate();
     addItem(p);
 }
 
 //---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onItemClick(LLNotificationTabbedItem* item)
+void LLFloaterNotificationsTabbed::onItemClick(LLNotificationListItem* item)
 {
     LLUUID id = item->getID();
     LLFloaterReg::showInstance("inspect_toast", id);
 }
 
 //---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onItemClose(LLNotificationTabbedItem* item)
+void LLFloaterNotificationsTabbed::onItemClose(LLNotificationListItem* item)
 {
     LLUUID id = item->getID();
 
@@ -366,12 +398,130 @@ void LLFloaterNotificationsTabbed::onItemClose(LLNotificationTabbedItem* item)
     else
     {
         // removeItemByID() should be called one time for each item to remove it from notification well
-        removeItemByID(id);
+        removeItemByID(id, item->getNotificationName());
     }
 
 }
 
 void LLFloaterNotificationsTabbed::onAdd( LLNotificationPtr notify )
 {
-    removeItemByID(notify->getID());
+    removeItemByID(notify->getID(), notify->getName());
+}
+
+void LLFloaterNotificationsTabbed::onClickDeleteAllBtn()
+{
+    closeAllOnCurrentTab();
+}
+
+void LLNotificationSeparator::initTaggedList(const std::string& tag, LLNotificationListView* list)
+{
+    mNotificationListMap.insert(notification_list_map_t::value_type(tag, list));
+    mNotificationLists.push_back(list);
+}
+
+void LLNotificationSeparator::initTaggedList(const std::set<std::string>& tags, LLNotificationListView* list)
+{
+    std::set<std::string>::const_iterator it = tags.begin();
+    for(;it != tags.end();it++)
+    {
+        initTaggedList(*it, list);
+    }
+}
+
+void LLNotificationSeparator::initUnTaggedList(LLNotificationListView* list)
+{
+    mUnTaggedList = list;
+}
+
+bool LLNotificationSeparator::addItem(std::string& tag, LLNotificationListItem* item)
+{
+    notification_list_map_t::iterator it = mNotificationListMap.find(tag);
+    if (it != mNotificationListMap.end())
+    {
+        return it->second->addNotification(item);
+    }
+    else if (mUnTaggedList != NULL)
+    {
+        return mUnTaggedList->addNotification(item);
+    }
+    return false;
+}
+
+bool LLNotificationSeparator::removeItemByID(std::string& tag, const LLUUID& id)
+{
+    notification_list_map_t::iterator it = mNotificationListMap.find(tag);
+    if (it != mNotificationListMap.end())
+    {
+        return it->second->removeItemByValue(id);
+    }
+    else if (mUnTaggedList != NULL)
+    {
+        return mUnTaggedList->removeItemByValue(id);
+    }
+    return false;
+}
+
+U32 LLNotificationSeparator::size() const
+{
+    U32 size = 0;
+    notification_list_list_t::const_iterator it = mNotificationLists.begin();
+    for (; it != mNotificationLists.end(); it++)
+    {
+        size = size + (*it)->size();
+    }
+    if (mUnTaggedList != NULL)
+    {
+        size = size + mUnTaggedList->size();
+    }
+    return size;
 }
+
+LLPanel* LLNotificationSeparator::findItemByID(std::string& tag, const LLUUID& id)
+{
+    notification_list_map_t::iterator it = mNotificationListMap.find(tag);
+    if (it != mNotificationListMap.end())
+    {
+        return it->second->getItemByValue(id);
+    }
+    else if (mUnTaggedList != NULL)
+    {
+        return mUnTaggedList->getItemByValue(id);
+    }
+
+    return NULL;    
+}
+
+//static
+void LLNotificationSeparator::getItemsFromList(std::vector<LLNotificationListItem*>& items, LLNotificationListView* list)
+{
+    std::vector<LLPanel*> list_items;
+    list->getItems(list_items);
+    std::vector<LLPanel*>::iterator it = list_items.begin();
+    for (; it != list_items.end(); ++it)
+    {
+        LLNotificationListItem* notify_item = dynamic_cast<LLNotificationListItem*>(*it);
+        if (notify_item)
+            items.push_back(notify_item);
+    }
+}
+
+void LLNotificationSeparator::getItems(std::vector<LLNotificationListItem*>& items) const
+{
+    items.clear();
+    notification_list_list_t::const_iterator lists_it = mNotificationLists.begin();
+    for (; lists_it != mNotificationLists.end(); lists_it++)
+    {
+        getItemsFromList(items, *lists_it);
+    }
+    if (mUnTaggedList != NULL)
+    {
+        getItemsFromList(items, mUnTaggedList);
+    }
+}
+
+LLNotificationSeparator::LLNotificationSeparator()
+    : mUnTaggedList(NULL)
+{}
+
+LLNotificationSeparator::~LLNotificationSeparator()
+{}
diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h
index 1fd60826cbb..36eee2f8669 100644
--- a/indra/newview/llfloaternotificationstabbed.h
+++ b/indra/newview/llfloaternotificationstabbed.h
@@ -1,6 +1,6 @@
 /** 
  * @file llfloaternotificationstabbed.h
- * @brief                                    // TODO
+ * @brief                                  
  *
  * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -32,6 +32,8 @@
 #include "llscreenchannel.h"
 #include "llsyswellitem.h"
 #include "lltransientdockablefloater.h"
+#include "llnotificationlistview.h"
+#include "lltabcontainer.h"
 
 class LLAvatarName;
 class LLChiclet;
@@ -40,6 +42,29 @@ class LLIMChiclet;
 class LLScriptChiclet;
 class LLSysWellChiclet;
 
+class LLNotificationSeparator
+{
+public:
+    LLNotificationSeparator();
+    ~LLNotificationSeparator();
+    void initTaggedList(const std::string& tag, LLNotificationListView* list);
+    void initTaggedList(const std::set<std::string>& tags, LLNotificationListView* list);
+    void initUnTaggedList(LLNotificationListView* list);
+    bool addItem(std::string& tag, LLNotificationListItem* item);
+    LLPanel* findItemByID(std::string& tag, const LLUUID& id);
+    bool removeItemByID(std::string& tag, const LLUUID& id);
+    void getItems(std::vector<LLNotificationListItem*>& items) const;
+    U32 size() const;
+private:
+    static void getItemsFromList(std::vector<LLNotificationListItem*>& items, LLNotificationListView* list);
+
+    typedef std::map<std::string, LLNotificationListView*> notification_list_map_t;
+    notification_list_map_t mNotificationListMap;
+    typedef std::list<LLNotificationListView*> notification_list_list_t;
+    notification_list_list_t mNotificationLists;
+    LLNotificationListView* mUnTaggedList;
+};
+
 class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
 {
 public:
@@ -54,8 +79,10 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
     bool isWindowEmpty();
 
     // Operating with items
-    void removeItemByID(const LLUUID& id);
-    LLPanel * findItemByID(const LLUUID& id);
+    void removeItemByID(const LLUUID& id, std::string type);
+    LLPanel * findItemByID(const LLUUID& id, std::string type);
+    void updateNotificationCounters();
+    void updateNotificationCounter(S32 panelIndex, S32 counterValue, std::string stringName);
 
     // Operating with outfit
     virtual void setVisible(BOOL visible);
@@ -67,14 +94,18 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
     /*virtual*/ void	handleReshape(const LLRect& rect, bool by_user);
 
     void onStartUpToastClick(S32 x, S32 y, MASK mask);
+    /*virtual*/ void onAdd(LLNotificationPtr notify);
 
     void setSysWellChiclet(LLSysWellChiclet* chiclet);
+    void closeAll();
+
+    static LLFloaterNotificationsTabbed* getInstance(const LLSD& key = LLSD());
 
     // size constants for the window and for its elements
     static const S32 MAX_WINDOW_HEIGHT		= 200;
     static const S32 MIN_WINDOW_WIDTH		= 318;
 
-protected:
+private:
     // init Window's channel
     virtual void initChannel();
 
@@ -86,7 +117,6 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
 
     // pointer to a corresponding channel's instance
     LLNotificationsUI::LLScreenChannel*	mChannel;
-    LLFlatListView*	mMessageList;
 
     /**
 	 * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
@@ -95,25 +125,12 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
 
     bool mIsReshapedByUser;
 
-public:
-    static LLFloaterNotificationsTabbed* getInstance(const LLSD& key = LLSD());
-
-    /*virtual*/ //BOOL postBuild();
-    /*virtual*/ //void setVisible(BOOL visible);
-    /*virtual*/ void onAdd(LLNotificationPtr notify);
-    // Operating with items
-    void addItem(LLNotificationTabbedItem::Params p);
-
-    // Closes all notifications and removes them from the Notification Well
-    void closeAll();
-
-protected:
     struct NotificationTabbedChannel : public LLNotificationChannel
     {
         NotificationTabbedChannel(LLFloaterNotificationsTabbed*);
         void onDelete(LLNotificationPtr notify)
         {
-            mNotificationsTabbedWindow->removeItemByID(notify->getID());
+            mNotificationsTabbedWindow->removeItemByID(notify->getID(), notify->getName());
         } 
 
         LLFloaterNotificationsTabbed* mNotificationsTabbedWindow;
@@ -122,19 +139,29 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
     LLNotificationChannelPtr mNotificationUpdates;
     virtual const std::string& getAnchorViewName() { return NOTIFICATION_TABBED_ANCHOR_NAME; }
 
-private:
     // init Window's channel
     // void initChannel();
     void clearScreenChannels();
+    // Operating with items
+    void addItem(LLNotificationListItem::Params p);
 
-    void onStoreToast(LLPanel* info_panel, LLUUID id);
+    // Closes all notifications and removes them from the Notification Well
+    void closeAllOnCurrentTab();
 
+    void onStoreToast(LLPanel* info_panel, LLUUID id);
+    void onClickDeleteAllBtn();
     // Handlers
-    void onItemClick(LLNotificationTabbedItem* item);
-    void onItemClose(LLNotificationTabbedItem* item);
-
+    void onItemClick(LLNotificationListItem* item);
+    void onItemClose(LLNotificationListItem* item);
     // ID of a toast loaded by user (by clicking notification well item)
     LLUUID mLoadedToastId;
+
+    LLNotificationListView*	mInviteMessageList;
+    LLNotificationListView*	mTransactionMessageList;
+    LLNotificationListView*	mSystemMessageList;
+    LLNotificationSeparator* mNotificationsSeparator;
+    LLTabContainer* mNotificationsTabContainer;
+    LLButton*	mDeleteAllBtn;
 };
 
 #endif // LL_FLOATERNOTIFICATIONSTABBED_H
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
new file mode 100644
index 00000000000..a55c7b85419
--- /dev/null
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -0,0 +1,196 @@
+/** 
+ * @file llnotificationlistitem.cpp
+ * @brief                                    // TODO
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llnotificationlistitem.h"
+
+#include "llwindow.h"
+#include "v4color.h"
+#include "lltrans.h"
+#include "lluicolortable.h"
+
+LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p),
+    mTitleBox(NULL),
+    mCloseBtn(NULL),
+    mSenderBox(NULL)
+{
+    buildFromFile( "panel_notification_tabbed_item.xml");
+
+    mTitleBox = getChild<LLTextBox>("GroupName_NoticeTitle");
+    mTimeBox = getChild<LLTextBox>("Time_Box");
+    mCloseBtn = getChild<LLButton>("close_btn");
+    mSenderBox = getChild<LLTextBox>("Sender_Resident");
+
+    mTitleBox->setValue(p.title);
+    mTimeBox->setValue(buildNotificationDate(p.time_stamp));
+    mSenderBox->setVisible(FALSE);
+
+    mCloseBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCloseBtn,this));
+
+    mID = p.notification_id;
+    mNotificationName = p.notification_name;
+}
+
+LLNotificationListItem::~LLNotificationListItem()
+{
+}
+
+//static
+std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_stamp)
+{
+    std::string timeStr = "[" + LLTrans::getString("LTimeMthNum") + "]/["
+        +LLTrans::getString("LTimeDay")+"]/["
+        +LLTrans::getString("LTimeYear")+"] ["
+        +LLTrans::getString("LTimeHour")+"]:["
+        +LLTrans::getString("LTimeMin")+"]";
+
+    LLSD substitution;
+    substitution["datetime"] = time_stamp;
+    LLStringUtil::format(timeStr, substitution);
+    return timeStr;
+}
+
+//---------------------------------------------------------------------------------
+//void LLNotificationTabbedItem::setTitle( std::string title )
+//{
+//    mTitleBox->setValue(title);
+//}
+
+void LLNotificationListItem::onClickCloseBtn()
+{
+    mOnItemClose(this);
+}
+
+BOOL LLNotificationListItem::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+    BOOL res = LLPanel::handleMouseDown(x, y, mask);
+    if(!mCloseBtn->getRect().pointInRect(x, y))
+    //if(!mCloseBtn->getRect().pointInRect(x, y))
+    //if(!mCloseBtn->getLocalRect().pointInRect(x, y))
+        mOnItemClick(this);
+
+    return res;
+}
+
+void LLNotificationListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+    //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemSelected" ));
+}
+
+void LLNotificationListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+    //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
+}
+
+//static
+LLNotificationListItem* LLNotificationListItem::create(const Params& p)
+{
+    if (LLNotificationListItem::getInviteTypes().count(p.notification_name))
+    {
+        return new LLInviteNotificationListItem(p);
+    }
+    else if (LLNotificationListItem::getTransactionTypes().count(p.notification_name))
+    {
+        return new LLTransactionNotificationListItem(p);
+    }
+    return new LLSystemNotificationListItem(p);
+}
+
+//static
+std::set<std::string> LLNotificationListItem::getInviteTypes() 
+{
+    return LLInviteNotificationListItem::getTypes();
+}
+
+//static
+std::set<std::string> LLNotificationListItem::getTransactionTypes()
+{
+    return LLTransactionNotificationListItem::getTypes();
+}
+
+std::set<std::string> LLInviteNotificationListItem::getTypes()
+{
+    std::set<std::string> types;
+    types.insert("JoinGroup");
+    return types;
+}
+
+std::set<std::string> LLTransactionNotificationListItem::getTypes()
+{
+    std::set<std::string> types;
+    types.insert("PaymentReceived");
+    types.insert("PaymentSent");
+    return types;
+}
+
+std::set<std::string> LLSystemNotificationListItem::getTypes()
+{
+    std::set<std::string> types;
+    types.insert("AddPrimitiveFailure");
+    types.insert("AddToNavMeshNoCopy");
+    types.insert("AssetServerTimeoutObjReturn");
+    types.insert("AvatarEjected");
+    types.insert("AutoUnmuteByIM");
+    types.insert("AutoUnmuteByInventory");
+    types.insert("AutoUnmuteByMoney");
+    types.insert("BuyInventoryFailedNoMoney");
+    types.insert("DeactivatedGesturesTrigger");
+    types.insert("DeedFailedNoPermToDeedForGroup");
+    types.insert("WhyAreYouTryingToWearShrubbery");
+    types.insert("YouDiedAndGotTPHome");
+    types.insert("YouFrozeAvatar");
+
+    types.insert("OfferCallingCard");
+    //ExpireExplanation
+    return types;
+}
+
+LLInviteNotificationListItem::LLInviteNotificationListItem(const Params& p)
+    : LLNotificationListItem(p)
+{
+    mGroupIcon = getChild<LLIconCtrl>("group_icon_small");
+    mGroupIcon->setValue(p.group_id);
+    mGroupID = p.group_id;
+    if (!p.sender.empty())
+    {
+        LLStringUtil::format_map_t string_args;
+        string_args["[SENDER_RESIDENT]"] = llformat("%s", p.sender);
+        std::string sender_text = getString("sender_resident_text", string_args);
+        mSenderBox->setValue(sender_text);
+        mSenderBox->setVisible(TRUE);
+    }
+}
+
+LLTransactionNotificationListItem::LLTransactionNotificationListItem(const Params& p)
+    : LLNotificationListItem(p)
+{}
+
+LLSystemNotificationListItem::LLSystemNotificationListItem(const Params& p)
+    :LLNotificationListItem(p)
+{}
+
diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h
new file mode 100644
index 00000000000..bc77d873a4d
--- /dev/null
+++ b/indra/newview/llnotificationlistitem.h
@@ -0,0 +1,136 @@
+/** 
+ * @file llnotificationlistitem.h
+ * @brief                                    // TODO
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNOTIFICATIONLISTITEM_H
+#define LL_LLNOTIFICATIONLISTITEM_H
+
+#include "llpanel.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "lliconctrl.h"
+
+#include "llgroupmgr.h"
+
+#include <string>
+
+class LLNotificationListItem : public LLPanel
+{
+public:
+    struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
+    {
+        LLUUID        	notification_id;
+        LLUUID          group_id;
+        std::string		notification_name;
+        std::string		title;
+        std::string		sender;
+        LLDate time_stamp;
+        Params()        {};
+    };
+
+    static LLNotificationListItem* create(const Params& p);
+
+    static std::set<std::string> getInviteTypes();
+    static std::set<std::string> getTransactionTypes();
+
+    // title
+    void setTitle( std::string title );
+
+    // get item's ID
+    LLUUID getID() { return mID; }
+    std::string getTitle() { return mTitle; }
+    std::string getNotificationName() { return mNotificationName; }
+
+    // handlers
+    virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+    virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+    virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+    //callbacks
+    typedef boost::function<void (LLNotificationListItem* item)> item_callback_t;
+    typedef boost::signals2::signal<void (LLNotificationListItem* item)> item_signal_t;
+    item_signal_t mOnItemClose;	
+    item_signal_t mOnItemClick;	
+    boost::signals2::connection setOnItemCloseCallback(item_callback_t cb) { return mOnItemClose.connect(cb); }
+    boost::signals2::connection setOnItemClickCallback(item_callback_t cb) { return mOnItemClick.connect(cb); }
+
+protected:
+    LLNotificationListItem(const Params& p);
+    virtual	~LLNotificationListItem();
+
+    static std::string buildNotificationDate(const LLDate&);
+    void onClickCloseBtn();
+
+    LLTextBox*	mTitleBox;
+    LLTextBox*  mTimeBox;
+    LLButton*	mCloseBtn;
+    LLUUID		mID;
+    std::string mTitle;
+    std::string mNotificationName;
+    LLTextBox*	mSenderBox;
+};
+
+class LLInviteNotificationListItem : public LLNotificationListItem
+{
+public:
+    //void setGroupID(const LLUUID& group_id);
+    //void setGroupIconID(const LLUUID& group_icon_id);
+    //void setGroupName(const std::string& group_name);
+    static std::set<std::string> getTypes();
+private:
+    friend class LLNotificationListItem;
+    LLInviteNotificationListItem(const Params& p);
+    LLInviteNotificationListItem(const LLInviteNotificationListItem &);
+    LLInviteNotificationListItem & operator=(LLInviteNotificationListItem &);
+
+    LLIconCtrl* mGroupIcon;
+    LLUUID		mGroupID;
+};
+
+class LLTransactionNotificationListItem : public LLNotificationListItem
+{
+public:
+    static std::set<std::string> getTypes();
+private:
+    friend class LLNotificationListItem;
+    LLTransactionNotificationListItem(const Params& p);
+    LLTransactionNotificationListItem(const LLTransactionNotificationListItem &);
+    LLTransactionNotificationListItem & operator=(LLTransactionNotificationListItem &);
+};
+
+class LLSystemNotificationListItem : public LLNotificationListItem
+{
+public:
+    static std::set<std::string> getTypes();
+private:
+    friend class LLNotificationListItem;
+    LLSystemNotificationListItem(const Params& p);
+    LLSystemNotificationListItem(const LLSystemNotificationListItem &);
+    LLSystemNotificationListItem & operator=(LLSystemNotificationListItem &);
+};
+
+#endif // LL_LLNOTIFICATIONLISTITEM_H
+
+
diff --git a/indra/newview/llnotificationlistview.cpp b/indra/newview/llnotificationlistview.cpp
new file mode 100644
index 00000000000..8690f185e9b
--- /dev/null
+++ b/indra/newview/llnotificationlistview.cpp
@@ -0,0 +1,44 @@
+/** 
+ * @file llnotificationlistview.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llnotificationlistview.h"
+
+static const LLDefaultChildRegistry::Register<LLNotificationListView> notification_list_view("notification_list_view");
+
+LLNotificationListView::LLNotificationListView(const Params& p)
+    : LLFlatListView(p)
+{}
+
+LLNotificationListView::~LLNotificationListView()
+{}
+
+bool LLNotificationListView::addNotification(LLNotificationListItem * item)
+{
+    return LLFlatListView::addItem(item, item->getID(), ADD_TOP);
+}
+
+//EOF
diff --git a/indra/newview/llnotificationlistview.h b/indra/newview/llnotificationlistview.h
new file mode 100644
index 00000000000..9329826faff
--- /dev/null
+++ b/indra/newview/llnotificationlistview.h
@@ -0,0 +1,49 @@
+/** 
+ * @file llflatlistview.h
+ * @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNOTIFICATIONLISTVIEW_H
+#define LL_LLNOTIFICATIONLISTVIEW_H
+
+#include "llflatlistview.h"
+#include "llnotificationlistitem.h"
+
+/**
+ * Notification list
+ */
+class LLNotificationListView : public LLFlatListView
+{
+	LOG_CLASS(LLNotificationListView);
+public:
+    struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> {};
+
+    LLNotificationListView(const Params& p);
+    ~LLNotificationListView();
+    friend class LLUICtrlFactory;
+
+    virtual bool addNotification(LLNotificationListItem * item);
+};
+
+#endif
\ No newline at end of file
diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp
index bc8333d5fcd..31ff9823995 100755
--- a/indra/newview/llsyswellitem.cpp
+++ b/indra/newview/llsyswellitem.cpp
@@ -89,85 +89,4 @@ void LLSysWellItem::onMouseLeave(S32 x, S32 y, MASK mask)
 	setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
 }
 
-//---------------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------------
-LLNotificationTabbedItem::LLNotificationTabbedItem(const Params& p) : LLPanel(p),
-    mTitle(NULL),
-    mSender(NULL),
-    mCloseBtn(NULL)
-{
-    buildFromFile( "panel_notification_tabbed_item.xml");
-
-    mTitle = getChild<LLTextBox>("GroupName_NoticeTitle");
-    mSender = getChild<LLTextBox>("Sender_Resident");
-    mTimeBox = getChild<LLTextBox>("Time_Box");
-    mGroupIcon = getChild<LLIconCtrl>("group_icon_small");
-    mCloseBtn = getChild<LLButton>("close_btn");
-
-    mTitle->setValue(p.title);
-    mSender->setValue("Sender: " + p.sender);
-    mTimeBox->setValue(buildNotificationDate(p.time_stamp));
-    mGroupIcon->setValue(p.group_id);
-
-    mCloseBtn->setClickedCallback(boost::bind(&LLNotificationTabbedItem::onClickCloseBtn,this));
-
-    mID = p.notification_id;
-}
-
-//---------------------------------------------------------------------------------
-LLNotificationTabbedItem::~LLNotificationTabbedItem()
-{
-}
-
-//---------------------------------------------------------------------------------
-//static
-std::string LLNotificationTabbedItem::buildNotificationDate(const LLDate& time_stamp)
-{
-    std::string timeStr = "[" + LLTrans::getString("LTimeMthNum") + "]/["
-        +LLTrans::getString("LTimeDay")+"]/["
-        +LLTrans::getString("LTimeYear")+"] ["
-        +LLTrans::getString("LTimeHour")+"]:["
-        +LLTrans::getString("LTimeMin")+"]";
-
-    LLSD substitution;
-    substitution["datetime"] = time_stamp;
-    LLStringUtil::format(timeStr, substitution);
-    return timeStr;
-}
-
-//---------------------------------------------------------------------------------
-void LLNotificationTabbedItem::setTitle( std::string title )
-{
-    mTitle->setValue(title);
-}
-
-//---------------------------------------------------------------------------------
-void LLNotificationTabbedItem::onClickCloseBtn()
-{
-    mOnItemClose(this);
-}
-
-//---------------------------------------------------------------------------------
-BOOL LLNotificationTabbedItem::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-    BOOL res = LLPanel::handleMouseDown(x, y, mask);
-    if(!mCloseBtn->getRect().pointInRect(x, y))
-    //if(!mCloseBtn->getRect().pointInRect(x, y))
-    //if(!mCloseBtn->getLocalRect().pointInRect(x, y))
-        mOnItemClick(this);
-
-    return res;
-}
-
-//---------------------------------------------------------------------------------
-void LLNotificationTabbedItem::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-    //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemSelected" ));
-}
-
-//---------------------------------------------------------------------------------
-void LLNotificationTabbedItem::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-    //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
-}
+//---------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h
index 4379b8dc224..8763caa4672 100755
--- a/indra/newview/llsyswellitem.h
+++ b/indra/newview/llsyswellitem.h
@@ -78,58 +78,6 @@ class LLSysWellItem : public LLPanel
 	LLUUID		mID;
 };
 
-class LLNotificationTabbedItem : public LLPanel
-{
-public:
-    struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
-    {
-        LLUUID        	notification_id;
-        LLUUID          group_id;
-        std::string		title;
-        std::string		sender;
-        LLDate time_stamp;
-        Params()        {};
-    };
-
-
-    LLNotificationTabbedItem(const Params& p);
-    virtual	~LLNotificationTabbedItem();
-
-    // title
-    void setTitle( std::string title );
-    void setGroupID(const LLUUID& group_id);
-    void setGroupIconID(const LLUUID& group_icon_id);
-    void setGroupName(const std::string& group_name);
-
-    // get item's ID
-    LLUUID getID() { return mID; }
-
-    // handlers
-    virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-    virtual void onMouseEnter(S32 x, S32 y, MASK mask);
-    virtual void onMouseLeave(S32 x, S32 y, MASK mask);
-
-    //callbacks
-    typedef boost::function<void (LLNotificationTabbedItem* item)> item_callback_t;
-    typedef boost::signals2::signal<void (LLNotificationTabbedItem* item)> item_signal_t;
-    item_signal_t mOnItemClose;	
-    item_signal_t mOnItemClick;	
-    boost::signals2::connection setOnItemCloseCallback(item_callback_t cb) { return mOnItemClose.connect(cb); }
-    boost::signals2::connection setOnItemClickCallback(item_callback_t cb) { return mOnItemClick.connect(cb); }
-
-private:
-    static std::string buildNotificationDate(const LLDate&);
-    void onClickCloseBtn();
-
-    LLTextBox*	mTitle;
-    LLTextBox*	mSender;
-    LLTextBox*  mTimeBox;
-    LLIconCtrl* mGroupIcon;
-    LLButton*	mCloseBtn;
-    LLUUID		mID;
-    LLUUID		mGroupID;
-};
-
 #endif // LL_LLSYSWELLITEM_H
 
 
diff --git a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
index b6277070560..6162bc99b29 100644
--- a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
+++ b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
@@ -19,9 +19,22 @@
  save_visibility="true"
  single_instance="true"
 >
+  <floater.string
+    name="system_tab_title">
+    System ([COUNT])
+  </floater.string>
+  <floater.string
+    name="transactions_tab_title">
+    Transactions ([COUNT])
+  </floater.string>
+  <floater.string
+    name="invitations_tab_title">
+    Invitations ([COUNT])
+  </floater.string>
+
   <string
    name="title_notification_tabbed_window">
-    NOTIFICATIONS TABBED
+    NOTIFICATIONS
   </string>
   <layout_stack width="336" height="550" enabled="true" orientation="vertical" name="TabButtonsStack" follows="left|top|right|bottom">
   <layout_panel width="336" height="550" enabled="true" name="TabButtonsLayoutPanel">
@@ -35,35 +48,53 @@
      width="336"
      height="491"
      mouse_opaque="true"
-     name="NotificationsTab">
+     name="notifications_tab_container">
       <panel
        border="true"
        bevel_style="none"
        follows="left|top|right|bottom"
-       label="System (2)"
+       label="System (0)"
        layout="topleft"
-       name="SystemNotificationsTab">        
+       name="system_notification_list_tab">
+        <notification_list_view
+          color="FloaterDefaultBackgroundColor"
+          follows="all"
+          layout="topleft"
+          name="system_notification_list"
+          left="0"
+          top="5"
+          height="0"
+          width="330"/>
       </panel>
       <panel
        border="true"
        bevel_style="none"
        follows="left|top|right|bottom"
-       label="Transactions (15)"
+       label="Transactions (0)"
        layout="topleft"
        name="TransactionNotificationsTab">
+        <notification_list_view
+          color="FloaterDefaultBackgroundColor"
+          follows="all"
+          layout="topleft"
+          name="transaction_notification_list"
+          left="0"
+          top="5"
+          height="0"
+          width="330"/>
       </panel>
       <panel
        border="true"
        bevel_style="none"
        follows="left|top|right|bottom"
-       label="Invites (2)"
+       label="Invitations (0)"
        layout="topleft"
        name="InviteNotificationsTab">
-        <flat_list_view
+        <notification_list_view
           color="FloaterDefaultBackgroundColor"
           follows="all"
           layout="topleft"
-          name="notification_list"
+          name="invite_notification_list"
           left="0"
           top="5"
           height="0"
@@ -73,15 +104,15 @@
     
     <layout_stack width="336" height="26" enabled="true" orientation="horizontal"  follows="left|right" name="ButtonsStack">
       <layout_panel width="336" height="30" enabled="true" orientation="horizontal" name="CondenseAllButtonPanel">
-        <button width="93" height="21" left="2" label="Condense All" name="CondenseAllButton">
+        <button width="93" height="21" left="2" label="Collapse all" name="CondenseAllButton">
         </button>
       </layout_panel>
       <layout_panel width="336" height="30" enabled="true" orientation="horizontal" name="GapLayoutPanel">
-        <panel width="90" height="21" left="2" label="Condense All" border="false" name="GapPanel">
+        <panel width="90" height="21" left="2" label="Gap Panel" border="false" name="GapPanel">
         </panel>
       </layout_panel>
       <layout_panel width="336" height="30" enabled="true" orientation="horizontal" name="DeleteAllButtonPanel">
-        <button width="93" height="21" left="2" label="Delete All" name="DeleteAllButton">
+        <button width="93" height="21" left="2" label="Delete all" name="delete_all_button">
         </button>
       </layout_panel>
     </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml b/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml
index bc4f90858b6..603a3312e0d 100644
--- a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml
@@ -2,8 +2,8 @@
 <!-- All our XML is utf-8 encoded. -->
 <panel
   translate="false"
-  name="sys_well_item"
-  title="sys_well_item"
+  name="panel_notification_tabbed_item"
+  title="panel_notification_tabbed_item"
   visible="true"
   top="0"
   left="0"
@@ -15,6 +15,10 @@
   background_opaque="false"
   background_visible="true"
   bg_alpha_color="SysWellItemUnselected" >
+  <panel.string
+    name="sender_resident_text">
+    Sender: "[SENDER_RESIDENT]"
+  </panel.string>
 
   <panel border="true" top="0" left="3" width="327" height="44" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="GroupNameNoticeTitlePanel">
     <layout_stack top="0" left="0" width="325" height="50" orientation="horizontal" follows="left|top|right|bottom" name="HorizontalStack">
@@ -24,16 +28,16 @@
       <layout_panel width="260" height="50" orientation="horizontal" follows="left|top|right|bottom" name="LayoutPanel">
         <panel border="false" top="0" width="260" height="38" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="MainInfoBlockPanel">
           <panel border="false" top="0" left="0" width="260" height="19" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="GroupNameNoticeTitlePanel">
-            <text allow_scroll="false" font="SansSerifLarge" top="2" left="0" width="267" height="17" layout="topleft" follows="right|left" text_color="White"
+            <text allow_scroll="false" font="SansSerifSmall" top="6" left="0" width="245" height="12" layout="topleft" follows="right|left" text_color="White"
               use_ellipses="true" word_wrap="true" mouse_opaque="false" name="GroupName_NoticeTitle" >
-              Group Name:Notice Title
+              Group Name:Notice Title N o t i c e T i t l e N o t i c e T i t l e N o t i c e T i t l e N oticeTitle
             </text>
-            <icon top="0" right="-1" width="21" height="21" image_name="Icon_Attachment_Small" follows="right" mouse_opaque="true" name="icon_attachment_small" tool_tip="Attachment"/>
+            <icon top="0" left="242" width="21" height="21" image_name="Icon_Attachment_Small" follows="right" mouse_opaque="true" name="icon_attachment_small" tool_tip="Attachment"/>
           </panel>
           <panel border="false" top="23" left="0" width="260" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="SenderAndTimePanel" height="15">
             <text allow_scroll="false" font="SansSerifSmall" top="0" left="0" width="250" height="13"    layout="topleft"    follows="right|left"
               use_ellipses="true" word_wrap="true" mouse_opaque="false" name="Sender_Resident" >
-              Sender.Resident
+              Sender:Resident
             </text>
             <text allow_scroll="false" font="SansSerifSmall" top="0" width="95" height="13" follows="right" halign="right" layout="topleft" left_pad="5"
               name="Time_Box" right="-5" value="2014/12/24 23:30" />
diff --git a/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml b/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml
new file mode 100644
index 00000000000..150225af27e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<notification_list_view
+ allow_select="false"
+ color="PanelFocusBackgroundColor"
+ item_pad="0"
+ keep_one_selected="false"
+ multi_select="false"
+ opaque="true">
+  <flat_list_view
+    color="FloaterDefaultBackgroundColor"
+    follows="all"
+    layout="topleft"
+    name="notification_list"
+    left="1"
+    top="20"
+    height="0"
+    width="318"/>
+</notification_list_view>
\ No newline at end of file
-- 
GitLab