merge changes for 3.8.6-release

master
Oz Linden 2015-10-29 10:11:57 -04:00
commit 848c1909c5
30 changed files with 2087 additions and 217 deletions

View File

@ -509,3 +509,4 @@ d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release
60572f718879f786f6bc8b5c9373ebebf4693078 3.8.3-release
27e3cf444c4cc645884960a61325a9ee0e9a2d0f 3.8.4-release
e821ef17c6edea4a59997719d8ba416d8c16e143 3.8.5-release
5a5bd148943bfb46cf2ff2ccf376c42dee93d19b 3.8.6-release

View File

@ -274,6 +274,7 @@ set(viewer_SOURCE_FILES
llfloatermodeluploadbase.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloateroutbox.cpp
@ -408,6 +409,8 @@ set(viewer_SOURCE_FILES
llnotificationgrouphandler.cpp
llnotificationhandlerutil.cpp
llnotificationhinthandler.cpp
llnotificationlistitem.cpp
llnotificationlistview.cpp
llnotificationmanager.cpp
llnotificationofferhandler.cpp
llnotificationscripthandler.cpp
@ -893,6 +896,7 @@ set(viewer_HEADER_FILES
llfloatermodeluploadbase.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloateroutbox.h
@ -1020,6 +1024,8 @@ set(viewer_HEADER_FILES
llnavigationbar.h
llnetmap.h
llnotificationhandler.h
llnotificationlistitem.h
llnotificationlistview.h
llnotificationmanager.h
llnotificationstorage.h
lloutfitslist.h

View File

@ -1 +1 @@
3.8.6
3.8.7

View File

@ -311,6 +311,7 @@ bool LLAvatarIconCtrl::updateFromCache()
else
{
LLIconCtrl::setValue(mDefaultIconName);
return false;
}
return true;

View File

@ -35,6 +35,7 @@
#include "llviewerwindow.h"
#include "llrootview.h"
#include "llsyswellwindow.h"
#include "llfloaternotificationstabbed.h"
#include "llfloaterreg.h"
#include <algorithm>
@ -131,7 +132,7 @@ void LLChannelManager::onLoginCompleted()
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4));
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));

View File

@ -35,6 +35,7 @@
#include "llscriptfloater.h"
#include "llsingleton.h"
#include "llsyswellwindow.h"
#include "llfloaternotificationstabbed.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
@ -165,7 +166,7 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
mNotificationChannel.reset(new ChicletNotificationChannel(this));
// ensure that notification well window exists, to synchronously
// handle toast add/delete events.
LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this);
}
void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
@ -173,7 +174,7 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
std::string action = user_data.asString();
if("close all" == action)
{
LLNotificationWellWindow::getInstance()->closeAll();
LLFloaterNotificationsTabbed::getInstance()->closeAll();
LLIMWellWindow::getInstance()->closeAll();
}
}
@ -224,7 +225,8 @@ bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNo
bool displayNotification;
if ( (notification->getName() == "ScriptDialog") // special case for scripts
// if there is no toast window for the notification, filter it
|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
//|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
|| (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName()))
)
{
displayNotification = false;

View File

@ -31,6 +31,7 @@
#include "lllayoutstack.h"
#include "llpaneltopinfobar.h"
#include "llsyswellwindow.h"
#include "llfloaternotificationstabbed.h"
namespace
{
@ -49,7 +50,7 @@ BOOL LLChicletBar::postBuild()
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty());
LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));

View File

@ -0,0 +1,575 @@
/**
* @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.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()
{}

View File

@ -0,0 +1,174 @@
/**
* @file llfloaternotificationstabbed.h
* @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$
*/
#ifndef LL_FLOATERNOTIFICATIONSTABBED_H
#define LL_FLOATERNOTIFICATIONSTABBED_H
#include "llimview.h"
#include "llnotifications.h"
#include "llscreenchannel.h"
#include "llsyswellitem.h"
#include "lltransientdockablefloater.h"
#include "llnotificationlistview.h"
#include "lltabcontainer.h"
class LLAvatarName;
class LLChiclet;
class LLFlatListView;
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:
LOG_CLASS(LLFloaterNotificationsTabbed);
LLFloaterNotificationsTabbed(const LLSD& key);
virtual ~LLFloaterNotificationsTabbed();
BOOL postBuild();
// other interface functions
// check is window empty
bool isWindowEmpty();
// Operating with items
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);
/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
// override LLFloater's minimization according to EXT-1216
/*virtual*/ void setMinimized(BOOL minimize);
/*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;
private:
// init Window's channel
virtual void initChannel();
const std::string NOTIFICATION_TABBED_ANCHOR_NAME;
const std::string IM_WELL_ANCHOR_NAME;
//virtual const std::string& getAnchorViewName() = 0;
void reshapeWindow();
// pointer to a corresponding channel's instance
LLNotificationsUI::LLScreenChannel* mChannel;
/**
* Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
*/
LLSysWellChiclet* mSysWellChiclet;
bool mIsReshapedByUser;
struct NotificationTabbedChannel : public LLNotificationChannel
{
NotificationTabbedChannel(LLFloaterNotificationsTabbed*);
void onDelete(LLNotificationPtr notify)
{
mNotificationsTabbedWindow->removeItemByID(notify->getID(), notify->getName());
}
LLFloaterNotificationsTabbed* mNotificationsTabbedWindow;
};
LLNotificationChannelPtr mNotificationUpdates;
virtual const std::string& getAnchorViewName() { return NOTIFICATION_TABBED_ANCHOR_NAME; }
// init Window's channel
// void initChannel();
void clearScreenChannels();
// Operating with items
void addItem(LLNotificationListItem::Params p);
void getAllItemsOnCurrentTab(std::vector<LLPanel*>& items) const;
// Closes all notifications and removes them from the Notification Well
void closeAllOnCurrentTab();
void collapseAllOnCurrentTab();
void onStoreToast(LLPanel* info_panel, LLUUID id);
void onClickDeleteAllBtn();
void onClickCollapseAllBtn();
// Handlers
void onItemClick(LLNotificationListItem* item);
void onItemClose(LLNotificationListItem* item);
// ID of a toast loaded by user (by clicking notification well item)
LLUUID mLoadedToastId;
LLNotificationListView* mGroupInviteMessageList;
LLNotificationListView* mGroupNoticeMessageList;
LLNotificationListView* mTransactionMessageList;
LLNotificationListView* mSystemMessageList;
LLNotificationSeparator* mNotificationsSeparator;
LLTabContainer* mNotificationsTabContainer;
LLButton* mDeleteAllBtn;
LLButton* mCollapseAllBtn;
};
#endif // LL_FLOATERNOTIFICATIONSTABBED_H

