From e5d6a14f05f857ecbbbd9b464db3ece82d1d099f Mon Sep 17 00:00:00 2001 From: pavelk_productengine Date: Fri, 9 Jan 2015 20:17:39 +0200 Subject: [PATCH 01/29] MAINT-4734 (Separate transaction notices from group notice/invites) - initial version Works: 1) All new notices shown on "Invites" tab of new floater "NOTIFICATIONS TABBED" in condensed view To be done: 1) Show other types of notices, like transactions and system 2) Separate notices between tabs "Invites", "System", "Transactions" 3) Design full notice view (in addition to condensed view) --- indra/newview/CMakeLists.txt | 2 + indra/newview/llchannelmanager.cpp | 4 +- indra/newview/llchiclet.cpp | 10 +- indra/newview/llchicletbar.cpp | 4 +- .../newview/llfloaternotificationstabbed.cpp | 377 ++++++++++++++++++ indra/newview/llfloaternotificationstabbed.h | 143 +++++++ indra/newview/llsyswellitem.cpp | 80 ++++ indra/newview/llsyswellitem.h | 54 +++ indra/newview/llviewerfloaterreg.cpp | 6 +- .../textures/icons/Icon_Attachment_Large.png | Bin 0 -> 4182 bytes .../textures/icons/Icon_Attachment_Small.png | Bin 0 -> 3774 bytes .../textures/icons/Icon_Group_Large.png | Bin 0 -> 12280 bytes .../textures/icons/Icon_Group_Small.png | Bin 0 -> 4473 bytes .../icons/Icon_Notification_Condense.png | Bin 0 -> 262 bytes .../icons/Icon_Notification_Expand.png | Bin 0 -> 239 bytes .../skins/default/textures/textures.xml | 7 + .../xui/en/floater_notifications_tabbed.xml | 134 +++++++ .../default/xui/en/language_settings.xml | 2 +- .../skins/default/xui/en/menu_login.xml | 2 +- .../xui/en/panel_notification_tabbed_item.xml | 53 +++ 20 files changed, 870 insertions(+), 8 deletions(-) create mode 100644 indra/newview/llfloaternotificationstabbed.cpp create mode 100644 indra/newview/llfloaternotificationstabbed.h create mode 100644 indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png create mode 100644 indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png create mode 100644 indra/newview/skins/default/textures/icons/Icon_Group_Large.png create mode 100644 indra/newview/skins/default/textures/icons/Icon_Group_Small.png create mode 100644 indra/newview/skins/default/textures/icons/Icon_Notification_Condense.png create mode 100644 indra/newview/skins/default/textures/icons/Icon_Notification_Expand.png create mode 100644 indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml create mode 100644 indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e8f4144e70..b17811d644 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -262,6 +262,7 @@ set(viewer_SOURCE_FILES llfloatermodeluploadbase.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp + llfloaternotificationstabbed.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp llfloateroutbox.cpp @@ -870,6 +871,7 @@ set(viewer_HEADER_FILES llfloatermodeluploadbase.h llfloaternamedesc.h llfloaternotificationsconsole.h + llfloaternotificationstabbed.h llfloaterobjectweights.h llfloateropenobject.h llfloateroutbox.h diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index b0537a83f1..49a71b0018 100755 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -35,6 +35,7 @@ #include "llviewerwindow.h" #include "llrootview.h" #include "llsyswellwindow.h" +#include "llfloaternotificationstabbed.h" #include "llfloaterreg.h" #include @@ -131,7 +132,8 @@ 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(&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")); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index c0823182c0..6435c934b9 100755 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -35,6 +35,7 @@ #include "llscriptfloater.h" #include "llsingleton.h" #include "llsyswellwindow.h" +#include "llfloaternotificationstabbed.h" static LLDefaultChildRegistry::Register t1("chiclet_panel"); static LLDefaultChildRegistry::Register t2("chiclet_notification"); @@ -165,7 +166,8 @@ 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); + //LLNotificationWellWindow::getInstance()->setSysWellChiclet(this); + LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this); } void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) @@ -173,7 +175,8 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) std::string action = user_data.asString(); if("close all" == action) { - LLNotificationWellWindow::getInstance()->closeAll(); + //LLNotificationWellWindow::getInstance()->closeAll(); + LLFloaterNotificationsTabbed::getInstance()->closeAll(); LLIMWellWindow::getInstance()->closeAll(); } } @@ -224,7 +227,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())) ) { displayNotification = false; diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index 28e367fbe1..45510d0824 100755 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -31,6 +31,7 @@ #include "lllayoutstack.h" #include "llpaneltopinfobar.h" #include "llsyswellwindow.h" +#include "llfloaternotificationstabbed.h" namespace { @@ -59,7 +60,8 @@ BOOL LLChicletBar::postBuild() mToolbarStack = getChild("toolbar_stack"); mChicletPanel = getChild("chiclet_list"); - showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty()); + //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)); diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp new file mode 100644 index 0000000000..09f0a0ed5e --- /dev/null +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -0,0 +1,377 @@ +/** + * @file llfloaternotificationstabbed.cpp + * @brief // TODO + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" // 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), + mMessageList(NULL), + mSysWellChiclet(NULL), + NOTIFICATION_TABBED_ANCHOR_NAME("notification_well_panel"), + IM_WELL_ANCHOR_NAME("im_well_panel"), + mIsReshapedByUser(false) + +{ + setOverlapsScreenChannel(true); + mNotificationUpdates.reset(new NotificationTabbedChannel(this)); +} + +//--------------------------------------------------------------------------------- +BOOL LLFloaterNotificationsTabbed::postBuild() +{ + mMessageList = getChild("notification_list"); + + // get a corresponding channel + initChannel(); + BOOL rv = LLTransientDockableFloater::postBuild(); + + //LLNotificationWellWindow::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) +{ + if(mMessageList->removeItemByValue(id)) + { + if (NULL != mSysWellChiclet) + { + mSysWellChiclet->updateWidget(isWindowEmpty()); + } + reshapeWindow(); + } + 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) +{ + return mMessageList->getItemByValue(id); +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::initChannel() +{ + LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID( + LLUUID(gSavedSettings.getString("NotificationChannelUUID"))); + mChannel = dynamic_cast(channel); + if(NULL == mChannel) + { + LL_WARNS() << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << LL_ENDL; + } + + //LLSysWellWindow::initChannel(); + //--------------------------------------------------------------------------------- + if(mChannel) + { + mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2)); + } +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::setVisible(BOOL visible) +{ + //LLNotificationWellWindow::setVisible + //-------------------------- + if (visible) + { + // when Notification channel is cleared, storable toasts will be added into the list. + clearScreenChannels(); + } + //-------------------------- + if (visible) + { + if (NULL == getDockControl() && getDockTongue().notNull()) + { + setDockControl(new LLDockControl( + LLChicletBar::getInstance()->getChild(getAnchorViewName()), this, + getDockTongue(), LLDockControl::BOTTOM)); + } + } + + // do not show empty window + if (NULL == mMessageList || 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() +{ + // save difference between floater height and the list height to take it into account while calculating new window height + // it includes height from floater top to list top and from floater bottom and list bottom + static S32 parent_list_delta_height = getRect().getHeight() - mMessageList->getRect().getHeight(); + + if (!mIsReshapedByUser) // Don't reshape Well window, if it ever was reshaped by user. See EXT-5715. + { + S32 notif_list_height = mMessageList->getItemsRect().getHeight() + 2 * mMessageList->getBorderWidth(); + + LLRect curRect = getRect(); + + S32 new_window_height = notif_list_height + parent_list_delta_height; + + if (new_window_height > MAX_WINDOW_HEIGHT) + { + new_window_height = MAX_WINDOW_HEIGHT; + } + S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH : curRect.getWidth(); + + curRect.setLeftTopAndSize(curRect.mLeft, curRect.mTop, newWidth, new_window_height); + reshape(curRect.getWidth(), curRect.getHeight(), TRUE); + setRect(curRect); + } + + // update notification channel state + // update on a window reshape is important only when a window is visible and docked + if(mChannel && getVisible() && isDocked()) + { + mChannel->updateShowToastsState(); + } +} + +//--------------------------------------------------------------------------------- +bool LLFloaterNotificationsTabbed::isWindowEmpty() +{ + return mMessageList->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"); +} + +/* +LLFloaterNotificationsTabbed::LLNotificationWellWindow(const LLSD& key) + : LLSysWellWindow(key) +{ + mNotificationUpdates.reset(new NotificationTabbedChannel(this)); +} +*/ + +// static +LLFloaterNotificationsTabbed* LLFloaterNotificationsTabbed::getInstance(const LLSD& key /*= LLSD()*/) +{ + return LLFloaterReg::getTypedInstance("notification_well_window", key); +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::addItem(LLNotificationTabbedItem::Params p) +{ + LLSD value = p.notification_id; + // do not add clones + if( mMessageList->getItemByValue(value)) + return; + + LLNotificationTabbedItem* new_item = new LLNotificationTabbedItem(p); + if (mMessageList->addItem(new_item, value, ADD_TOP)) + { + mSysWellChiclet->updateWidget(isWindowEmpty()); + reshapeWindow(); + new_item->setOnItemCloseCallback(boost::bind(&LLFloaterNotificationsTabbed::onItemClose, this, _1)); + new_item->setOnItemClickCallback(boost::bind(&LLFloaterNotificationsTabbed::onItemClick, this, _1)); + } + else + { + LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id + << ", title: " << p.title + << LL_ENDL; + + new_item->die(); + } +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::closeAll() +{ + // Need to clear notification channel, to add storable toasts into the list. + clearScreenChannels(); + std::vector items; + mMessageList->getItems(items); + for (std::vector::iterator + iter = items.begin(), + iter_end = items.end(); + iter != iter_end; ++iter) + { + LLNotificationTabbedItem* sys_well_item = dynamic_cast(*iter); + if (sys_well_item) + onItemClose(sys_well_item); + } +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS +//void LLFloaterNotificationsTabbed::initChannel() +//{ +// LLFloaterNotificationsTabbed::initChannel(); +// if(mChannel) +// { +// mChannel->addOnStoreToastCallback(boost::bind(&LLFloaterNotificationsTabbed::onStoreToast, this, _1, _2)); +// } +//} + +//--------------------------------------------------------------------------------- +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) +{ + LLNotificationTabbedItem::Params p; + p.notification_id = id; + p.title = static_cast(info_panel)->getTitle(); + LLNotificationsUI::LLToast* toast = mChannel->getToastByNotificationID(id); + LLSD payload = toast->getNotification()->getPayload(); + LLDate time_stamp = toast->getNotification()->getDate(); + p.group_id = payload["group_id"]; + p.sender = payload["name"]; + p.time_stamp = time_stamp; + addItem(p); +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::onItemClick(LLNotificationTabbedItem* item) +{ + LLUUID id = item->getID(); + LLFloaterReg::showInstance("inspect_toast", id); +} + +//--------------------------------------------------------------------------------- +void LLFloaterNotificationsTabbed::onItemClose(LLNotificationTabbedItem* 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 LLFloaterNotificationsTabbed::onAdd( LLNotificationPtr notify ) +{ + removeItemByID(notify->getID()); +} diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h new file mode 100644 index 0000000000..1fd60826cb --- /dev/null +++ b/indra/newview/llfloaternotificationstabbed.h @@ -0,0 +1,143 @@ +/** + * @file llfloaternotificationstabbed.h + * @brief // TODO + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATERNOTIFICATIONSTABBED_H +#define LL_FLOATERNOTIFICATIONSTABBED_H + +#include "llimview.h" +#include "llnotifications.h" +#include "llscreenchannel.h" +#include "llsyswellitem.h" +#include "lltransientdockablefloater.h" + +class LLAvatarName; +class LLChiclet; +class LLFlatListView; +class LLIMChiclet; +class LLScriptChiclet; +class LLSysWellChiclet; + +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); + LLPanel * findItemByID(const LLUUID& id); + + // Operating with outfit + virtual void setVisible(BOOL visible); + void adjustWindowPosition();//not used - ? + + /*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); + + void setSysWellChiclet(LLSysWellChiclet* chiclet); + + // size constants for the window and for its elements + static const S32 MAX_WINDOW_HEIGHT = 200; + static const S32 MIN_WINDOW_WIDTH = 318; + +protected: + // 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; + LLFlatListView* mMessageList; + + /** + * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147 + */ + LLSysWellChiclet* mSysWellChiclet; + + bool mIsReshapedByUser; + +public: + static LLFloaterNotificationsTabbed* getInstance(const LLSD& key = LLSD()); + + /*virtual*/ //BOOL postBuild(); + /*virtual*/ //void setVisible(BOOL visible); + /*virtual*/ void onAdd(LLNotificationPtr notify); + // Operating with items + void addItem(LLNotificationTabbedItem::Params p); + + // Closes all notifications and removes them from the Notification Well + void closeAll(); + +protected: + struct NotificationTabbedChannel : public LLNotificationChannel + { + NotificationTabbedChannel(LLFloaterNotificationsTabbed*); + void onDelete(LLNotificationPtr notify) + { + mNotificationsTabbedWindow->removeItemByID(notify->getID()); + } + + LLFloaterNotificationsTabbed* mNotificationsTabbedWindow; + }; + + LLNotificationChannelPtr mNotificationUpdates; + virtual const std::string& getAnchorViewName() { return NOTIFICATION_TABBED_ANCHOR_NAME; } + +private: + // init Window's channel + // void initChannel(); + void clearScreenChannels(); + + void onStoreToast(LLPanel* info_panel, LLUUID id); + + // Handlers + void onItemClick(LLNotificationTabbedItem* item); + void onItemClose(LLNotificationTabbedItem* item); + + // ID of a toast loaded by user (by clicking notification well item) + LLUUID mLoadedToastId; +}; + +#endif // LL_FLOATERNOTIFICATIONSTABBED_H + + + diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp index 057d80457c..bc8333d5fc 100755 --- a/indra/newview/llsyswellitem.cpp +++ b/indra/newview/llsyswellitem.cpp @@ -31,6 +31,7 @@ #include "llwindow.h" #include "v4color.h" +#include "lltrans.h" #include "lluicolortable.h" //--------------------------------------------------------------------------------- @@ -90,4 +91,83 @@ void LLSysWellItem::onMouseLeave(S32 x, S32 y, MASK mask) //--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- +LLNotificationTabbedItem::LLNotificationTabbedItem(const Params& p) : LLPanel(p), + mTitle(NULL), + mSender(NULL), + mCloseBtn(NULL) +{ + buildFromFile( "panel_notification_tabbed_item.xml"); + mTitle = getChild("GroupName_NoticeTitle"); + mSender = getChild("Sender_Resident"); + mTimeBox = getChild("Time_Box"); + mGroupIcon = getChild("group_icon_small"); + mCloseBtn = getChild("close_btn"); + + mTitle->setValue(p.title); + mSender->setValue("Sender: " + p.sender); + mTimeBox->setValue(buildNotificationDate(p.time_stamp)); + mGroupIcon->setValue(p.group_id); + + mCloseBtn->setClickedCallback(boost::bind(&LLNotificationTabbedItem::onClickCloseBtn,this)); + + mID = p.notification_id; +} + +//--------------------------------------------------------------------------------- +LLNotificationTabbedItem::~LLNotificationTabbedItem() +{ +} + +//--------------------------------------------------------------------------------- +//static +std::string LLNotificationTabbedItem::buildNotificationDate(const LLDate& time_stamp) +{ + std::string timeStr = "[" + LLTrans::getString("LTimeMthNum") + "]/[" + +LLTrans::getString("LTimeDay")+"]/[" + +LLTrans::getString("LTimeYear")+"] [" + +LLTrans::getString("LTimeHour")+"]:[" + +LLTrans::getString("LTimeMin")+"]"; + + LLSD substitution; + substitution["datetime"] = time_stamp; + LLStringUtil::format(timeStr, substitution); + return timeStr; +} + +//--------------------------------------------------------------------------------- +void LLNotificationTabbedItem::setTitle( std::string title ) +{ + mTitle->setValue(title); +} + +//--------------------------------------------------------------------------------- +void LLNotificationTabbedItem::onClickCloseBtn() +{ + mOnItemClose(this); +} + +//--------------------------------------------------------------------------------- +BOOL LLNotificationTabbedItem::handleMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL res = LLPanel::handleMouseDown(x, y, mask); + if(!mCloseBtn->getRect().pointInRect(x, y)) + //if(!mCloseBtn->getRect().pointInRect(x, y)) + //if(!mCloseBtn->getLocalRect().pointInRect(x, y)) + mOnItemClick(this); + + return res; +} + +//--------------------------------------------------------------------------------- +void LLNotificationTabbedItem::onMouseEnter(S32 x, S32 y, MASK mask) +{ + //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemSelected" )); +} + +//--------------------------------------------------------------------------------- +void LLNotificationTabbedItem::onMouseLeave(S32 x, S32 y, MASK mask) +{ + //setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" )); +} diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h index d961708a01..4379b8dc22 100755 --- a/indra/newview/llsyswellitem.h +++ b/indra/newview/llsyswellitem.h @@ -32,6 +32,8 @@ #include "llbutton.h" #include "lliconctrl.h" +#include "llgroupmgr.h" + #include class LLSysWellItem : public LLPanel @@ -76,6 +78,58 @@ private: LLUUID mID; }; +class LLNotificationTabbedItem : public LLPanel +{ +public: + struct Params : public LLInitParam::Block + { + LLUUID notification_id; + LLUUID group_id; + std::string title; + std::string sender; + LLDate time_stamp; + Params() {}; + }; + + + LLNotificationTabbedItem(const Params& p); + virtual ~LLNotificationTabbedItem(); + + // title + void setTitle( std::string title ); + void setGroupID(const LLUUID& group_id); + void setGroupIconID(const LLUUID& group_icon_id); + void setGroupName(const std::string& group_name); + + // get item's ID + LLUUID getID() { return mID; } + + // handlers + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual void onMouseEnter(S32 x, S32 y, MASK mask); + virtual void onMouseLeave(S32 x, S32 y, MASK mask); + + //callbacks + typedef boost::function item_callback_t; + typedef boost::signals2::signal item_signal_t; + item_signal_t mOnItemClose; + item_signal_t mOnItemClick; + boost::signals2::connection setOnItemCloseCallback(item_callback_t cb) { return mOnItemClose.connect(cb); } + boost::signals2::connection setOnItemClickCallback(item_callback_t cb) { return mOnItemClick.connect(cb); } + +private: + static std::string buildNotificationDate(const LLDate&); + void onClickCloseBtn(); + + LLTextBox* mTitle; + LLTextBox* mSender; + LLTextBox* mTimeBox; + LLIconCtrl* mGroupIcon; + LLButton* mCloseBtn; + LLUUID mID; + LLUUID mGroupID; +}; + #endif // LL_LLSYSWELLITEM_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index e19fe9ca75..d20b8e342a 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -85,6 +85,7 @@ #include "llfloatermodelpreview.h" #include "llfloaternamedesc.h" #include "llfloaternotificationsconsole.h" +#include "llfloaternotificationstabbed.h" #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutbox.h" @@ -255,7 +256,10 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + + LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + //LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + //LLFloaterReg::add("notifications_tabbed", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png b/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png new file mode 100644 index 0000000000000000000000000000000000000000..0732a33d933b3ed6f8f7c62ea2a31f0656b3392f GIT binary patch literal 4182 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 literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png b/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png new file mode 100644 index 0000000000000000000000000000000000000000..81245549022bde22e658b3efe4ecb26b7cffc2a7 GIT binary patch literal 3774 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 literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/icons/Icon_Group_Large.png b/indra/newview/skins/default/textures/icons/Icon_Group_Large.png new file mode 100644 index 0000000000000000000000000000000000000000..6dc0cbda0b062692d0defa18749563e9e505dadc GIT binary patch literal 12280 zcmV004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000Uv 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 IbxsLQ0Lc4c^Z)<= literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/icons/Icon_Notification_Expand.png b/indra/newview/skins/default/textures/icons/Icon_Notification_Expand.png new file mode 100644 index 0000000000000000000000000000000000000000..186822da431c71df9f504ea1b76a43ff50b2ce3b GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^{2yt6-|LxnicRPwEX0V)8T%CF-jd>TNhg2X#+gT620@lo?tdgV4+61Q@YN)$o mdF1iTn6qz|WU+A=Fnr1LnRx4;*ioS47(8A5T-G@yGywprieB3Q literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1f10d966d5..0744962064 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -795,4 +795,11 @@ with the same filename but different name + + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml new file mode 100644 index 0000000000..b627707056 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml @@ -0,0 +1,134 @@ + + + + NOTIFICATIONS TABBED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml index 51779e4bfd..3ad0f04469 100755 --- a/indra/newview/skins/default/xui/en/language_settings.xml +++ b/indra/newview/skins/default/xui/en/language_settings.xml @@ -50,7 +50,7 @@ second,datetime,local hour,datetime,local min,datetime,local - year,datetime,local + year,datetime,local weekday,datetime,utc day,datetime,utc diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index e91eea04d1..0d9612990d 100755 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -303,7 +303,7 @@ + + + + + + + + + + + + + Group Name:Notice Title + + + + + + Sender.Resident + + + + + + + + - + - diff --git a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml b/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml index bc4f90858b..603a3312e0 100644 --- a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml +++ b/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml @@ -2,8 +2,8 @@ + + Sender: "[SENDER_RESIDENT]" + @@ -24,16 +28,16 @@ - - Group Name:Notice Title + Group Name:Notice Title N o t i c e T i t l e N o t i c e T i t l e N o t i c e T i t l e N oticeTitle - + - Sender.Resident + Sender:Resident diff --git a/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml b/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml new file mode 100644 index 0000000000..150225af27 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/notification_list_view.xml @@ -0,0 +1,18 @@ + + + + \ No newline at end of file From 5f96f3bba20fcacbe7115b7d27bc50cad56850d4 Mon Sep 17 00:00:00 2001 From: pavelkproductengine Date: Wed, 4 Feb 2015 15:48:22 +0200 Subject: [PATCH 04/29] MAINT-4734 (Separate transaction notices from group notice/invites) - fixed Mac build --- indra/newview/llnotificationlistitem.cpp | 2 +- indra/newview/llnotificationlistitem.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index a55c7b8541..4fdd6b1a54 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -179,7 +179,7 @@ LLInviteNotificationListItem::LLInviteNotificationListItem(const Params& p) if (!p.sender.empty()) { LLStringUtil::format_map_t string_args; - string_args["[SENDER_RESIDENT]"] = llformat("%s", p.sender); + string_args["[SENDER_RESIDENT]"] = llformat("%s", p.sender.c_str()); std::string sender_text = getString("sender_resident_text", string_args); mSenderBox->setValue(sender_text); mSenderBox->setVisible(TRUE); diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index bc77d873a4..89de0487be 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -60,8 +60,8 @@ public: // get item's ID LLUUID getID() { return mID; } - std::string getTitle() { return mTitle; } - std::string getNotificationName() { return mNotificationName; } + std::string& getTitle() { return mTitle; } + std::string& getNotificationName() { return mNotificationName; } // handlers virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); From 9d8bbe16007ef9292a04856f55f71016cf1220bf Mon Sep 17 00:00:00 2001 From: pavelk_productengine Date: Tue, 10 Feb 2015 19:56:32 +0200 Subject: [PATCH 05/29] MAINT-4734 (Separate transaction notices from group notice/invites) - introduced different design for System, Incoming/Outcoming Transactions, Invites --- indra/newview/llnotificationlistitem.cpp | 126 ++++++++++++------ indra/newview/llnotificationlistitem.h | 14 +- .../icons/Incoming_Transaction_Small.png | Bin 0 -> 1666 bytes .../icons/Outcoming_Transaction_Small.png | Bin 0 -> 1322 bytes .../icons/System_Notification_Small.png | Bin 0 -> 661 bytes .../skins/default/textures/textures.xml | 3 + ...m.xml => panel_notification_list_item.xml} | 31 +++-- 7 files changed, 115 insertions(+), 59 deletions(-) create mode 100644 indra/newview/skins/default/textures/icons/Incoming_Transaction_Small.png create mode 100644 indra/newview/skins/default/textures/icons/Outcoming_Transaction_Small.png create mode 100644 indra/newview/skins/default/textures/icons/System_Notification_Small.png rename indra/newview/skins/default/xui/en/{panel_notification_tabbed_item.xml => panel_notification_list_item.xml} (66%) diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 4fdd6b1a54..7f0e3460b1 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -35,27 +35,28 @@ #include "lluicolortable.h" LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p), + mParams(p), mTitleBox(NULL), - mCloseBtn(NULL), - mSenderBox(NULL) + mCloseBtn(NULL) { - buildFromFile( "panel_notification_tabbed_item.xml"); - - mTitleBox = getChild("GroupName_NoticeTitle"); - mTimeBox = getChild("Time_Box"); - mCloseBtn = getChild("close_btn"); - mSenderBox = getChild("Sender_Resident"); - - mTitleBox->setValue(p.title); - mTimeBox->setValue(buildNotificationDate(p.time_stamp)); - mSenderBox->setVisible(FALSE); - - mCloseBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCloseBtn,this)); - mID = p.notification_id; mNotificationName = p.notification_name; } +BOOL LLNotificationListItem::postBuild() +{ + BOOL rv = LLPanel::postBuild(); + mTitleBox = getChild("notification_title"); + mTimeBox = getChild("notification_time"); + mCloseBtn = getChild("close_btn"); + + mTitleBox->setValue(mParams.title); + mTimeBox->setValue(buildNotificationDate(mParams.time_stamp)); + + mCloseBtn->setClickedCallback(boost::bind(&LLNotificationListItem::onClickCloseBtn,this)); + return rv; +} + LLNotificationListItem::~LLNotificationListItem() { } @@ -151,46 +152,87 @@ std::set LLTransactionNotificationListItem::getTypes() std::set LLSystemNotificationListItem::getTypes() { std::set types; - types.insert("AddPrimitiveFailure"); - types.insert("AddToNavMeshNoCopy"); - types.insert("AssetServerTimeoutObjReturn"); - types.insert("AvatarEjected"); - types.insert("AutoUnmuteByIM"); - types.insert("AutoUnmuteByInventory"); - types.insert("AutoUnmuteByMoney"); - types.insert("BuyInventoryFailedNoMoney"); - types.insert("DeactivatedGesturesTrigger"); - types.insert("DeedFailedNoPermToDeedForGroup"); - types.insert("WhyAreYouTryingToWearShrubbery"); - types.insert("YouDiedAndGotTPHome"); - types.insert("YouFrozeAvatar"); - - types.insert("OfferCallingCard"); - //ExpireExplanation + //types.insert("AddPrimitiveFailure"); + //types.insert("AddToNavMeshNoCopy"); + //types.insert("AssetServerTimeoutObjReturn"); + //types.insert("AvatarEjected"); + //types.insert("AutoUnmuteByIM"); + //types.insert("AutoUnmuteByInventory"); + //types.insert("AutoUnmuteByMoney"); + //types.insert("BuyInventoryFailedNoMoney"); + //types.insert("DeactivatedGesturesTrigger"); + //types.insert("DeedFailedNoPermToDeedForGroup"); + //types.insert("WhyAreYouTryingToWearShrubbery"); + //types.insert("YouDiedAndGotTPHome"); + //types.insert("YouFrozeAvatar"); + //types.insert("OfferCallingCard"); return types; } LLInviteNotificationListItem::LLInviteNotificationListItem(const Params& p) - : LLNotificationListItem(p) + : LLNotificationListItem(p), + mSenderBox(NULL) { - mGroupIcon = getChild("group_icon_small"); - mGroupIcon->setValue(p.group_id); - mGroupID = p.group_id; - if (!p.sender.empty()) + buildFromFile("panel_notification_list_item.xml"); +} + +BOOL LLInviteNotificationListItem::postBuild() +{ + BOOL rv = LLNotificationListItem::postBuild(); + mGroupIcon = getChild("group_icon"); + mGroupIcon->setValue(mParams.group_id); + mGroupIcon->setVisible(TRUE); + mGroupID = mParams.group_id; + mSenderBox = getChild("sender_resident"); + if (!mParams.sender.empty()) { LLStringUtil::format_map_t string_args; - string_args["[SENDER_RESIDENT]"] = llformat("%s", p.sender.c_str()); + string_args["[SENDER_RESIDENT]"] = llformat("%s", mParams.sender.c_str()); std::string sender_text = getString("sender_resident_text", string_args); mSenderBox->setValue(sender_text); mSenderBox->setVisible(TRUE); - } + } else { + mSenderBox->setVisible(FALSE); + } + return rv; } LLTransactionNotificationListItem::LLTransactionNotificationListItem(const Params& p) - : LLNotificationListItem(p) -{} + : LLNotificationListItem(p), + mTransactionIcon(NULL) +{ + buildFromFile("panel_notification_list_item.xml"); +} + +BOOL LLTransactionNotificationListItem::postBuild() +{ + BOOL rv = LLNotificationListItem::postBuild(); + if (mParams.notification_name == "PaymentReceived") + { + mTransactionIcon = getChild("incoming_transaction_icon"); + } + else if (mParams.notification_name == "PaymentSent") + { + mTransactionIcon = getChild("outcoming_transaction_icon"); + } + if(mTransactionIcon) + mTransactionIcon->setVisible(TRUE); + return rv; +} LLSystemNotificationListItem::LLSystemNotificationListItem(const Params& p) - :LLNotificationListItem(p) -{} + : LLNotificationListItem(p), + mSystemNotificationIcon(NULL) +{ + buildFromFile("panel_notification_list_item.xml"); +} + +BOOL LLSystemNotificationListItem::postBuild() +{ + BOOL rv = LLNotificationListItem::postBuild(); + mSystemNotificationIcon = getChild("system_notification_icon"); + if (mSystemNotificationIcon) + mSystemNotificationIcon->setVisible(TRUE); + return rv; +} diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index 89de0487be..da6d792fb8 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -30,7 +30,7 @@ #include "llpanel.h" #include "lltextbox.h" #include "llbutton.h" -#include "lliconctrl.h" +#include "llgroupiconctrl.h" #include "llgroupmgr.h" @@ -76,6 +76,7 @@ public: 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 postBuild(); protected: LLNotificationListItem(const Params& p); virtual ~LLNotificationListItem(); @@ -83,13 +84,13 @@ protected: static std::string buildNotificationDate(const LLDate&); void onClickCloseBtn(); + Params mParams; LLTextBox* mTitleBox; LLTextBox* mTimeBox; LLButton* mCloseBtn; LLUUID mID; std::string mTitle; std::string mNotificationName; - LLTextBox* mSenderBox; }; class LLInviteNotificationListItem : public LLNotificationListItem @@ -99,36 +100,43 @@ public: //void setGroupIconID(const LLUUID& group_icon_id); //void setGroupName(const std::string& group_name); static std::set getTypes(); + + virtual BOOL postBuild(); private: friend class LLNotificationListItem; LLInviteNotificationListItem(const Params& p); LLInviteNotificationListItem(const LLInviteNotificationListItem &); LLInviteNotificationListItem & operator=(LLInviteNotificationListItem &); - LLIconCtrl* mGroupIcon; + LLGroupIconCtrl* mGroupIcon; LLUUID mGroupID; + LLTextBox* mSenderBox; }; class LLTransactionNotificationListItem : public LLNotificationListItem { public: static std::set getTypes(); + virtual BOOL postBuild(); private: friend class LLNotificationListItem; LLTransactionNotificationListItem(const Params& p); LLTransactionNotificationListItem(const LLTransactionNotificationListItem &); LLTransactionNotificationListItem & operator=(LLTransactionNotificationListItem &); + LLIconCtrl* mTransactionIcon; }; class LLSystemNotificationListItem : public LLNotificationListItem { public: static std::set getTypes(); + virtual BOOL postBuild(); private: friend class LLNotificationListItem; LLSystemNotificationListItem(const Params& p); LLSystemNotificationListItem(const LLSystemNotificationListItem &); LLSystemNotificationListItem & operator=(LLSystemNotificationListItem &); + LLIconCtrl* mSystemNotificationIcon; }; #endif // LL_LLNOTIFICATIONLISTITEM_H diff --git a/indra/newview/skins/default/textures/icons/Incoming_Transaction_Small.png b/indra/newview/skins/default/textures/icons/Incoming_Transaction_Small.png new file mode 100644 index 0000000000000000000000000000000000000000..8b39770c63e3bc264ee9b1f36546ff7b9561f0b8 GIT binary patch literal 1666 zcmV-|27UR7P)P000>X1^@s6#OZ}&00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;VI^GGzb&1@lQnK~zXftyXDlR80cTi3yv4{t+pAKv`M~)fg}egrdbi{E);%ahox7axobQ}_?`S3k6nPnj0gJ^Vs?w$Dx~}xesVV51 z4y)Djuel9l>BQzDV>?C=>@c{rxG}Z8jt%Sfh*BZ?#(S&DUS4@yW?a zL?V$mfULb+*Tt(Tdg*jJRfmWeaX1{)8Za<00Ebma%0sh|Hv3`qb|zSGp}${^+mr(d z>RZHax5ssH*eYn!`QgC>sQ>Yd@SusV)dG}(RngykuMXku6qsV8XGY-;a zrpIMB=cGKM+Pt(B)9tjIvi5#bT~(>WvKz@HlN)U$IevhQnb}HLkv6GGoRJ zdLN}oBA^XLUn0G~S7K||Z>WIVk$|&j>q(bpB4Pkb7niF+0dcup>bs-84Mq96s3hlZ zk0)Av0zg2I+l}}3RpY58PvY{WOKSea#6-Mc7MGR)TC`eqRvPA|dT{n!JIYH+{!vvn zn*%NF0sMabno6cbpfMlPq*%oGsWbHmhJva>rB9+QEh^-?F3e4Jvy|!7RM^C$vw({y ziU`z-a`Av7weQRJp}V^aw{P8o!Kx98q{)Vqi0|CFgWjGVq^D=7eIo!Rg@tHp>BRMu z1xQOaAog|cYm5a=r1=c=)D`1wQwvIqi&WW)_4~O^qQ42<=k?q<;j+%{I{eNtpsFE+|km zh%8J`M?-TP7Lb}>ejDJ%`@6F8b92$!PJrVj3cws=XNV>Ze$%v~E6mL%Ac?}zC@Gq6 zqNBE)p0%Nv9LFTn>&5AYMnyqP3JB01IFCL7SSX&-1OZ@|QCg>MMHi!GDM=>~46}_I z@Gr4o<+2Pkx3;2)5yeDu5j&UibNy%w1hDq`3}lutVp23h0GABYrT|3gB8VY%Or+qH zFlWM%W<$mHK^!{SkGEDWLJK1*$jeiPV|&P-lfwu)v2$e(4xac4TXzis57-DmqtPP` zJmr)<-QYt7F97^GAG2Y@o*}$b*NdZDbFuA>By`u6p{*mJ670>)Qt!^L9_FA7+t+(= zc#|KyYx}VI{UKOVgc4c|Y07y8B6>t}LdD4l-rPNi>f-{Ck5``Kg6m=U=9;*6vJB6Z zreS>KPdr^Z2RA=2gO_EBYg1Uh%!Q9OF2depz1UPW2#pcNaw0)k#d~$N2*8FL*mt}S zN4Del2IDd4Q4#^H?6MZZQIO(y4rvN4l zP000>X0ssI2ON$aT00004XF*Lt006O% z3;baP00009a7bBm000tm000tm0gNKK2LJ#77<5HgbW?9;ba!ELWdLwtX>N2bZe?^J zG%heMHD!e|WdHyKs7XXYR7gvemD^7obri?vL0IlA>@s_q%WrmO_Qoy?lr1nop`loz zP@t$SD6rXuU=$OHnivuqVneF2w#3?(Ce}jxM_8a--hIFtM51X3Aq^?_5D*X$zq3OJ zY<M(j8931TL@4w1>dwV-OJNNH>x3#qe#!uQh5?*E1g`16y z4ecHUU^V6N5SF#Iwb~1BcqO4EKe)8Cq^)m9FO4@hH<6|>1%)oc>gwvM#>ie+SSUYJ z;&u>^NIa5In3uD@zK&x3VE|o%3=DFEfC3wmua4rY$ zcJL|)TwcIGH#hfwM>}$qU~c}Y?4n>^B-A=PJFB|zaIY-NgvImyZaK^2Dp3k1Cnt0K zKAC5ogmVfUK<9wZ^YrQOr9}nEM7~qtvFMeh#l=M`)clUfGnX6cu~TRjJ!6o*YoCi8 zBk>3p5M@^9-m5+OXe%o#4Ry6x3^g}V!JL4=+R>dZ0_^VYJ{%mZdcDHI+7KdVM*ynN zpC23;&~k7Akcp`YV-03!QQ1B($nSANrzb&*eeH-u@RPvW5CB9Z9KzmfIhqJnKBtUs za{QT8md_h-*(6TYEiW(YB0xtZ%-gLzW94iX1Y8|$k*G&KK~3b5C8uD^_1NK|{F&}c zW#osi0uF}uI;HvfdHu-SB4H?4D~-@}?cvZ#kz2x{Sto91zj>C2hw^*f4QKhk#+8v< zSpq|Qoa%|70JDTzo9&hi1YC@j24F^gG^Z#?yk+9sY}7WCaXycW^17V$r7Z6Me5{~5 z-ez`64s55oU+rzS43ny(%>YC=)T)VOfruQ9j!<|ouGE+DnQql3*PUS@+8$A~?l_xS z76o+o+ssUPS!rppQd(4mC@(9Uo}PwCB1B*^CT<5*(U|hbuu@yX!b7=bsiv6GM2OwT z%A*@u44p0#9&fY$9_gcrgd=wI#5YmVxGLHog^O`XBIS~$izSRM+8M#43Y#hz+LR^< z{NnTHCq;y?v?;x{lG`6U7NPKBiCuL`qNBRVc2e}o6=F^^b~X^JIhAnilgUYlFdfG* z44u~5z?+OI-7Su-p(7E-tS+|8QI~K*v1+2d(ZY|f5R)}if#pbanNK&SXd=Y+u=3;G?8bAppeMbt zg8AuQuG$4g8&Ym{O2(9=?sv)NBL(wT6V&Me-~-R{}h4ojqa{RNPL_D9;&ae zFU}Bq+M7Ds@B8_F?$ki;%tJMve4qQvpbEb}PK39Ip?5otfuKf#Hkm*VX@y z+M1e}nAZ%3SVL@VY)lLy&VajP1|4%0UgAr2b?_YhKTb_ep~0)stEZ=@w^zd`AK}Za g0jf}|Dh?0-20z%Ql2H)+Jpcdz07*qoM6N<$g66_(WB>pF literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/icons/System_Notification_Small.png b/indra/newview/skins/default/textures/icons/System_Notification_Small.png new file mode 100644 index 0000000000000000000000000000000000000000..027a8446d89a6838de4c25b0c8f8a059d7600ed6 GIT binary patch literal 661 zcmV;G0&4wP000>X1^@s6#OZ}&00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0xC&FK~zXf-IhJC zF;Ni5$Ai%5M4?fLm&z9q5ky1y5E2C{QD}t3M^TfI5JDvc6+H!s1c^o{boTCyv9atf zx46yoOJvS}&YYQZ&g^dJ1QGaS{;~a2J{DQ6R!}Guz~}RU$z%eZP6uYQnKb%w{u8Q2 z+U+(abi3VfI-Q_YD#2p0fbDh*^ZA@K`f(oPFkThx$t&VQ?2|B?&Df(2#$i0JQ{t@% z1}BqAR&u)CF3tCPJ@&}KbxQk|T~{O$fp9nstyYUYa>RJDx7&^EE4VHc3Q-;z_gaE* zI2;sr@yuj0p%}DUU<~GaAf2RKE<-k(Wu=VKXp~tsFi)jYVfFNMjmKk%Mx(5hu~;lJ zs|M!5d=I1|;;HCS)Z*JBnCH1~QW3x35B+|hl`?w0o~*%OAgjh;Fra)A_tpr)Znyi` zcqEg_@JJoZv)}JoiJC1D3eFoz&-syC*M~-R}@LF&o{))vSd*$SEIVq;u zY_j(q)glju!yzSkMSLLzm&+w=HXHV+Bl~tKaXz2HEMIQS|BoZ_}9*?AdgXVSR^Len_?Q}h2a;yectCeTJ vN3)2{W`pbX3S#qNI-Roj_xvw^i2!~8oAoO7bM8ny00000NkvXXu0mjfiR3JC literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 0744962064..66fe119848 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -801,5 +801,8 @@ with the same filename but different name + + + diff --git a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml b/indra/newview/skins/default/xui/en/panel_notification_list_item.xml similarity index 66% rename from indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml rename to indra/newview/skins/default/xui/en/panel_notification_list_item.xml index 603a3312e0..9bd9742a20 100644 --- a/indra/newview/skins/default/xui/en/panel_notification_tabbed_item.xml +++ b/indra/newview/skins/default/xui/en/panel_notification_list_item.xml @@ -2,8 +2,8 @@ - + - - + + + + + - - - + + + + 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 - + + use_ellipses="true" word_wrap="true" mouse_opaque="false" name="sender_resident" visible="false"> Sender:Resident + name="notification_time" right="-5" value="2014/12/24 23:30" /> - - + + @@ -118,48 +118,4 @@ - - - - diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index ecedb27438..2c5176cf01 100755 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -23,10 +23,6 @@ name="title_im_well_window"> CONVERSATIONS - - NOTIFICATIONS - second,datetime,local hour,datetime,local min,datetime,local - year,datetime,local + year,datetime,local weekday,datetime,utc day,datetime,utc diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 0d9612990d..e91eea04d1 100755 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -303,7 +303,7 @@ - - - + + - 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 - - - Sender:Resident + + Sender: "Resident R e s i d e n t R e s i d e n t" @@ -76,19 +74,17 @@ - - - - - - + + + + - Notice Title Notice Title N o t i c e T i t l e + 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 @@ -96,27 +92,20 @@ - Sender: "Resident R e s i d e n t R e s i d e n t" - 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 . - - - 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 . - - From 60d28437e616a6afda51a368ea40ad49a707d16c Mon Sep 17 00:00:00 2001 From: pavelk_productengine Date: Wed, 8 Apr 2015 19:51:39 +0300 Subject: [PATCH 09/29] MAINT-4734 (Separate transaction notices from group notice/invites) 1) added GroupNotice notification type and tab "Group" for it; 2) added Attachment field to group notice notifications which may contain inventory offers, notecards, etc; 3) added Fee field to Group Invite notifications; 4) added notification resize depending on attachment field. --- .../newview/llfloaternotificationstabbed.cpp | 24 ++- indra/newview/llfloaternotificationstabbed.h | 3 +- indra/newview/llnotificationlistitem.cpp | 166 ++++++++++++++---- indra/newview/llnotificationlistitem.h | 82 +++++++-- indra/newview/lltoastgroupnotifypanel.cpp | 2 +- indra/newview/llviewermessage.cpp | 1 + .../skins/default/textures/textures.xml | 2 + .../xui/en/floater_notifications_tabbed.xml | 29 ++- .../xui/en/panel_notification_list_item.xml | 69 +++++--- 9 files changed, 289 insertions(+), 89 deletions(-) diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp index 05a0af01ce..fd5f1486d9 100644 --- a/indra/newview/llfloaternotificationstabbed.cpp +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -41,7 +41,8 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LLTransientDockableFloater(NULL, true, key), mChannel(NULL), mSysWellChiclet(NULL), - mInviteMessageList(NULL), + mGroupInviteMessageList(NULL), + mGroupNoticeMessageList(NULL), mTransactionMessageList(NULL), mSystemMessageList(NULL), mNotificationsSeparator(NULL), @@ -59,10 +60,12 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL //--------------------------------------------------------------------------------- BOOL LLFloaterNotificationsTabbed::postBuild() { - mInviteMessageList = getChild("invite_notification_list"); + mGroupInviteMessageList = getChild("group_invite_notification_list"); + mGroupNoticeMessageList = getChild("group_notice_notification_list"); mTransactionMessageList = getChild("transaction_notification_list"); mSystemMessageList = getChild("system_notification_list"); - mNotificationsSeparator->initTaggedList(LLNotificationListItem::getInviteTypes(), mInviteMessageList); + mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupInviteTypes(), mGroupInviteMessageList); + mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupNoticeTypes(), mGroupNoticeMessageList); mNotificationsSeparator->initTaggedList(LLNotificationListItem::getTransactionTypes(), mTransactionMessageList); mNotificationsSeparator->initUnTaggedList(mSystemMessageList); mNotificationsTabContainer = getChild("notifications_tab_container"); @@ -257,7 +260,8 @@ void LLFloaterNotificationsTabbed::updateNotificationCounters() { updateNotificationCounter(0, mSystemMessageList->size(), "system_tab_title"); updateNotificationCounter(1, mTransactionMessageList->size(), "transactions_tab_title"); - updateNotificationCounter(2, mInviteMessageList->size(), "invitations_tab_title"); + updateNotificationCounter(2, mGroupInviteMessageList->size(), "group_invitations_tab_title"); + updateNotificationCounter(3, mGroupNoticeMessageList->size(), "group_notices_tab_title"); } //--------------------------------------------------------------------------------- @@ -316,7 +320,10 @@ void LLFloaterNotificationsTabbed::getAllItemsOnCurrentTab(std::vector mTransactionMessageList->getItems(items); break; case 2: - mInviteMessageList->getItems(items); + mGroupInviteMessageList->getItems(items); + break; + case 3: + mGroupNoticeMessageList->getItems(items); break; default: break; @@ -379,10 +386,15 @@ void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id) LLSD payload = notify->getPayload(); p.notification_name = notify->getName(); p.group_id = payload["group_id"]; - p.sender = payload["name"].asString(); + 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"]; addItem(p); } diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h index 5191b783f6..8dd20b18c4 100644 --- a/indra/newview/llfloaternotificationstabbed.h +++ b/indra/newview/llfloaternotificationstabbed.h @@ -158,7 +158,8 @@ private: // ID of a toast loaded by user (by clicking notification well item) LLUUID mLoadedToastId; - LLNotificationListView* mInviteMessageList; + LLNotificationListView* mGroupInviteMessageList; + LLNotificationListView* mGroupNoticeMessageList; LLNotificationListView* mTransactionMessageList; LLNotificationListView* mSystemMessageList; LLNotificationSeparator* mNotificationsSeparator; diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 4c4dd07d7f..6b674fcc7d 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -29,10 +29,13 @@ #include "llnotificationlistitem.h" +#include "llagent.h" +#include "llinventoryicon.h" #include "llwindow.h" #include "v4color.h" #include "lltrans.h" #include "lluicolortable.h" +#include "message.h" LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p), mParams(p), @@ -42,7 +45,9 @@ LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p), mCloseBtn(NULL), mCondensedViewPanel(NULL), mExpandedViewPanel(NULL), - mMainPanel(NULL) + mCondensedHeight(0), + mExpandedHeight(0), + mExpandedHeightResize(0) { mNotificationName = p.notification_name; } @@ -60,7 +65,6 @@ BOOL LLNotificationListItem::postBuild() mCondenseBtn = getChild("condense_btn"); mCloseBtn = getChild("close_btn"); mCloseBtnExp = getChild("close_expanded_btn"); - mVerticalStack = getChild("item_vertical_stack"); mTitleBox->setValue(mParams.title); mTitleBoxExp->setValue(mParams.title); @@ -78,14 +82,13 @@ BOOL LLNotificationListItem::postBuild() mCondensedViewPanel = getChild("layout_panel_condensed_view"); mExpandedViewPanel = getChild("layout_panel_expanded_view"); - mMainPanel = getChild("main_panel"); - std::string expanded_heigt_str = getString("item_expanded_height"); - std::string condensed_heigt_str = getString("item_condensed_height"); - - mExpandedHeight = (S32)atoi(expanded_heigt_str.c_str()); - mCondensedHeight = (S32)atoi(condensed_heigt_str.c_str()); + 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; } @@ -124,9 +127,13 @@ BOOL LLNotificationListItem::handleMouseUp(S32 x, S32 y, MASK mask) //static LLNotificationListItem* LLNotificationListItem::create(const Params& p) { - if (LLNotificationListItem::getInviteTypes().count(p.notification_name)) + if (LLNotificationListItem::getGroupInviteTypes().count(p.notification_name)) { - return new LLInviteNotificationListItem(p); + return new LLGroupInviteNotificationListItem(p); + } + else if (LLNotificationListItem::getGroupNoticeTypes().count(p.notification_name)) + { + return new LLGroupNoticeNotificationListItem(p); } else if (LLNotificationListItem::getTransactionTypes().count(p.notification_name)) { @@ -136,9 +143,15 @@ LLNotificationListItem* LLNotificationListItem::create(const Params& p) } //static -std::set LLNotificationListItem::getInviteTypes() +std::set LLNotificationListItem::getGroupInviteTypes() { - return LLInviteNotificationListItem::getTypes(); + return LLGroupInviteNotificationListItem::getTypes(); +} + + +std::set LLNotificationListItem::getGroupNoticeTypes() +{ + return LLGroupNoticeNotificationListItem::getTypes(); } //static @@ -164,7 +177,7 @@ void LLNotificationListItem::setExpanded(BOOL value) S32 width = this->getRect().getWidth(); if (value) { - this->reshape(width, mExpandedHeight, FALSE); + this->reshape(width, mExpandedHeight + mExpandedHeightResize, FALSE); } else { @@ -172,13 +185,20 @@ void LLNotificationListItem::setExpanded(BOOL value) } } -std::set LLInviteNotificationListItem::getTypes() +std::set LLGroupInviteNotificationListItem::getTypes() { std::set types; types.insert("JoinGroup"); return types; } +std::set LLGroupNoticeNotificationListItem::getTypes() +{ + std::set types; + types.insert("GroupNotice"); + return types; +} + std::set LLTransactionNotificationListItem::getTypes() { std::set types; @@ -187,14 +207,94 @@ std::set LLTransactionNotificationListItem::getTypes() return types; } -LLInviteNotificationListItem::LLInviteNotificationListItem(const Params& p) +LLGroupNotificationListItem::LLGroupNotificationListItem(const Params& p) : LLNotificationListItem(p), - mSenderBox(NULL) + mSenderOrFeeBox(NULL) +{ +} + +LLGroupInviteNotificationListItem::LLGroupInviteNotificationListItem(const Params& p) + : LLGroupNotificationListItem(p) { buildFromFile("panel_notification_list_item.xml"); } -BOOL LLInviteNotificationListItem::postBuild() +BOOL LLGroupInviteNotificationListItem::postBuild() +{ + BOOL rv = LLGroupNotificationListItem::postBuild(); + setFee(mParams.fee); + return rv; +} + +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"); +} + +BOOL LLGroupNoticeNotificationListItem::postBuild() +{ + BOOL rv = LLGroupNotificationListItem::postBuild(); + + mAttachmentTextBox = getChild("attachment_text"); + mAttachmentIcon = getChild("attachment_icon"); + mAttachmentIconExp = getChild("attachment_icon_exp"); + mAttachmentPanel = getChild("attachment_panel"); + mAttachmentPanel->setVisible(FALSE); + + + mTitleBox->setValue(mParams.subject); + mTitleBoxExp->setValue(mParams.subject); + mNoticeTextExp->setValue(mParams.message); + //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)); + mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time)); + } + setSender(mParams.sender); + + if (mInventoryOffer != NULL) + { + mAttachmentTextBox->setValue(mInventoryOffer->mDesc); + mAttachmentIcon->setVisible(TRUE); + + std::string icon_name = LLInventoryIcon::getIconName(mInventoryOffer->mType, + LLInventoryType::IT_TEXTURE); + + mAttachmentIconExp->setValue(icon_name); + mAttachmentIconExp->setVisible(TRUE); + + 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(); @@ -210,10 +310,8 @@ BOOL LLInviteNotificationListItem::postBuild() mGroupId = mParams.group_id; - mSenderBox = getChild("sender_resident"); - mSenderBoxExp = getChild("sender_resident_exp"); - - setSender(mParams.sender); + mSenderOrFeeBox = getChild("sender_or_fee_box"); + mSenderOrFeeBoxExp = getChild("sender_or_fee_box_exp"); LLSD value(mParams.group_id); setGroupId(value); @@ -221,7 +319,7 @@ BOOL LLInviteNotificationListItem::postBuild() return rv; } -void LLInviteNotificationListItem::changed(LLGroupChange gc) +void LLGroupNotificationListItem::changed(LLGroupChange gc) { if (GC_PROPERTIES == gc) { @@ -229,7 +327,7 @@ void LLInviteNotificationListItem::changed(LLGroupChange gc) } } -bool LLInviteNotificationListItem::updateFromCache() +bool LLGroupNotificationListItem::updateFromCache() { LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId); if (!group_data) return false; @@ -237,7 +335,7 @@ bool LLInviteNotificationListItem::updateFromCache() return true; } -void LLInviteNotificationListItem::setGroupId(const LLUUID& value) +void LLGroupNotificationListItem::setGroupId(const LLUUID& value) { LLGroupMgr* gm = LLGroupMgr::getInstance(); if (mGroupId.notNull()) @@ -255,7 +353,7 @@ void LLInviteNotificationListItem::setGroupId(const LLUUID& value) } } -void LLInviteNotificationListItem::setGroupName(std::string name) +void LLGroupNotificationListItem::setGroupName(std::string name) { if (!name.empty()) { @@ -272,22 +370,22 @@ void LLInviteNotificationListItem::setGroupName(std::string name) } } -void LLInviteNotificationListItem::setSender(std::string sender) +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); - mSenderBox->setValue(sender_text); - mSenderBox->setVisible(TRUE); - mSenderBoxExp->setValue(sender_text); - mSenderBoxExp->setVisible(TRUE); + mSenderOrFeeBox->setValue(sender_text); + mSenderOrFeeBoxExp->setValue(sender_text); + mSenderOrFeeBox->setVisible(TRUE); + mSenderOrFeeBoxExp->setVisible(TRUE); } else { - mSenderBox->setValue(LLStringUtil::null); - mSenderBoxExp->setValue(LLStringUtil::null); - mSenderBox->setVisible(FALSE); - mSenderBoxExp->setVisible(FALSE); + mSenderOrFeeBox->setValue(LLStringUtil::null); + mSenderOrFeeBoxExp->setValue(LLStringUtil::null); + mSenderOrFeeBox->setVisible(FALSE); + mSenderOrFeeBoxExp->setVisible(FALSE); } } diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h index 22003a3a6a..bd76d17fe8 100644 --- a/indra/newview/llnotificationlistitem.h +++ b/indra/newview/llnotificationlistitem.h @@ -35,6 +35,7 @@ #include "llavatariconctrl.h" #include "llgroupmgr.h" +#include "llviewermessage.h" #include @@ -49,15 +50,21 @@ public: LLUUID paid_to_id; std::string notification_name; std::string title; + std::string subject; + std::string message; std::string sender; - LLDate time_stamp; + S32 fee; + LLDate time_stamp; + LLDate received_time; + LLSD inventory_offer; Params() {}; }; static LLNotificationListItem* create(const Params& p); - static std::set getInviteTypes(); static std::set getTransactionTypes(); + static std::set getGroupInviteTypes(); + static std::set getGroupNoticeTypes(); // title void setTitle( std::string title ); @@ -99,43 +106,80 @@ protected: LLButton* mCondenseBtn; LLButton* mCloseBtn; LLButton* mCloseBtnExp; - LLLayoutStack* mVerticalStack; LLPanel* mCondensedViewPanel; LLPanel* mExpandedViewPanel; - LLPanel* mMainPanel; std::string mTitle; std::string mNotificationName; - S32 mCondensedHeight; - S32 mExpandedHeight; + S32 mCondensedHeight; + S32 mExpandedHeight; + S32 mExpandedHeightResize; }; -class LLInviteNotificationListItem +class LLGroupNotificationListItem : public LLNotificationListItem, public LLGroupMgrObserver { public: - static std::set getTypes(); virtual BOOL postBuild(); void setGroupId(const LLUUID& value); // LLGroupMgrObserver observer trigger virtual void changed(LLGroupChange gc); -private: + friend class LLNotificationListItem; - LLInviteNotificationListItem(const Params& p); - LLInviteNotificationListItem(const LLInviteNotificationListItem &); - LLInviteNotificationListItem & operator=(LLInviteNotificationListItem &); - - void setSender(std::string sender); - void setGroupName(std::string name); - - bool updateFromCache(); +protected: + LLGroupNotificationListItem(const Params& p); LLGroupIconCtrl* mGroupIcon; LLGroupIconCtrl* mGroupIconExp; LLUUID mGroupId; - LLTextBox* mSenderBox; - LLTextBox* mSenderBoxExp; + 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 getTypes(); + virtual BOOL postBuild(); + +private: + friend class LLNotificationListItem; + LLGroupInviteNotificationListItem(const Params& p); + LLGroupInviteNotificationListItem(const LLGroupInviteNotificationListItem &); + LLGroupInviteNotificationListItem & operator=(LLGroupInviteNotificationListItem &); + + void setFee(S32 fee); +}; + +class LLGroupNoticeNotificationListItem + : public LLGroupNotificationListItem +{ +public: + static std::set getTypes(); + virtual BOOL postBuild(); + +private: + friend class LLNotificationListItem; + LLGroupNoticeNotificationListItem(const Params& p); + LLGroupNoticeNotificationListItem(const LLGroupNoticeNotificationListItem &); + LLGroupNoticeNotificationListItem & operator=(LLGroupNoticeNotificationListItem &); + + void setSender(std::string sender); + + LLPanel* mAttachmentPanel; + LLTextBox* mAttachmentTextBox; + LLIconCtrl* mAttachmentIcon; + LLIconCtrl* mAttachmentIconExp; + LLOfferInfo* mInventoryOffer; }; class LLTransactionNotificationListItem : public LLNotificationListItem diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index e00b18dedb..def5a0ac7c 100755 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -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"]; LLSD substitution; substitution["datetime"] = (S32) notice_date.secondsSinceEpoch(); LLStringUtil::format(timeStr, substitution); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6507794cdd..99db3ff093 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2681,6 +2681,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(); diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index e47e0c03f1..4f8962182e 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -798,4 +798,6 @@ with the same filename but different name + + diff --git a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml index 55ecfb637b..0fdd9ed0c6 100644 --- a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml +++ b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml @@ -28,9 +28,13 @@ Transactions ([COUNT]) + name="group_invitations_tab_title"> Invitations ([COUNT]) + + Group ([COUNT]) + @@ -72,7 +76,7 @@ follows="left|top|right|bottom" label="Transactions (0)" layout="topleft" - name="TransactionNotificationsTab"> + name="transaction_notifications_tab"> + name="group_invite_notifications_tab"> + + + Group: "[GROUP_NAME]" + + Fee: [GROUP_FEE] + 50 - 200 + 175 + + + 27 - + @@ -49,10 +57,11 @@ 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 + + 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" - - -