From 5f237f8559da76d3c2fd6251b324360fcf25515f Mon Sep 17 00:00:00 2001
From: Eugene Mutavchi <emutavchi@productengine.com>
Date: Fri, 18 Dec 2009 14:01:18 +0200
Subject: Implemented major sub-task EXT-3525 (Context menu for Notifications
 well)

--HG--
branch : product-engine
---
 indra/newview/llchiclet.cpp                        | 62 ++++++++++++++++++++++
 indra/newview/llchiclet.h                          | 29 +++++++++-
 indra/newview/llsyswellwindow.cpp                  | 17 ++++++
 indra/newview/llsyswellwindow.h                    |  3 ++
 .../xui/en/menu_notification_well_button.xml       | 16 ++++++
 5 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_notification_well_button.xml

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index c6fe076911..5695f7cac1 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -154,6 +154,7 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
 , mMaxDisplayedCount(p.max_displayed_count)
 , mIsNewMessagesState(false)
 , mFlashToLitTimer(NULL)
+, mContextMenu(NULL)
 {
 	LLButton::Params button_params = p.button;
 	mButton = LLUICtrlFactory::create<LLButton>(button_params);
@@ -229,6 +230,21 @@ void LLSysWellChiclet::setNewMessagesState(bool new_messages)
 	mIsNewMessagesState = new_messages;
 }
 
+// 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;
+}
+
 /************************************************************************/
 /*               LLIMWellChiclet implementation                         */
 /************************************************************************/
@@ -248,6 +264,11 @@ LLIMWellChiclet::~LLIMWellChiclet()
 	LLIMMgr::getInstance()->removeSessionObserver(this);
 }
 
+void LLIMWellChiclet::createMenu()
+{
+	// TODO: implement context menu for IM well
+}
+
 void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
 {
 	setCounter(LLBottomTray::getInstance()->getTotalUnreadIMCount());
@@ -281,6 +302,47 @@ void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& no
 	}
 }
 
+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());
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index b3341f78a8..d8f641d0f9 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -806,6 +806,13 @@ protected:
 	 */
 	void changeLitState();
 
+	/**
+	 * Displays menu.
+	 */
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	virtual void createMenu() = 0;
+
 protected:
 	class FlashToLitTimer;
 	LLButton* mButton;
@@ -814,7 +821,7 @@ protected:
 	bool mIsNewMessagesState;
 
 	FlashToLitTimer* mFlashToLitTimer;
-
+	LLContextMenu* mContextMenu;
 };
 
 /**
@@ -834,6 +841,11 @@ public:
 protected:
 	LLIMWellChiclet(const Params& p);
 
+	/**
+	 * Creates menu.
+	 */
+	/*virtual*/ void createMenu();
+
 	/**
 	 * Handles changes in a session (message was added, messages were read, etc.)
 	 *
@@ -854,6 +866,21 @@ class LLNotificationChiclet : public LLSysWellChiclet
 protected:
 	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();
+
 	// connect counter updaters to the corresponding signals
 	void connectCounterUpdatersToSignal(const std::string& notification_type);
 
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 3769ddb1cc..7bff06e9a3 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -610,6 +610,23 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
 	}
 }
 
+void LLNotificationWellWindow::closeAll()
+{
+	// Need to clear notification channel, to add storable toasts into the list.
+	clearScreenChannels();
+	std::vector<LLPanel*> items;
+	mMessageList->getItems(items);
+	for (std::vector<LLPanel*>::iterator
+			 iter = items.begin(),
+			 iter_end = items.end();
+		 iter != iter_end; ++iter)
+	{
+		LLSysWellItem* sys_well_item = dynamic_cast<LLSysWellItem*>(*iter);
+		if (sys_well_item)
+			onItemClose(sys_well_item);
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////
 // PRIVATE METHODS
 void LLNotificationWellWindow::initChannel() 
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 736b1b9fb4..5f2c2ba501 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -147,6 +147,9 @@ public:
 	// Operating with items
 	void addItem(LLSysWellItem::Params p);
 
+	// Closes all notifications and removes them from the Notification Well
+	void closeAll();
+
 protected:
 	/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
 
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>
-- 
cgit v1.2.3