summaryrefslogtreecommitdiff
path: root/indra/newview/llfloaternotificationstabbed.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llfloaternotificationstabbed.cpp
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/newview/llfloaternotificationstabbed.cpp')
-rw-r--r--indra/newview/llfloaternotificationstabbed.cpp1152
1 files changed, 576 insertions, 576 deletions
diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp
index 81505582d1..6e793a9291 100644
--- a/indra/newview/llfloaternotificationstabbed.cpp
+++ b/indra/newview/llfloaternotificationstabbed.cpp
@@ -1,576 +1,576 @@
-/**
- * @file llfloaternotificationstabbed.cpp
- * @brief
- * $LicenseInfo:firstyear=2015&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 "llfloaternotificationstabbed.h"
-
-#include "llchiclet.h"
-#include "llchicletbar.h"
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llnotificationmanager.h"
-#include "llnotificationsutil.h"
-#include "llscriptfloater.h"
-#include "llspeakers.h"
-#include "lltoastpanel.h"
-#include "lltoastnotifypanel.h"
-
-//---------------------------------------------------------------------------------
-LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LLTransientDockableFloater(NULL, true, key),
- mChannel(NULL),
- mSysWellChiclet(NULL),
- mGroupInviteMessageList(NULL),
- mGroupNoticeMessageList(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)
-
-{
- setOverlapsScreenChannel(true);
- mNotificationUpdates.reset(new NotificationTabbedChannel(this));
- mNotificationsSeparator = new LLNotificationSeparator();
-}
-
-//---------------------------------------------------------------------------------
-bool LLFloaterNotificationsTabbed::postBuild()
-{
- mGroupInviteMessageList = getChild<LLNotificationListView>("group_invite_notification_list");
- mGroupNoticeMessageList = getChild<LLNotificationListView>("group_notice_notification_list");
- mTransactionMessageList = getChild<LLNotificationListView>("transaction_notification_list");
- mSystemMessageList = getChild<LLNotificationListView>("system_notification_list");
- mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupInviteTypes(), mGroupInviteMessageList);
- mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupNoticeTypes(), mGroupNoticeMessageList);
- 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));
-
- mCollapseAllBtn = getChild<LLButton>("collapse_all_button");
- mCollapseAllBtn->setClickedCallback(boost::bind(&LLFloaterNotificationsTabbed::onClickCollapseAllBtn,this));
-
- // get a corresponding channel
- initChannel();
- bool rv = LLTransientDockableFloater::postBuild();
-
- setTitle(getString("title_notification_tabbed_window"));
- return rv;
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::setMinimized(bool minimize)
-{
- LLTransientDockableFloater::setMinimized(minimize);
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::handleReshape(const LLRect& rect, bool by_user)
-{
- mIsReshapedByUser |= by_user; // mark floater that it is reshaped by user
- LLTransientDockableFloater::handleReshape(rect, by_user);
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onStartUpToastClick(S32 x, S32 y, MASK mask)
-{
- // just set floater visible. Screen channels will be cleared.
- setVisible(true);
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::setSysWellChiclet(LLSysWellChiclet* chiclet)
-{
- mSysWellChiclet = chiclet;
- if(NULL != mSysWellChiclet)
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
-}
-
-//---------------------------------------------------------------------------------
-LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed()
-{
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::removeItemByID(const LLUUID& id, std::string type)
-{
- if(mNotificationsSeparator->removeItemByID(type, id))
- {
- if (NULL != mSysWellChiclet)
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
- reshapeWindow();
- updateNotificationCounters();
- }
- else
- {
- LL_WARNS() << "Unable to remove notification from the list, ID: " << id
- << LL_ENDL;
- }
-
- // hide chiclet window if there are no items left
- if(isWindowEmpty())
- {
- setVisible(false);
- }
-}
-
-//---------------------------------------------------------------------------------
-LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id, std::string type)
-{
- return mNotificationsSeparator->findItemByID(type, id);
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::initChannel()
-{
- LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
- LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
- mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
- if(NULL == mChannel)
- {
- LL_WARNS() << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << LL_ENDL;
- }
-
- if(mChannel)
- {
- mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2));
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::setVisible(bool visible)
-{
- if (visible)
- {
- // when Notification channel is cleared, storable toasts will be added into the list.
- clearScreenChannels();
- }
- if (visible)
- {
- if (NULL == getDockControl() && getDockTongue().notNull())
- {
- setDockControl(new LLDockControl(
- LLChicletBar::getInstance()->getChild<LLView>(getAnchorViewName()), this,
- getDockTongue(), LLDockControl::BOTTOM));
- }
- }
-
- // do not show empty window
- if (NULL == mNotificationsSeparator || isWindowEmpty()) visible = false;
-
- LLTransientDockableFloater::setVisible(visible);
-
- // update notification channel state
- initChannel(); // make sure the channel still exists
- if(mChannel)
- {
- mChannel->updateShowToastsState();
- mChannel->redrawToasts();
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::setDocked(bool docked, bool pop_on_undock)
-{
- LLTransientDockableFloater::setDocked(docked, pop_on_undock);
-
- // update notification channel state
- if(mChannel)
- {
- mChannel->updateShowToastsState();
- mChannel->redrawToasts();
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::reshapeWindow()
-{
- // update notification channel state
- // update on a window reshape is important only when a window is visible and docked
- if(mChannel && getVisible() && isDocked())
- {
- mChannel->updateShowToastsState();
- }
-}
-
-//---------------------------------------------------------------------------------
-bool LLFloaterNotificationsTabbed::isWindowEmpty()
-{
- return mNotificationsSeparator->size() == 0;
-}
-
-//---------------------------------------------------------------------------------
-LLFloaterNotificationsTabbed::NotificationTabbedChannel::NotificationTabbedChannel(LLFloaterNotificationsTabbed* notifications_tabbed_window)
- : LLNotificationChannel(LLNotificationChannel::Params().name(notifications_tabbed_window->getPathname())),
- mNotificationsTabbedWindow(notifications_tabbed_window)
-{
- connectToChannel("Notifications");
- connectToChannel("Group Notifications");
- connectToChannel("Offer");
-}
-
-// 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, mGroupInviteMessageList->size(), "group_invitations_tab_title");
- updateNotificationCounter(3, mGroupNoticeMessageList->size(), "group_notices_tab_title");
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::addItem(LLNotificationListItem::Params p)
-{
- // do not add clones
- if (mNotificationsSeparator->findItemByID(p.notification_name, p.notification_id))
- return;
- 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: " << 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<LLNotificationListItem*> items;
- mNotificationsSeparator->getItems(items);
- std::vector<LLNotificationListItem*>::iterator iter = items.begin();
- for (; iter != items.end(); ++iter)
- {
- onItemClose(*iter);
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::getAllItemsOnCurrentTab(std::vector<LLPanel*>& items) const
-{
- switch (mNotificationsTabContainer->getCurrentPanelIndex())
- {
- case 0:
- mSystemMessageList->getItems(items);
- break;
- case 1:
- mTransactionMessageList->getItems(items);
- break;
- case 2:
- mGroupInviteMessageList->getItems(items);
- break;
- case 3:
- mGroupNoticeMessageList->getItems(items);
- break;
- default:
- break;
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::closeAllOnCurrentTab()
-{
- // Need to clear notification channel, to add storable toasts into the list.
- clearScreenChannels();
- std::vector<LLPanel*> items;
- getAllItemsOnCurrentTab(items);
- 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::collapseAllOnCurrentTab()
-{
- std::vector<LLPanel*> items;
- getAllItemsOnCurrentTab(items);
- std::vector<LLPanel*>::iterator iter = items.begin();
- for (; iter != items.end(); ++iter)
- {
- LLNotificationListItem* notify_item = dynamic_cast<LLNotificationListItem*>(*iter);
- if (notify_item)
- notify_item->setExpanded(false);
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::clearScreenChannels()
-{
- // 1 - remove StartUp toast and channel if present
- if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
- {
- LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
- }
-
- // 2 - remove toasts in Notification channel
- if(mChannel)
- {
- mChannel->removeAndStoreAllStorableToasts();
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id)
-{
- LLNotificationListItem::Params p;
- p.notification_id = id;
- p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
- LLNotificationPtr notify = mChannel->getToastByNotificationID(id)->getNotification();
- LLSD payload = notify->getPayload();
- p.notification_name = notify->getName();
- p.transaction_id = payload["transaction_id"];
- p.group_id = payload["group_id"];
- p.fee = payload["fee"];
- p.use_offline_cap = payload["use_offline_cap"].asInteger();
- p.subject = payload["subject"].asString();
- p.message = payload["message"].asString();
- p.sender = payload["sender_name"].asString();
- p.time_stamp = notify->getDate();
- p.received_time = payload["received_time"].asDate();
- p.paid_from_id = payload["from_id"];
- p.paid_to_id = payload["dest_id"];
- p.inventory_offer = payload["inventory_offer"];
- p.notification_priority = notify->getPriority();
- addItem(p);
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onItemClick(LLNotificationListItem* item)
-{
- LLUUID id = item->getID();
- if (item->showPopup())
- {
- LLFloaterReg::showInstance("inspect_toast", id);
- }
- else
- {
- item->setExpanded(true);
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onItemClose(LLNotificationListItem* item)
-{
- LLUUID id = item->getID();
-
- if(mChannel)
- {
- // removeItemByID() is invoked from killToastByNotificationID() and item will removed;
- mChannel->killToastByNotificationID(id);
- }
- else
- {
- // removeItemByID() should be called one time for each item to remove it from notification well
- removeItemByID(id, item->getNotificationName());
- }
-
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onAdd( LLNotificationPtr notify )
-{
- removeItemByID(notify->getID(), notify->getName());
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onClickDeleteAllBtn()
-{
- closeAllOnCurrentTab();
-}
-
-//---------------------------------------------------------------------------------
-void LLFloaterNotificationsTabbed::onClickCollapseAllBtn()
-{
- collapseAllOnCurrentTab();
-}
-
-//---------------------------------------------------------------------------------
-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()
-{}
+/**
+ * @file llfloaternotificationstabbed.cpp
+ * @brief
+ * $LicenseInfo:firstyear=2015&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 "llfloaternotificationstabbed.h"
+
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
+#include "llnotificationmanager.h"
+#include "llnotificationsutil.h"
+#include "llscriptfloater.h"
+#include "llspeakers.h"
+#include "lltoastpanel.h"
+#include "lltoastnotifypanel.h"
+
+//---------------------------------------------------------------------------------
+LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LLTransientDockableFloater(NULL, true, key),
+ mChannel(NULL),
+ mSysWellChiclet(NULL),
+ mGroupInviteMessageList(NULL),
+ mGroupNoticeMessageList(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)
+
+{
+ setOverlapsScreenChannel(true);
+ mNotificationUpdates.reset(new NotificationTabbedChannel(this));
+ mNotificationsSeparator = new LLNotificationSeparator();
+}
+
+//---------------------------------------------------------------------------------
+bool LLFloaterNotificationsTabbed::postBuild()
+{
+ mGroupInviteMessageList = getChild<LLNotificationListView>("group_invite_notification_list");
+ mGroupNoticeMessageList = getChild<LLNotificationListView>("group_notice_notification_list");
+ mTransactionMessageList = getChild<LLNotificationListView>("transaction_notification_list");
+ mSystemMessageList = getChild<LLNotificationListView>("system_notification_list");
+ mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupInviteTypes(), mGroupInviteMessageList);
+ mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupNoticeTypes(), mGroupNoticeMessageList);
+ 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));
+
+ mCollapseAllBtn = getChild<LLButton>("collapse_all_button");
+ mCollapseAllBtn->setClickedCallback(boost::bind(&LLFloaterNotificationsTabbed::onClickCollapseAllBtn,this));
+
+ // get a corresponding channel
+ initChannel();
+ bool rv = LLTransientDockableFloater::postBuild();
+
+ setTitle(getString("title_notification_tabbed_window"));
+ return rv;
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::setMinimized(bool minimize)
+{
+ LLTransientDockableFloater::setMinimized(minimize);
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::handleReshape(const LLRect& rect, bool by_user)
+{
+ mIsReshapedByUser |= by_user; // mark floater that it is reshaped by user
+ LLTransientDockableFloater::handleReshape(rect, by_user);
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onStartUpToastClick(S32 x, S32 y, MASK mask)
+{
+ // just set floater visible. Screen channels will be cleared.
+ setVisible(true);
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::setSysWellChiclet(LLSysWellChiclet* chiclet)
+{
+ mSysWellChiclet = chiclet;
+ if(NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
+}
+
+//---------------------------------------------------------------------------------
+LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed()
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::removeItemByID(const LLUUID& id, std::string type)
+{
+ if(mNotificationsSeparator->removeItemByID(type, id))
+ {
+ if (NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
+ reshapeWindow();
+ updateNotificationCounters();
+ }
+ else
+ {
+ LL_WARNS() << "Unable to remove notification from the list, ID: " << id
+ << LL_ENDL;
+ }
+
+ // hide chiclet window if there are no items left
+ if(isWindowEmpty())
+ {
+ setVisible(false);
+ }
+}
+
+//---------------------------------------------------------------------------------
+LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id, std::string type)
+{
+ return mNotificationsSeparator->findItemByID(type, id);
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::initChannel()
+{
+ LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID);
+ mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+ if(NULL == mChannel)
+ {
+ LL_WARNS() << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << LL_ENDL;
+ }
+
+ if(mChannel)
+ {
+ mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2));
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::setVisible(bool visible)
+{
+ if (visible)
+ {
+ // when Notification channel is cleared, storable toasts will be added into the list.
+ clearScreenChannels();
+ }
+ if (visible)
+ {
+ if (NULL == getDockControl() && getDockTongue().notNull())
+ {
+ setDockControl(new LLDockControl(
+ LLChicletBar::getInstance()->getChild<LLView>(getAnchorViewName()), this,
+ getDockTongue(), LLDockControl::BOTTOM));
+ }
+ }
+
+ // do not show empty window
+ if (NULL == mNotificationsSeparator || isWindowEmpty()) visible = false;
+
+ LLTransientDockableFloater::setVisible(visible);
+
+ // update notification channel state
+ initChannel(); // make sure the channel still exists
+ if(mChannel)
+ {
+ mChannel->updateShowToastsState();
+ mChannel->redrawToasts();
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::setDocked(bool docked, bool pop_on_undock)
+{
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
+
+ // update notification channel state
+ if(mChannel)
+ {
+ mChannel->updateShowToastsState();
+ mChannel->redrawToasts();
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::reshapeWindow()
+{
+ // update notification channel state
+ // update on a window reshape is important only when a window is visible and docked
+ if(mChannel && getVisible() && isDocked())
+ {
+ mChannel->updateShowToastsState();
+ }
+}
+
+//---------------------------------------------------------------------------------
+bool LLFloaterNotificationsTabbed::isWindowEmpty()
+{
+ return mNotificationsSeparator->size() == 0;
+}
+
+//---------------------------------------------------------------------------------
+LLFloaterNotificationsTabbed::NotificationTabbedChannel::NotificationTabbedChannel(LLFloaterNotificationsTabbed* notifications_tabbed_window)
+ : LLNotificationChannel(LLNotificationChannel::Params().name(notifications_tabbed_window->getPathname())),
+ mNotificationsTabbedWindow(notifications_tabbed_window)
+{
+ connectToChannel("Notifications");
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+}
+
+// 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, mGroupInviteMessageList->size(), "group_invitations_tab_title");
+ updateNotificationCounter(3, mGroupNoticeMessageList->size(), "group_notices_tab_title");
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::addItem(LLNotificationListItem::Params p)
+{
+ // do not add clones
+ if (mNotificationsSeparator->findItemByID(p.notification_name, p.notification_id))
+ return;
+ 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: " << 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<LLNotificationListItem*> items;
+ mNotificationsSeparator->getItems(items);
+ std::vector<LLNotificationListItem*>::iterator iter = items.begin();
+ for (; iter != items.end(); ++iter)
+ {
+ onItemClose(*iter);
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::getAllItemsOnCurrentTab(std::vector<LLPanel*>& items) const
+{
+ switch (mNotificationsTabContainer->getCurrentPanelIndex())
+ {
+ case 0:
+ mSystemMessageList->getItems(items);
+ break;
+ case 1:
+ mTransactionMessageList->getItems(items);
+ break;
+ case 2:
+ mGroupInviteMessageList->getItems(items);
+ break;
+ case 3:
+ mGroupNoticeMessageList->getItems(items);
+ break;
+ default:
+ break;
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::closeAllOnCurrentTab()
+{
+ // Need to clear notification channel, to add storable toasts into the list.
+ clearScreenChannels();
+ std::vector<LLPanel*> items;
+ getAllItemsOnCurrentTab(items);
+ 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::collapseAllOnCurrentTab()
+{
+ std::vector<LLPanel*> items;
+ getAllItemsOnCurrentTab(items);
+ std::vector<LLPanel*>::iterator iter = items.begin();
+ for (; iter != items.end(); ++iter)
+ {
+ LLNotificationListItem* notify_item = dynamic_cast<LLNotificationListItem*>(*iter);
+ if (notify_item)
+ notify_item->setExpanded(false);
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::clearScreenChannels()
+{
+ // 1 - remove StartUp toast and channel if present
+ if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
+ {
+ LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
+ }
+
+ // 2 - remove toasts in Notification channel
+ if(mChannel)
+ {
+ mChannel->removeAndStoreAllStorableToasts();
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id)
+{
+ LLNotificationListItem::Params p;
+ p.notification_id = id;
+ p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
+ LLNotificationPtr notify = mChannel->getToastByNotificationID(id)->getNotification();
+ LLSD payload = notify->getPayload();
+ p.notification_name = notify->getName();
+ p.transaction_id = payload["transaction_id"];
+ p.group_id = payload["group_id"];
+ p.fee = payload["fee"];
+ p.use_offline_cap = payload["use_offline_cap"].asInteger();
+ p.subject = payload["subject"].asString();
+ p.message = payload["message"].asString();
+ p.sender = payload["sender_name"].asString();
+ p.time_stamp = notify->getDate();
+ p.received_time = payload["received_time"].asDate();
+ p.paid_from_id = payload["from_id"];
+ p.paid_to_id = payload["dest_id"];
+ p.inventory_offer = payload["inventory_offer"];
+ p.notification_priority = notify->getPriority();
+ addItem(p);
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onItemClick(LLNotificationListItem* item)
+{
+ LLUUID id = item->getID();
+ if (item->showPopup())
+ {
+ LLFloaterReg::showInstance("inspect_toast", id);
+ }
+ else
+ {
+ item->setExpanded(true);
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onItemClose(LLNotificationListItem* item)
+{
+ LLUUID id = item->getID();
+
+ if(mChannel)
+ {
+ // removeItemByID() is invoked from killToastByNotificationID() and item will removed;
+ mChannel->killToastByNotificationID(id);
+ }
+ else
+ {
+ // removeItemByID() should be called one time for each item to remove it from notification well
+ removeItemByID(id, item->getNotificationName());
+ }
+
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onAdd( LLNotificationPtr notify )
+{
+ removeItemByID(notify->getID(), notify->getName());
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onClickDeleteAllBtn()
+{
+ closeAllOnCurrentTab();
+}
+
+//---------------------------------------------------------------------------------
+void LLFloaterNotificationsTabbed::onClickCollapseAllBtn()
+{
+ collapseAllOnCurrentTab();
+}
+
+//---------------------------------------------------------------------------------
+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()
+{}