View File

@ -0,0 +1,645 @@
/**
* @file llnotificationlistitem.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 "llnotificationlistitem.h"
#include "llagent.h"
#include "llgroupactions.h"
#include "llinventoryicon.h"
#include "llwindow.h"
#include "v4color.h"
#include "lltrans.h"
#include "lluicolortable.h"
#include "message.h"
#include "llnotificationsutil.h"
#include <boost/regex.hpp>
LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p),
mParams(p),
mTitleBox(NULL),
mExpandBtn(NULL),
mCondenseBtn(NULL),
mCloseBtn(NULL),
mCondensedViewPanel(NULL),
mExpandedViewPanel(NULL),
mCondensedHeight(0),
mExpandedHeight(0),
mExpandedHeightResize(0),
mExpanded(false)
{
mNotificationName = p.notification_name;
}
BOOL LLNotificationListItem::postBuild()
{
BOOL rv = LLPanel::postBuild();
mTitleBox = getChild<LLTextBox>("notification_title");
mTitleBoxExp = getChild<LLTextBox>("notification_title_exp");
mNoticeTextExp = getChild<LLChatEntry>("notification_text_exp");
mTimeBox = getChild<LLTextBox>("notification_time");
mTimeBoxExp = getChild<LLTextBox>("notification_time_exp");
mExpandBtn = getChild<LLButton>("expand_btn");
mCondenseBtn = getChild<LLButton>("condense_btn");
mCloseBtn = getChild<LLButton>("close_btn");
mCloseBtnExp = getChild<LLButton>("close_expanded_btn");
mTitleBox->setValue(mParams.title);
mTitleBoxExp->setValue(mParams.title);
mNoticeTextExp->setValue(mParams.title);
mNoticeTextExp->setEnabled(FALSE);
mNoticeTextExp->setTextExpandedCallback(boost::bind(&LLNotificationListItem::reshapeNotification, this));
mTitleBox->setContentTrusted(false);
mTitleBoxExp->setContentTrusted(false);
mNoticeTextExp->setContentTrusted(false);
mTimeBox->setValue(buildNotificationDate(mParams.time_stamp));
mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp));
mExpandBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickExpandBtn,this));
mCondenseBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCondenseBtn,this));
//mCloseBtn and mCloseExpandedBtn share the same callback
mCloseBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCloseBtn,this));
mCloseBtnExp->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCloseBtn,this));
mCondensedViewPanel = getChild<LLPanel>("layout_panel_condensed_view");
mExpandedViewPanel = getChild<LLPanel>("layout_panel_expanded_view");
std::string expanded_height_str = getString("item_expanded_height");
std::string condensed_height_str = getString("item_condensed_height");
mExpandedHeight = (S32)atoi(expanded_height_str.c_str());
mCondensedHeight = (S32)atoi(condensed_height_str.c_str());
setExpanded(FALSE);
return rv;
}
LLNotificationListItem::~LLNotificationListItem()
{
}
//static
std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_stamp, ETimeType time_type)
{
std::string timeStr;
switch(time_type)
{
case Local:
timeStr = "[" + LLTrans::getString("LTimeMthNum") + "]/["
+LLTrans::getString("LTimeDay")+"]/["
+LLTrans::getString("LTimeYear")+"] ["
+LLTrans::getString("LTimeHour")+"]:["
+LLTrans::getString("LTimeMin")+ "]";
break;
case UTC:
timeStr = "[" + LLTrans::getString("UTCTimeMth") + "]/["
+LLTrans::getString("UTCTimeDay")+"]/["
+LLTrans::getString("UTCTimeYr")+"] ["
+LLTrans::getString("UTCTimeHr")+"]:["
+LLTrans::getString("UTCTimeMin")+"] ["
+LLTrans::getString("UTCTimeTimezone")+"]";
break;
case SLT:
default:
timeStr = "[" + LLTrans::getString("TimeMonth") + "]/["
+LLTrans::getString("TimeDay")+"]/["
+LLTrans::getString("TimeYear")+"] ["
+LLTrans::getString("TimeHour")+"]:["
+LLTrans::getString("TimeMin")+"]";
break;
}
LLSD substitution;
substitution["datetime"] = time_stamp;
LLStringUtil::format(timeStr, substitution);
return timeStr;
}
void LLNotificationListItem::onClickCloseBtn()
{
mOnItemClose(this);
close();
}
BOOL LLNotificationListItem::handleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL res = LLPanel::handleMouseUp(x, y, mask);
mOnItemClick(this);
return res;
}
void LLNotificationListItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
mCondensedViewPanel->setTransparentColor(LLUIColorTable::instance().getColor( "ScrollHoveredColor" ));
mExpandedViewPanel->setTransparentColor(LLUIColorTable::instance().getColor( "ScrollHoveredColor" ));
}
void LLNotificationListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
mCondensedViewPanel->setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
mExpandedViewPanel->setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
}
//static
LLNotificationListItem* LLNotificationListItem::create(const Params& p)
{
if (LLNotificationListItem::getGroupInviteTypes().count(p.notification_name))
{
return new LLGroupInviteNotificationListItem(p);
}
else if (LLNotificationListItem::getGroupNoticeTypes().count(p.notification_name))
{
return new LLGroupNoticeNotificationListItem(p);
}
else if (LLNotificationListItem::getTransactionTypes().count(p.notification_name))
{
return new LLTransactionNotificationListItem(p);
}
return new LLSystemNotificationListItem(p);
}
//static
std::set<std::string> LLNotificationListItem::getGroupInviteTypes()
{
return LLGroupInviteNotificationListItem::getTypes();
}
std::set<std::string> LLNotificationListItem::getGroupNoticeTypes()
{
return LLGroupNoticeNotificationListItem::getTypes();
}
//static
std::set<std::string> LLNotificationListItem::getTransactionTypes()
{
return LLTransactionNotificationListItem::getTypes();
}
void LLNotificationListItem::onClickExpandBtn()
{
setExpanded(TRUE);
}
void LLNotificationListItem::onClickCondenseBtn()
{
setExpanded(FALSE);
}
void LLNotificationListItem::reshapeNotification()
{
if(mExpanded)
{
S32 width = this->getRect().getWidth();
this->reshape(width, mNoticeTextExp->getRect().getHeight() + mExpandedHeight, FALSE);
}
}
void LLNotificationListItem::setExpanded(BOOL value)
{
mCondensedViewPanel->setVisible(!value);
mExpandedViewPanel->setVisible(value);
S32 width = this->getRect().getWidth();
if (value)
{
this->reshape(width, mNoticeTextExp->getRect().getHeight() + mExpandedHeight, FALSE);
}
else
{
this->reshape(width, mCondensedHeight, FALSE);
}
mExpanded = value;
}
std::set<std::string> LLGroupInviteNotificationListItem::getTypes()
{
std::set<std::string> types;
types.insert("JoinGroup");
return types;
}
std::set<std::string> LLGroupNoticeNotificationListItem::getTypes()
{
std::set<std::string> types;
types.insert("GroupNotice");
return types;
}
std::set<std::string> LLTransactionNotificationListItem::getTypes()
{
std::set<std::string> types;
types.insert("PaymentReceived");
types.insert("PaymentSent");
return types;
}
LLGroupNotificationListItem::LLGroupNotificationListItem(const Params& p)
: LLNotificationListItem(p),
mSenderOrFeeBox(NULL)
{
}
LLGroupInviteNotificationListItem::LLGroupInviteNotificationListItem(const Params& p)
: LLGroupNotificationListItem(p)
{
buildFromFile("panel_notification_list_item.xml");
}
BOOL LLGroupInviteNotificationListItem::postBuild()
{
BOOL rv = LLGroupNotificationListItem::postBuild();
setFee(mParams.fee);
mInviteButtonPanel = getChild<LLPanel>("button_panel");
mInviteButtonPanel->setVisible(TRUE);
mJoinBtn = getChild<LLButton>("join_btn");
mDeclineBtn = getChild<LLButton>("decline_btn");
mInfoBtn = getChild<LLButton>("info_btn");
//invitation with any non-default group role, doesn't have newline characters at the end unlike simple invitations
std::string invitation_desc = mNoticeTextExp->getValue().asString();
boost::regex pattern = boost::regex("\n\n$", boost::regex::perl|boost::regex::icase);
boost::match_results<std::string::const_iterator> matches;
if(!boost::regex_search(invitation_desc, matches, pattern))
{
invitation_desc += "\n\n";
mNoticeTextExp->setValue(invitation_desc);
}
mJoinBtn->setClickedCallback(boost::bind(&LLGroupInviteNotificationListItem::onClickJoinBtn,this));
mDeclineBtn->setClickedCallback(boost::bind(&LLGroupInviteNotificationListItem::onClickDeclineBtn,this));
mInfoBtn->setClickedCallback(boost::bind(&LLGroupInviteNotificationListItem::onClickInfoBtn,this));
std::string expanded_height_resize_str = getString("expanded_height_resize_for_attachment");
mExpandedHeightResize = (S32)atoi(expanded_height_resize_str.c_str());
return rv;
}
void LLGroupInviteNotificationListItem::onClickJoinBtn()
{
if (!gAgent.canJoinGroups())
{
LLNotificationsUtil::add("JoinedTooManyGroups");
return;
}
if(mParams.fee > 0)
{
LLSD args;
args["COST"] = llformat("%d", mParams.fee);
// Set the fee for next time to 0, so that we don't keep
// asking about a fee.
LLSD next_payload;
next_payload["group_id"]= mParams.group_id;
next_payload["transaction_id"]= mParams.transaction_id;
next_payload["fee"] = 0;
LLNotificationsUtil::add("JoinGroupCanAfford", args, next_payload);
}
else
{
send_improved_im(mParams.group_id,
std::string("name"),
std::string("message"),
IM_ONLINE,
IM_GROUP_INVITATION_ACCEPT,
mParams.transaction_id);
}
LLNotificationListItem::onClickCloseBtn();
}
void LLGroupInviteNotificationListItem::onClickDeclineBtn()
{
send_improved_im(mParams.group_id,
std::string("name"),
std::string("message"),
IM_ONLINE,
IM_GROUP_INVITATION_DECLINE,
mParams.transaction_id);
LLNotificationListItem::onClickCloseBtn();
}
void LLGroupInviteNotificationListItem::onClickInfoBtn()
{
LLGroupActions::show(mParams.group_id);
}
void LLGroupInviteNotificationListItem::setFee(S32 fee)
{
LLStringUtil::format_map_t string_args;
string_args["[GROUP_FEE]"] = llformat("%d", fee);
std::string fee_text = getString("group_fee_text", string_args);
mSenderOrFeeBox->setValue(fee_text);
mSenderOrFeeBoxExp->setValue(fee_text);
mSenderOrFeeBox->setVisible(TRUE);
mSenderOrFeeBoxExp->setVisible(TRUE);
}
LLGroupNoticeNotificationListItem::LLGroupNoticeNotificationListItem(const Params& p)
: LLGroupNotificationListItem(p),
mAttachmentPanel(NULL),
mAttachmentTextBox(NULL),
mAttachmentIcon(NULL),
mAttachmentIconExp(NULL),
mInventoryOffer(NULL)
{
if (mParams.inventory_offer.isDefined())
{
mInventoryOffer = new LLOfferInfo(mParams.inventory_offer);
}
buildFromFile("panel_notification_list_item.xml");
}
LLGroupNoticeNotificationListItem::~LLGroupNoticeNotificationListItem()
{
LLGroupMgr::getInstance()->removeObserver(this);
}
BOOL LLGroupNoticeNotificationListItem::postBuild()
{
BOOL rv = LLGroupNotificationListItem::postBuild();
mAttachmentTextBox = getChild<LLTextBox>("attachment_text");
mAttachmentIcon = getChild<LLIconCtrl>("attachment_icon");
mAttachmentIconExp = getChild<LLIconCtrl>("attachment_icon_exp");
mAttachmentPanel = getChild<LLPanel>("attachment_panel");
mAttachmentPanel->setVisible(FALSE);
mTitleBox->setValue(mParams.subject);
mTitleBoxExp->setValue(mParams.subject);
mNoticeTextExp->setValue(mParams.message);
mTimeBox->setValue(buildNotificationDate(mParams.time_stamp, UTC));
mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp, UTC));
//Workaround: in case server timestamp is 0 - we use the time when notification was actually received
if (mParams.time_stamp.isNull())
{
mTimeBox->setValue(buildNotificationDate(mParams.received_time, UTC));
mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time, UTC));
}
setSender(mParams.sender);
if (mInventoryOffer != NULL)
{
mAttachmentTextBox->setValue(mInventoryOffer->mDesc);
mAttachmentTextBox->setVisible(TRUE);
mAttachmentIcon->setVisible(TRUE);
std::string icon_name = LLInventoryIcon::getIconName(mInventoryOffer->mType,
LLInventoryType::IT_TEXTURE);
mAttachmentIconExp->setValue(icon_name);
mAttachmentIconExp->setVisible(TRUE);
mAttachmentTextBox->setClickedCallback(boost::bind(
&LLGroupNoticeNotificationListItem::onClickAttachment, this));
std::string expanded_height_resize_str = getString("expanded_height_resize_for_attachment");
mExpandedHeightResize = (S32)atoi(expanded_height_resize_str.c_str());
mAttachmentPanel->setVisible(TRUE);
}
return rv;
}
BOOL LLGroupNotificationListItem::postBuild()
{
BOOL rv = LLNotificationListItem::postBuild();
mGroupIcon = getChild<LLGroupIconCtrl>("group_icon");
mGroupIconExp = getChild<LLGroupIconCtrl>("group_icon_exp");
mGroupNameBoxExp = getChild<LLTextBox>("group_name_exp");
mGroupIcon->setValue(mParams.group_id);
mGroupIconExp->setValue(mParams.group_id);
mGroupIcon->setVisible(TRUE);
mGroupIconExp->setVisible(TRUE);
mGroupId = mParams.group_id;
mSenderOrFeeBox = getChild<LLTextBox>("sender_or_fee_box");
mSenderOrFeeBoxExp = getChild<LLTextBox>("sender_or_fee_box_exp");
LLSD value(mParams.group_id);
setGroupId(value);
return rv;
}
void LLGroupNotificationListItem::changed(LLGroupChange gc)
{
if (GC_PROPERTIES == gc)
{
updateFromCache();
LLGroupMgr::getInstance()->removeObserver(this);
}
}
bool LLGroupNotificationListItem::updateFromCache()
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId);
if (!group_data) return false;
setGroupName(group_data->mName);
return true;
}
void LLGroupNotificationListItem::setGroupId(const LLUUID& value)
{
LLGroupMgr* gm = LLGroupMgr::getInstance();
if (mGroupId.notNull())
{
gm->removeObserver(this);
mID = mGroupId;
// Check if cache already contains image_id for that group
if (!updateFromCache())
{
gm->addObserver(this);
gm->sendGroupPropertiesRequest(mGroupId);
}
}
}
void LLGroupNotificationListItem::setGroupName(std::string name)
{
if (!name.empty())
{
LLStringUtil::format_map_t string_args;
string_args["[GROUP_NAME]"] = llformat("%s", name.c_str());
std::string group_box_str = getString("group_name_text", string_args);
mGroupNameBoxExp->setValue(group_box_str);
mGroupNameBoxExp->setVisible(TRUE);
}
else
{
mGroupNameBoxExp->setValue(LLStringUtil::null);
mGroupNameBoxExp->setVisible(FALSE);
}
}
void LLGroupNoticeNotificationListItem::setSender(std::string sender)
{
if (!sender.empty())
{
LLStringUtil::format_map_t string_args;
string_args["[SENDER_RESIDENT]"] = llformat("%s", sender.c_str());
std::string sender_text = getString("sender_resident_text", string_args);
mSenderOrFeeBox->setValue(sender_text);
mSenderOrFeeBoxExp->setValue(sender_text);
mSenderOrFeeBox->setVisible(TRUE);
mSenderOrFeeBoxExp->setVisible(TRUE);
} else {
mSenderOrFeeBox->setValue(LLStringUtil::null);
mSenderOrFeeBoxExp->setValue(LLStringUtil::null);
mSenderOrFeeBox->setVisible(FALSE);
mSenderOrFeeBoxExp->setVisible(FALSE);
}
}
void LLGroupNoticeNotificationListItem::close()
{
// The group notice dialog may be an inventory offer.
// If it has an inventory save button and that button is still enabled
// Then we need to send the inventory declined message
if (mInventoryOffer != NULL)
{
mInventoryOffer->forceResponse(IOR_DECLINE);
mInventoryOffer = NULL;
}
LLGroupMgr::getInstance()->removeObserver(this);
}
void LLGroupNoticeNotificationListItem::onClickAttachment()
{
if (mInventoryOffer != NULL) {
mInventoryOffer->forceResponse(IOR_ACCEPT);
static const LLUIColor textColor = LLUIColorTable::instance().getColor(
"GroupNotifyDimmedTextColor");
mAttachmentTextBox->setColor(textColor);
mAttachmentIconExp->setEnabled(FALSE);
//if attachment isn't openable - notify about saving
if (!isAttachmentOpenable(mInventoryOffer->mType)) {
LLNotifications::instance().add("AttachmentSaved", LLSD(), LLSD());
}
mInventoryOffer = NULL;
}
}
//static
bool LLGroupNoticeNotificationListItem::isAttachmentOpenable(LLAssetType::EType type)
{
switch (type)
{
case LLAssetType::AT_LANDMARK:
case LLAssetType::AT_NOTECARD:
case LLAssetType::AT_IMAGE_JPEG:
case LLAssetType::AT_IMAGE_TGA:
case LLAssetType::AT_TEXTURE:
case LLAssetType::AT_TEXTURE_TGA:
return true;
default:
return false;
}
}
LLTransactionNotificationListItem::LLTransactionNotificationListItem(const Params& p)
: LLNotificationListItem(p),
mAvatarIcon(NULL)
{
buildFromFile("panel_notification_list_item.xml");
}
BOOL LLTransactionNotificationListItem::postBuild()
{
BOOL rv = LLNotificationListItem::postBuild();
mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
mAvatarIconExp = getChild<LLAvatarIconCtrl>("avatar_icon_exp");
mAvatarIcon->setValue("System_Notification");
mAvatarIconExp->setValue("System_Notification");
mAvatarIcon->setVisible(TRUE);
mAvatarIconExp->setVisible(TRUE);
if((GOVERNOR_LINDEN_ID == mParams.paid_to_id) ||
(GOVERNOR_LINDEN_ID == mParams.paid_from_id))
{
return rv;
}
if (mParams.notification_name == "PaymentReceived")
{
mAvatarIcon->setValue(mParams.paid_from_id);
mAvatarIconExp->setValue(mParams.paid_from_id);
}
else if (mParams.notification_name == "PaymentSent")
{
mAvatarIcon->setValue(mParams.paid_to_id);
mAvatarIconExp->setValue(mParams.paid_to_id);
}
return rv;
}
LLSystemNotificationListItem::LLSystemNotificationListItem(const Params& p)
: LLNotificationListItem(p),
mSystemNotificationIcon(NULL),
mIsCaution(false)
{
buildFromFile("panel_notification_list_item.xml");
mIsCaution = p.notification_priority >= NOTIFICATION_PRIORITY_HIGH;
if (mIsCaution)
{
mTitleBox->setColor(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
mTitleBoxExp->setColor(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
mNoticeTextExp->setReadOnlyColor(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
mTimeBox->setColor(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
mTimeBoxExp->setColor(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
}
}
BOOL LLSystemNotificationListItem::postBuild()
{
BOOL rv = LLNotificationListItem::postBuild();
mSystemNotificationIcon = getChild<LLIconCtrl>("system_notification_icon");
mSystemNotificationIconExp = getChild<LLIconCtrl>("system_notification_icon_exp");
if (mSystemNotificationIcon)
mSystemNotificationIcon->setVisible(TRUE);
if (mSystemNotificationIconExp)
mSystemNotificationIconExp->setVisible(TRUE);
return rv;
}

View File

@ -0,0 +1,250 @@
/**
* @file llnotificationlistitem.h
* @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$
*/
#ifndef LL_LLNOTIFICATIONLISTITEM_H
#define LL_LLNOTIFICATIONLISTITEM_H
#include "llpanel.h"
#include "lllayoutstack.h"
#include "lltextbox.h"
#include "llviewertexteditor.h"
#include "llbutton.h"
#include "llgroupiconctrl.h"
#include "llavatariconctrl.h"
#include "llchatentry.h"
#include "llgroupmgr.h"
#include "llviewermessage.h"
#include <string>
class LLNotificationListItem : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
LLUUID notification_id;
LLUUID transaction_id;
LLUUID group_id;
LLUUID paid_from_id;
LLUUID paid_to_id;
std::string notification_name;
std::string title;
std::string subject;
std::string message;
std::string sender;
S32 fee;
LLDate time_stamp;
LLDate received_time;
LLSD inventory_offer;
e_notification_priority notification_priority;
Params() {};
};
static LLNotificationListItem* create(const Params& p);
static std::set<std::string> getTransactionTypes();
static std::set<std::string> getGroupInviteTypes();
static std::set<std::string> getGroupNoticeTypes();
// title
void setTitle( std::string title );
// get item's ID
LLUUID getID() { return mParams.notification_id; }
std::string& getTitle() { return mTitle; }
std::string& getNotificationName() { return mNotificationName; }
// handlers
virtual BOOL handleMouseUp(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); }
virtual bool showPopup() { return true; }
void setExpanded(BOOL value);
virtual BOOL postBuild();
void reshapeNotification();
typedef enum e_time_type
{
SLT = 1,
Local = 2,
UTC = 3,
}ETimeType;
protected:
LLNotificationListItem(const Params& p);
virtual ~LLNotificationListItem();
static std::string buildNotificationDate(const LLDate& time_stamp, ETimeType time_type = SLT);
void onClickExpandBtn();
void onClickCondenseBtn();
void onClickCloseBtn();
virtual void close() {};
Params mParams;
LLTextBox* mTitleBox;
LLTextBox* mTitleBoxExp;
LLChatEntry* mNoticeTextExp;
LLTextBox* mTimeBox;
LLTextBox* mTimeBoxExp;
LLButton* mExpandBtn;
LLButton* mCondenseBtn;
LLButton* mCloseBtn;
LLButton* mCloseBtnExp;
LLPanel* mCondensedViewPanel;
LLPanel* mExpandedViewPanel;
std::string mTitle;
std::string mNotificationName;
S32 mCondensedHeight;
S32 mExpandedHeight;
S32 mExpandedHeightResize;
bool mExpanded;
};
class LLGroupNotificationListItem
: public LLNotificationListItem, public LLGroupMgrObserver
{
public:
virtual BOOL postBuild();
void setGroupId(const LLUUID& value);
// LLGroupMgrObserver observer trigger
virtual void changed(LLGroupChange gc);
friend class LLNotificationListItem;
protected:
LLGroupNotificationListItem(const Params& p);
LLGroupIconCtrl* mGroupIcon;
LLGroupIconCtrl* mGroupIconExp;
LLUUID mGroupId;
LLTextBox* mSenderOrFeeBox;
LLTextBox* mSenderOrFeeBoxExp;
LLTextBox* mGroupNameBoxExp;
private:
LLGroupNotificationListItem(const LLGroupNotificationListItem &);
LLGroupNotificationListItem & operator=(LLGroupNotificationListItem &);
void setGroupName(std::string name);
bool updateFromCache();
};
class LLGroupInviteNotificationListItem
: public LLGroupNotificationListItem
{
public:
static std::set<std::string> getTypes();
virtual BOOL postBuild();
/*virtual*/ bool showPopup() { return false; }
private:
friend class LLNotificationListItem;
LLGroupInviteNotificationListItem(const Params& p);
LLGroupInviteNotificationListItem(const LLGroupInviteNotificationListItem &);
LLGroupInviteNotificationListItem & operator=(LLGroupInviteNotificationListItem &);
void setFee(S32 fee);
void onClickJoinBtn();
void onClickDeclineBtn();
void onClickInfoBtn();
LLPanel* mInviteButtonPanel;
LLButton* mJoinBtn;
LLButton* mDeclineBtn;
LLButton* mInfoBtn;
};
class LLGroupNoticeNotificationListItem
: public LLGroupNotificationListItem
{
public:
~LLGroupNoticeNotificationListItem();
static std::set<std::string> getTypes();
virtual BOOL postBuild();
/*virtual*/ bool showPopup() { return false; }
private:
friend class LLNotificationListItem;
LLGroupNoticeNotificationListItem(const Params& p);
LLGroupNoticeNotificationListItem(const LLGroupNoticeNotificationListItem &);
LLGroupNoticeNotificationListItem & operator=(LLGroupNoticeNotificationListItem &);
void setSender(std::string sender);
void onClickAttachment();
/*virtual*/ void close();
static bool isAttachmentOpenable(LLAssetType::EType);
LLPanel* mAttachmentPanel;
LLTextBox* mAttachmentTextBox;
LLIconCtrl* mAttachmentIcon;
LLIconCtrl* mAttachmentIconExp;
LLOfferInfo* mInventoryOffer;
};
class LLTransactionNotificationListItem : public LLNotificationListItem
{
public:
static std::set<std::string> getTypes();
virtual BOOL postBuild();
private:
friend class LLNotificationListItem;
LLTransactionNotificationListItem(const Params& p);
LLTransactionNotificationListItem(const LLTransactionNotificationListItem &);
LLTransactionNotificationListItem & operator=(LLTransactionNotificationListItem &);
LLAvatarIconCtrl* mAvatarIcon;
LLAvatarIconCtrl* mAvatarIconExp;
};
class LLSystemNotificationListItem : public LLNotificationListItem
{
public:
virtual BOOL postBuild();
private:
friend class LLNotificationListItem;
LLSystemNotificationListItem(const Params& p);
LLSystemNotificationListItem(const LLSystemNotificationListItem &);
LLSystemNotificationListItem & operator=(LLSystemNotificationListItem &);
LLIconCtrl* mSystemNotificationIcon;
LLIconCtrl* mSystemNotificationIconExp;
bool mIsCaution;
};
#endif // LL_LLNOTIFICATIONLISTITEM_H

