summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2012-12-19 20:08:57 -0800
committerMerov Linden <merov@lindenlab.com>2012-12-19 20:08:57 -0800
commit059fa6fca5a05326d9ba6570c3d9b325f70bd553 (patch)
treefdb7ec1f426f889004eae009058269a48bc1310f /indra
parentba297b167f75d8a09c959952a300d492f2aec88b (diff)
parentcc900b732dd1af2790248485a270197a4006e0f7 (diff)
Pull merge from richard/viewer-chui
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llchiclet.cpp216
-rw-r--r--indra/newview/llchiclet.h208
-rw-r--r--indra/newview/llchicletbar.cpp3
-rw-r--r--indra/newview/llsyswellwindow.cpp15
-rw-r--r--indra/newview/llsyswellwindow.h7
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/da/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/de/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_notification_well_button.xml16
-rw-r--r--indra/newview/skins/default/xui/en/panel_chiclet_bar.xml44
-rw-r--r--indra/newview/skins/default/xui/es/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/it/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/menu_notification_well_button.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_notification_well_button.xml4
19 files changed, 546 insertions, 9 deletions
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 1acbdd32b7..2fdcb17570 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,15 +27,17 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
+#include "llchicletbar.h"
#include "llfloaterimsession.h"
#include "llfloaterimcontainer.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
-#include "llnotifications.h"
#include "llscriptfloater.h"
#include "llsingleton.h"
+#include "llsyswellwindow.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
@@ -46,6 +48,195 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLSysWellChiclet::Params::Params()
+ : button("button")
+ , unread_notifications("unread_notifications")
+ , max_displayed_count("max_displayed_count", 99)
+{
+ button.name = "button";
+ button.tab_stop = FALSE;
+ button.label = LLStringUtil::null;
+}
+
+LLSysWellChiclet::LLSysWellChiclet(const Params& p)
+ : LLChiclet(p)
+ , mButton(NULL)
+ , mCounter(0)
+ , mMaxDisplayedCount(p.max_displayed_count)
+ , mIsNewMessagesState(false)
+ , mFlashToLitTimer(NULL)
+ , mContextMenu(NULL)
+{
+ LLButton::Params button_params = p.button;
+ mButton = LLUICtrlFactory::create<LLButton>(button_params);
+ addChild(mButton);
+
+ mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
+}
+
+LLSysWellChiclet::~LLSysWellChiclet()
+{
+ delete mFlashToLitTimer;
+}
+
+void LLSysWellChiclet::setCounter(S32 counter)
+{
+ // do nothing if the same counter is coming. EXT-3678.
+ if (counter == mCounter) return;
+
+ // note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+ std::string s_count;
+ if(counter != 0)
+ {
+ static std::string more_messages_exist("+");
+ std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
+ s_count = llformat("%d%s"
+ , llmin(counter, mMaxDisplayedCount)
+ , more_messages.c_str()
+ );
+ }
+
+ mButton->setLabel(s_count);
+
+ mCounter = counter;
+}
+
+boost::signals2::connection LLSysWellChiclet::setClickCallback(
+ const commit_callback_t& cb)
+{
+ return mButton->setClickedCallback(cb);
+}
+
+void LLSysWellChiclet::setToggleState(BOOL toggled) {
+ mButton->setToggleState(toggled);
+}
+
+void LLSysWellChiclet::changeLitState(bool blink)
+{
+ setNewMessagesState(!mIsNewMessagesState);
+}
+
+void LLSysWellChiclet::setNewMessagesState(bool new_messages)
+{
+ /*
+ Emulate 4 states of button by background images, see detains in EXT-3147
+ xml attribute Description
+ image_unselected "Unlit" - there are no new messages
+ image_selected "Unlit" + "Selected" - there are no new messages and the Well is open
+ image_pressed "Lit" - there are new messages
+ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open
+ */
+ mButton->setForcePressedState(new_messages);
+
+ mIsNewMessagesState = new_messages;
+}
+
+void LLSysWellChiclet::updateWidget(bool is_window_empty)
+{
+ mButton->setEnabled(!is_window_empty);
+
+ if (LLChicletBar::instanceExists())
+ {
+ LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty);
+ }
+}
+// virtual
+BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(!mContextMenu)
+ {
+ createMenu();
+ }
+ if (mContextMenu)
+ {
+ mContextMenu->show(x, y);
+ LLMenuGL::showPopup(this, mContextMenu, x, y);
+ }
+ return TRUE;
+}
+
+/************************************************************************/
+/* LLNotificationChiclet implementation */
+/************************************************************************/
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+: LLSysWellChiclet(p),
+ mUreadSystemNotifications(0)
+{
+ mNotificationChannel.reset(new ChicletNotificationChannel(this));
+ // ensure that notification well window exists, to synchronously
+ // handle toast add/delete events.
+ LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
+}
+
+void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+ std::string action = user_data.asString();
+ if("close all" == action)
+ {
+ LLNotificationWellWindow::getInstance()->closeAll();
+ }
+}
+
+bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
+{
+ std::string item = user_data.asString();
+ if (item == "can close all")
+ {
+ return mUreadSystemNotifications != 0;
+ }
+ return true;
+}
+
+void LLNotificationChiclet::createMenu()
+{
+ if(mContextMenu)
+ {
+ llwarns << "Menu already exists" << llendl;
+ return;
+ }
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("NotificationWellChicletMenu.Action",
+ boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2));
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ enable_registrar.add("NotificationWellChicletMenu.EnableItem",
+ boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
+
+ mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
+ ("menu_notification_well_button.xml",
+ LLMenuGL::sMenuContainer,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+/*virtual*/
+void LLNotificationChiclet::setCounter(S32 counter)
+{
+ LLSysWellChiclet::setCounter(counter);
+ updateWidget(getCounter() == 0);
+
+}
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+ if (notification->getName() == "ScriptDialog")
+ {
+ return false;
+ }
+
+ if( !(notification->canLogToIM() && notification->hasFormElements())
+ && (!notification->getPayload().has("give_inventory_notification")
+ || notification->getPayload()["give_inventory_notification"]))
+ {
+ return true;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
LLChiclet::Params::Params()
: show_counter("show_counter", true)
, enable_counter("enable_counter", false)
@@ -57,12 +248,6 @@ LLChiclet::LLChiclet(const Params& p)
, mSessionId(LLUUID::null)
, mShowCounter(p.show_counter)
{
-
-}
-
-LLChiclet::~LLChiclet()
-{
-
}
boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
@@ -125,6 +310,15 @@ BOOL LLIMChiclet::postBuild()
return TRUE;
}
+void LLIMChiclet::enableCounterControl(bool enable)
+{
+ mCounterEnabled = enable;
+ if(!enable)
+ {
+ LLChiclet::setShowCounter(false);
+ }
+}
+
void LLIMChiclet::setRequiredWidth()
{
S32 required_width = mDefaultWidth;
@@ -791,13 +985,19 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLChicletNotificationCounterCtrl::Params::Params()
+ : max_displayed_count("max_displayed_count", 99)
+{
+}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
: LLAvatarIconCtrl(p)
{
}
-
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index bd6c1a3e71..efaf03384a 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,11 +29,71 @@
#include "llavatariconctrl.h"
#include "llbutton.h"
+#include "llnotifications.h"
+#include "lltextbox.h"
class LLMenuGL;
class LLFloaterIMSession;
/**
+ * Class for displaying amount of messages/notifications(unread).
+ */
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
+ {
+ /**
+ * Contains maximum displayed count of unread messages. Default value is 9.
+ *
+ * If count is less than "max_unread_count" will be displayed as is.
+ * Otherwise 9+ will be shown (for default value).
+ */
+ Optional<S32> max_displayed_count;
+
+ Params();
+ };
+
+ /**
+ * Sets number of notifications
+ */
+ virtual void setCounter(S32 counter);
+
+ /**
+ * Returns number of notifications
+ */
+ virtual S32 getCounter() const { return mCounter; }
+
+ /**
+ * Returns width, required to display amount of notifications in text form.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
+
+ /**
+ * Sets number of notifications using LLSD
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+ /**
+ * Returns number of notifications wrapped in LLSD
+ */
+ /*virtual*/ LLSD getValue() const;
+
+protected:
+
+ LLChicletNotificationCounterCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+
+private:
+
+ S32 mCounter;
+ S32 mInitialWidth;
+ S32 mMaxDisplayedCount;
+};
+
+/**
* Class for displaying avatar's icon in P2P chiclet.
*/
class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
@@ -104,7 +164,7 @@ public:
Params();
};
- /*virtual*/ ~LLChiclet();
+ virtual ~LLChiclet() {}
/**
* Associates chat session id with chiclet.
@@ -117,6 +177,11 @@ public:
virtual const LLUUID& getSessionId() const { return mSessionId; }
/**
+ * Sets show counter state.
+ */
+ virtual void setShowCounter(bool show) { mShowCounter = show; }
+
+ /**
* Connects chiclet clicked event with callback.
*/
/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
@@ -195,6 +260,22 @@ public:
BOOL postBuild();
/**
+ * Sets IM session name. This name will be displayed in chiclet tooltip.
+ */
+ virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
+
+ /**
+ * Sets id of person/group user is chatting with.
+ * Session id should be set before calling this
+ */
+ virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
+
+ /**
+ * Enables/disables the counter control for a chiclet.
+ */
+ virtual void enableCounterControl(bool enable);
+
+ /**
* Sets required width for a chiclet according to visible controls.
*/
virtual void setRequiredWidth();
@@ -367,6 +448,131 @@ private:
};
/**
+ * Implements notification chiclet. Used to display total amount of unread messages
+ * across all IM sessions, total amount of system notifications. See EXT-3147 for details
+ */
+class LLSysWellChiclet : public LLChiclet
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+ {
+ Optional<LLButton::Params> button;
+
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+ /**
+ * Contains maximum displayed count of unread messages. Default value is 9.
+ *
+ * If count is less than "max_unread_count" will be displayed as is.
+ * Otherwise 9+ will be shown (for default value).
+ */
+ Optional<S32> max_displayed_count;
+
+ Params();
+ };
+
+ /*virtual*/ void setCounter(S32 counter);
+
+ // *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
+ // but inherited interface requires it to implement.
+ // Probably it can be safe removed.
+ /*virtual*/S32 getCounter() { return mCounter; }
+
+ boost::signals2::connection setClickCallback(const commit_callback_t& cb);
+
+ /*virtual*/ ~LLSysWellChiclet();
+
+ void setToggleState(BOOL toggled);
+
+ void setNewMessagesState(bool new_messages);
+ //this method should change a widget according to state of the SysWellWindow
+ virtual void updateWidget(bool is_window_empty);
+
+protected:
+
+ LLSysWellChiclet(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /**
+ * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
+ *
+ * There is an assumption that it will be called 2*N times to do not change its start state.
+ * @see FlashToLitTimer
+ */
+ void changeLitState(bool blink);
+
+ /**
+ * Displays menu.
+ */
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ virtual void createMenu() = 0;
+
+protected:
+ class FlashToLitTimer;
+ LLButton* mButton;
+ S32 mCounter;
+ S32 mMaxDisplayedCount;
+ bool mIsNewMessagesState;
+
+ LLFlashTimer* mFlashToLitTimer;
+ LLContextMenu* mContextMenu;
+};
+
+class LLNotificationChiclet : public LLSysWellChiclet
+{
+ LOG_CLASS(LLNotificationChiclet);
+
+ friend class LLUICtrlFactory;
+public:
+ struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
+
+protected:
+ struct ChicletNotificationChannel : public LLNotificationChannel
+ {
+ ChicletNotificationChannel(LLNotificationChiclet* chiclet)
+ : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
+ , mChiclet(chiclet)
+ {
+ // connect counter handlers to the signals
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+ connectToChannel("Notifications");
+ }
+
+ static bool filterNotification(LLNotificationPtr notify);
+ // connect counter updaters to the corresponding signals
+ /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+ /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+
+ LLNotificationChiclet* const mChiclet;
+ };
+
+ boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+
+ LLNotificationChiclet(const Params& p);
+
+ /**
+ * Processes clicks on chiclet menu.
+ */
+ void onMenuItemClicked(const LLSD& user_data);
+
+ /**
+ * Enables chiclet menu items.
+ */
+ bool enableMenuItem(const LLSD& user_data);
+
+ /**
+ * Creates menu.
+ */
+ /*virtual*/ void createMenu();
+
+ /*virtual*/ void setCounter(S32 counter);
+ S32 mUreadSystemNotifications;
+};
+
+/**
* Storage class for all IM chiclets. Provides mechanism to display,
* scroll, create, remove chiclets.
*/
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index fde7764129..a51c844775 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -30,6 +30,7 @@
#include "llchiclet.h"
#include "lllayoutstack.h"
#include "llpaneltopinfobar.h"
+#include "llsyswellwindow.h"
namespace
{
@@ -58,6 +59,8 @@ BOOL LLChicletBar::postBuild()
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
+ showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
+
LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 8a43855a7d..e92bd766ca 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -40,6 +40,7 @@
LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true, key),
mChannel(NULL),
mMessageList(NULL),
+ mSysWellChiclet(NULL),
NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
IM_WELL_ANCHOR_NAME("im_well_panel"),
mIsReshapedByUser(false)
@@ -79,6 +80,15 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
setVisible(TRUE);
}
+void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet)
+{
+ mSysWellChiclet = chiclet;
+ if(NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
+}
+
//---------------------------------------------------------------------------------
LLSysWellWindow::~LLSysWellWindow()
{
@@ -89,6 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
{
if(mMessageList->removeItemByValue(id))
{
+ if (NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
reshapeWindow();
}
else
@@ -334,6 +348,7 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
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));
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 406ab1b59e..cc5c057d8b 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -66,6 +66,8 @@ public:
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;
@@ -84,6 +86,11 @@ protected:
LLNotificationsUI::LLScreenChannel* mChannel;
LLFlatListView* mMessageList;
+ /**
+ * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
+ */
+ LLSysWellChiclet* mSysWellChiclet;
+
bool mIsReshapedByUser;
};
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index bf6e933dfd..a07d7e4855 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -365,6 +365,8 @@ with the same filename but different name
<texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
+ <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
+
<texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
<texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />
diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
new file mode 100644
index 0000000000..40b35b5fdd
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Luk alle" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
new file mode 100644
index 0000000000..0f2784f160
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Alle schließen" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
new file mode 100644
index 0000000000..263ac40f4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Notification Well Button Context Menu">
+ <menu_item_call
+ label="Close All"
+ layout="topleft"
+ name="Close All">
+ <menu_item_call.on_click
+ function="NotificationWellChicletMenu.Action"
+ parameter="close all" />
+ <menu_item_call.on_enable
+ function="NotificationWellChicletMenu.EnableItem"
+ parameter="can close all" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index 390047d493..fc321fdd23 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -77,5 +77,49 @@
width="12" />
</chiclet_panel>
</layout_panel>
+ <layout_panel auto_resize="false"
+ width="4"
+ min_width="4"/>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="37"
+ name="notification_well_panel"
+ top="0"
+ width="37">
+ <chiclet_notification
+ follows="right"
+ height="23"
+ layout="topleft"
+ left="0"
+ max_displayed_count="99"
+ name="notification_well"
+ top="5"
+ width="35">
+ <button
+ auto_resize="false"
+ bottom_pad="3"
+ follows="right"
+ halign="center"
+ height="23"
+ image_overlay="Notices_Unread"
+ image_overlay_alignment="center"
+ image_pressed="WellButton_Lit"
+ image_pressed_selected="WellButton_Lit_Selected"
+ image_selected="PushButton_Press"
+ label_color="Black"
+ left="0"
+ name="Unread"
+ tool_tip="Notifications"
+ width="34">
+ <init_callback
+ function="Button.SetDockableFloaterToggle"
+ parameter="notification_well_window" />
+ </button>
+ </chiclet_notification>
+ </layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
new file mode 100644
index 0000000000..0562d35be7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Cerrar todo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
new file mode 100644
index 0000000000..323bfdbf16
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Tout fermer" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
new file mode 100644
index 0000000000..8c82e30f0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Chiudi tutto" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
new file mode 100644
index 0000000000..913bae8958
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="すべて閉じる" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
new file mode 100644
index 0000000000..bd3d42f9b1
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Zamknij" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
new file mode 100644
index 0000000000..43ad4134ec
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Fechar tudo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
new file mode 100644
index 0000000000..4d067e232a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Закрыть все" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
new file mode 100644
index 0000000000..39c66268f5
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="Tümünü Kapat" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
new file mode 100644
index 0000000000..b629f73584
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+ <menu_item_call label="全部關閉" name="Close All"/>
+</context_menu>