View File

@ -0,0 +1,44 @@
/**
* @file llnotificationlistview.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"
#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

View File

@ -0,0 +1,49 @@
/**
* @file llnotificationlistview.h
* @brief LLNotificationListView class to support notifications list contained in enclosing floater.
*
* $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$
*/
#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

View File

@ -295,158 +295,6 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
return mChiclet->handleRightMouseDown(x, y, mask);
}
/************************************************************************/
/* LLNotificationWellWindow implementation */
/************************************************************************/
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
mWellWindow(well_window)
{
connectToChannel("Notifications");
connectToChannel("Group Notifications");
connectToChannel("Offer");
}
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
: LLSysWellWindow(key)
{
mNotificationUpdates.reset(new WellNotificationChannel(this));
}
// static
LLNotificationWellWindow* LLNotificationWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
{
return LLFloaterReg::getTypedInstance<LLNotificationWellWindow>("notification_well_window", key);
}
// virtual
BOOL LLNotificationWellWindow::postBuild()
{
BOOL rv = LLSysWellWindow::postBuild();
setTitle(getString("title_notification_well_window"));
return rv;
}
// virtual
void LLNotificationWellWindow::setVisible(BOOL visible)
{
if (visible)
{
// when Notification channel is cleared, storable toasts will be added into the list.
clearScreenChannels();
}
LLSysWellWindow::setVisible(visible);
}
//---------------------------------------------------------------------------------
void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
{
LLSD value = p.notification_id;
// do not add clones
if( mMessageList->getItemByValue(value))
return;
LLSysWellItem* new_item = new LLSysWellItem(p);
if (mMessageList->addItem(new_item, value, ADD_TOP))
{
mSysWellChiclet->updateWidget(isWindowEmpty());
reshapeWindow();
new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
}
else
{
LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id
<< ", title: " << p.title
<< LL_ENDL;
new_item->die();
}
}
void LLNotificationWellWindow::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)
{
LLSysWellItem* sys_well_item = dynamic_cast<LLSysWellItem*>(*iter);
if (sys_well_item)
onItemClose(sys_well_item);
}
}
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
void LLNotificationWellWindow::initChannel()
{
LLSysWellWindow::initChannel();
if(mChannel)
{
mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
}
}
void LLNotificationWellWindow::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 LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
{
LLSysWellItem::Params p;
p.notification_id = id;
p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
addItem(p);
}
void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
{
LLUUID id = item->getID();
LLFloaterReg::showInstance("inspect_toast", id);
}
void LLNotificationWellWindow::onItemClose(LLSysWellItem* 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);
}
}
void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
{
removeItemByID(notify->getID());
}
/************************************************************************/
/* LLIMWellWindow implementation */
/************************************************************************/

View File

@ -95,57 +95,6 @@ protected:
bool mIsReshapedByUser;
};
/**
* Class intended to manage incoming notifications.
*
* It contains a list of notifications that have not been responded to.
*/
class LLNotificationWellWindow : public LLSysWellWindow
{
public:
LLNotificationWellWindow(const LLSD& key);
static LLNotificationWellWindow* getInstance(const LLSD& key = LLSD());
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void onAdd(LLNotificationPtr notify);
// Operating with items
void addItem(LLSysWellItem::Params p);
// Closes all notifications and removes them from the Notification Well
void closeAll();
protected:
struct WellNotificationChannel : public LLNotificationChannel
{
WellNotificationChannel(LLNotificationWellWindow*);
void onDelete(LLNotificationPtr notify)
{
mWellWindow->removeItemByID(notify->getID());
}
LLNotificationWellWindow* mWellWindow;
};
LLNotificationChannelPtr mNotificationUpdates;
/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
private:
// init Window's channel
void initChannel();
void clearScreenChannels();
void onStoreToast(LLPanel* info_panel, LLUUID id);
// Handlers
void onItemClick(LLSysWellItem* item);
void onItemClose(LLSysWellItem* item);
// ID of a toast loaded by user (by clicking notification well item)
LLUUID mLoadedToastId;
};
/**
* Class intended to manage incoming messages in IM chats.
*

View File

@ -92,7 +92,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
+LLTrans::getString("UTCTimeSec")+"] ["
+LLTrans::getString("UTCTimeTimezone")+"]";
const LLDate timeStamp = notification->getDate();
LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
LLDate notice_date = timeStamp.notNull() ? timeStamp : payload["received_time"].asDate();
LLSD substitution;
substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
LLStringUtil::format(timeStr, substitution);

View File

@ -90,6 +90,7 @@
#include "llfloatermodelpreview.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaternotificationstabbed.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutbox.h"
@ -268,7 +269,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>);
LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationsTabbed>);
LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);

View File

@ -2683,6 +2683,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
payload["sender_name"] = name;
payload["group_id"] = group_id;
payload["inventory_name"] = item_name;
payload["received_time"] = LLDate::now();
if(info && info->asLLSD())
{
payload["inventory_offer"] = info->asLLSD();
@ -5638,6 +5639,7 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
}
}
final_args["MESSAGE"] = message;
payload["dest_id"] = dest_id;
notification = success ? "PaymentSent" : "PaymentFailure";
}
else {

View File

@ -873,8 +873,11 @@
<color
name="ToolbarDropZoneColor"
value=".48 .69 1 .5" />
<!-- Generic color names (legacy) -->
<color
name="PanelNotificationListItem"
value="0.3 0.3 0.3 .3" />
<!-- Generic color names (legacy) -->
<color
name="white"
value="1 1 1 1"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

View File

@ -804,4 +804,9 @@ with the same filename but different name
<texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
<texture name="NavBar Separator" file_name="navbar/separator.png"/>
<texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
<texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
<texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
<texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png" preload="true"/>
<texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png" preload="true"/>
</textures>

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater
legacy_header_height="18"
bevel_style="in"
layout="topleft"
name="floater_notifications_tabbed"
help_topic="notification_chiclet"
save_rect="true"
title="NOTIFICATIONS"
width="350"
min_width="435"
height="550"
min_height="150"
can_minimize="false"
can_tear_off="false"
can_resize="true"
can_drag_on_left="false"
can_dock="true"
save_dock_state="true"
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="group_invitations_tab_title">
Invitations ([COUNT])
</floater.string>
<floater.string
name="group_notices_tab_title">
Group ([COUNT])
</floater.string>
<string
name="title_notification_tabbed_window">
NOTIFICATIONS
</string>
<layout_stack
width="336"
height="533"
enabled="true"
orientation="vertical"
name="TabButtonsStack"
follows="left|top|right|bottom"
top="17">
<layout_panel
width="336"
height="530"
enabled="true"
name="TabButtonsLayoutPanel">
<tab_container
follows="left|top|right|bottom"
halign="center"
layout="topleft"
tab_position="top"
left="7"
top="7"
width="336"
height="491"
mouse_opaque="true"
name="notifications_tab_container">
<panel
border="true"
bevel_style="none"
follows="left|top|right|bottom"
label="System (0)"
layout="topleft"
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 (0)"
layout="topleft"
name="transaction_notifications_tab">
<notification_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
layout="topleft"
name="transaction_notification_list"
left="0"
top="5"
height="0"
width="328"/>
</panel>
<panel
border="true"
bevel_style="none"
follows="left|top|right|bottom"
label="Invitations (0)"
layout="topleft"
name="group_invite_notifications_tab">
<notification_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
layout="topleft"
name="group_invite_notification_list"
left="0"
top="5"
height="0"
width="328"/>
</panel>
<panel
border="true"
bevel_style="none"
follows="left|top|right|bottom"
label="Group (0)"
layout="topleft"
name="group_notice_notifications_tab">
<notification_list_view
color="FloaterDefaultBackgroundColor"
follows="all"
layout="topleft"
name="group_notice_notification_list"
left="0"
top="5"
height="0"
width="328"/>
</panel>
</tab_container>
<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="Collapse all" name="collapse_all_button">
</button>
</layout_panel>
<layout_panel width="336" height="30" enabled="true" orientation="horizontal" name="GapLayoutPanel">
<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="delete_all_button">
</button>
</layout_panel>
</layout_stack>
</layout_panel>
</layout_stack>
</floater>

View File

@ -23,10 +23,6 @@
name="title_im_well_window">
CONVERSATIONS
</string>
<string
name="title_notification_well_window">
NOTIFICATIONS
</string>
<flat_list_view
color="FloaterDefaultBackgroundColor"

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- All our XML is utf-8 encoded. -->
<panel
translate="false"
name="main_panel"
title="panel_notification_list_item"
visible="true"
top="0"
left="0"
width="331"
height="202"
can_resize="true"
layout="topleft"
follows="left|top|right|bottom" >
<!-- background_opaque="false" -->
<!-- background_visible="true"> -->
<!-- bg_alpha_color="PanelNotificationListItem"> -->
<panel.string
name="sender_resident_text">
Sender: "[SENDER_RESIDENT]"
</panel.string>
<panel.string
name="group_name_text">
Group: "[GROUP_NAME]"
</panel.string>
<panel.string
name="group_fee_text">
Fee: [GROUP_FEE]
</panel.string>
<panel.string
name="item_condensed_height">
50
</panel.string>
<panel.string
name="item_expanded_height">
87
</panel.string>
<panel.string
name="expanded_height_resize_for_attachment">
27
</panel.string>
<panel top="0" left="0" width="331" height="196" bevel_style="none" layout="topleft" follows="left|top|right|bottom" name="panel_total_view">
<layout_stack top="0" left="0" width="331" height="196" orientation="vertical" follows="left|top|right|bottom" name="item_vertical_stack">
<layout_panel top="0" left="0" height="30" follows="left|top|right|bottom" layout="topleft" name="layout_panel_condensed_view" visible="false" background_opaque="false" background_visible="true" bg_alpha_color="SysWellItemUnselected">
<panel border="true" top="0" left="5" height="30" bevel_style="none" layout="topleft" follows="left|top|right|bottom" name="panel_condensed_view">
<layout_stack top="0" left="0" width="325" height="50" orientation="horizontal" follows="left|top|right|bottom" name="horizontal_stack">
<layout_panel width="30" height="39" orientation="horizontal" follows="left|top|right|bottom" name="layout_panel_right">
<group_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="group_icon" tool_tip="Group" default_icon_name="Generic_Group" visible="true"/>
<avatar_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="avatar_icon" tool_tip="Avatar" default_icon_name="Generic_Person" visible="false"/>
<icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="system_notification_icon" tool_tip="Icon" image_name="System_Notification" visible="false"/>
</layout_panel>
<layout_panel width="260" height="50" orientation="horizontal" name="layout_panel_middle">
<panel border="false" top="0" width="260" height="38" bevel_style="none" follows="left|top|right" layout="topleft" name="main_info_panel">
<panel border="false" top="0" left="0" width="260" height="19" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="notification_title_panel">
<text allow_scroll="false" font="SansSerifSmall" top="6" left="0" width="260" height="12" layout="topleft" follows="right|left" text_color="White"
use_ellipses="true" word_wrap="true" mouse_opaque="false" name="notification_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="1" left="242" width="21" height="21" image_name="Icon_Attachment_Small" follows="right" mouse_opaque="true" name="attachment_icon" tool_tip="Attachment" visible="false"/>
</panel>
<panel border="false" top="23" left="0" width="260" height="15" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="sender_time_panel">
<text allow_scroll="false" font="SansSerifSmall" top="0" left="0" width="170" height="13" layout="topleft" follows="right|left"
use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_or_fee_box" visible="false">
Sender: "Resident R e s i d e n t R e s i d e n t"
</text>
<text allow_scroll="false" font="SansSerifSmall" top="0" right="-5" width="95" height="13" follows="right" halign="right" layout="topleft" left_pad="5"
name="notification_time" value="2014/12/24 23:30" />
</panel>
</panel>
</layout_panel>
<layout_panel width="18" height="48" orientation="horizontal" follows="right|top|bottom" name="layout_panel_right">
<panel top="0" left="0" width="17" height="39" follows="left|top|right|bottom" layout="topleft" name="close_expand_panel">
<button top="0" left="0" width="17" height="17" layout="topleft" follows="top" name="close_btn" mouse_opaque="true"
tab_stop="false" image_unselected="Icon_Close_Foreground" image_selected="Icon_Close_Press" />
<button bottom="-16" right="15" width="17" height="17" layout="topleft" follows="bottom" name="expand_btn" mouse_opaque="true"
tab_stop="false" image_unselected="Notification_Expand" image_selected="Notification_Expand" />
</panel>
</layout_panel>
</layout_stack>
</panel>
</layout_panel>
<layout_panel top="0" left="0" height="196" follows="left|top|right|bottom" layout="topleft" name="layout_panel_expanded_view" visible="true" background_opaque="false" background_visible="true" bg_alpha_color="SysWellItemUnselected">
<panel border="true" top="0" left="5" height="196" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="panel_expanded_view">
<layout_stack top="0" left="0" width="325" height="196" orientation="horizontal" follows="left|top|right|bottom" name="horizontal_stack">
<layout_panel width="30" height="170" orientation="horizontal" follows="left|top|bottom" name="layout_panel_right_exp">
<group_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="group_icon_exp" tool_tip="Group" default_icon_name="Generic_Group" visible="true"/>
<avatar_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="avatar_icon_exp" tool_tip="Avatar" default_icon_name="Generic_Person" visible="false"/>
<icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="system_notification_icon_exp" tool_tip="Icon" image_name="System_Notification" visible="false"/>
<icon left="12" top="144" width="20" height="20" name="attachment_icon_exp" tool_tip="Attachment" image_name="Icon_Attachment_Large" follows="left" mouse_opaque="true" visible="false"/>
</layout_panel>
<layout_panel width="230" height="196" orientation="horizontal" follows="left|top|right|bottom" name="layout_panel_middle_exp">
<panel border="false" top="0" width="230" height="196" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="main_info_panel_expanded">
<panel border="false" top="0" left="0" width="230" height="30" bevel_style="none" follows="left|top|right" layout="topleft" name="notification_title_panel_exp" >
<text allow_scroll="false" font="SansSerif" top="6" left="0" width="233" height="10" layout="topleft" follows="right|left" text_color="White"
use_ellipses="true" word_wrap="false" mouse_opaque="false" name="notification_title_exp">
Notice Title Notice Title N o t i c e T i t l e N o t i c e T i t l e
</text>
<text allow_scroll="false" font="SansSerif" left="0" width="233" height="10" layout="topleft" follows="right|left" text_color="White"
use_ellipses="true" word_wrap="false" mouse_opaque="false" name="group_name_exp" parse_urls="false" visible="false">
Group Name Group Name Group Na m e e
</text>
</panel>
<panel border="false" left="0" width="230" height="15" bevel_style="none" follows="left|top|right" layout="topleft" name="sender_time_panel_exp">
<text allow_scroll="false" font="SansSerifSmall" top="0" left="0" width="145" height="13" layout="topleft" follows="right|left"
use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_or_fee_box_exp" visible="false">
Sender: "Resident R e s i d e n t R e s i d e n t"
</text>
<text allow_scroll="false" font="SansSerifSmall" top="0" right="-1" width="95" height="13" follows="right" halign="right" layout="topleft" left_pad="5"
name="notification_time_exp" value="2014/12/24 23:30" />
</panel>
<panel border="false" left="0" height="115" width="230" bevel_style="none" follows="all" layout="topleft" name="notification_text_panel_exp" visible="true">
<chat_editor is_expandable="true" top="0" left="0" width="230" height="110" layout="topleft" follows="left|right"
word_wrap="true" max_length="65536" name="notification_text_exp" parse_urls="true">
Notice text goes here b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla. bla bla bla bla bla bla bla bla bla bla bla bla bla .
</chat_editor>
</panel>
<panel border="false" left="1" bottom="-5" width="230" height="22" bevel_style="none" follows="left|right|bottom" layout="topleft" name="attachment_panel" visible="false">
<text allow_scroll="false" font="SansSerifSmall" top="4" left="5" width="220" height="12" layout="topleft" follows="left|top|right|bottom"
use_ellipses="true" word_wrap="true" max_length="96" name="attachment_text">
Attachment goes here b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla. bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla .
</text>
</panel>
<panel border="false" left="1" bottom="-5" height="55" bevel_style="none" follows="left|right|bottom" layout="topleft" name="button_panel" visible="false">
<button top="2" left="0" width="65" height="23" layout="topleft" follows="left|top|bottom" name="join_btn" mouse_opaque="true" tab_stop="false" label = "Join"/>
<button top="2" left_pad="12" width="65" height="23" layout="topleft" follows="left|top|bottom" name="decline_btn" mouse_opaque="true" tab_stop="false" label = "Decline"/>
<button top="2" left_pad="12" width="65" height="23" layout="topleft" follows="left|top|bottom" name="info_btn" mouse_opaque="true" tab_stop="false" label = "Info"/>
</panel>
</panel>
</layout_panel>
<layout_panel width="18" orientation="horizontal" follows="right|top|bottom" name="layout_panel_left_exp">
<panel top="0" left="0" width="17" follows="left|top|right|bottom" layout="topleft" name="close_expand_panel_exp">
<button top="0" left="2" width="17" height="17" layout="topleft" follows="top" name="close_expanded_btn" mouse_opaque="true"
tab_stop="false" image_unselected="Icon_Close_Foreground" image_selected="Icon_Close_Press" />
<button bottom="5" left="0" width="17" height="17" layout="topleft" follows="bottom" name="condense_btn" mouse_opaque="true"
tab_stop="false" image_unselected="Notification_Condense" image_selected="Notification_Condense" />
</panel>
</layout_panel>
</layout_stack>
</panel>
</layout_panel>
</layout_stack>
</panel>
</panel>

View File

@ -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>