PageRenderTime 76ms CodeModel.GetById 16ms app.highlight 55ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llfloaternotificationsconsole.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 295 lines | 214 code | 43 blank | 38 comment | 17 complexity | ac0d6de186c5801c4593d439eb198615 MD5 | raw file
  1/** 
  2 * @file llnotificationsconsole.cpp
  3 * @brief Debugging console for unified notifications.
  4 *
  5 * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28#include "llfloaternotificationsconsole.h"
 29#include "llnotifications.h"
 30#include "lluictrlfactory.h"
 31#include "llbutton.h"
 32#include "llscrolllistctrl.h"
 33#include "llscrolllistitem.h"
 34#include "llpanel.h"
 35#include "llcombobox.h"
 36
 37const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
 38const S32 HEADER_PADDING = 38;
 39
 40class LLNotificationChannelPanel : public LLLayoutPanel
 41{
 42public:
 43	LLNotificationChannelPanel(const Params& p);
 44	BOOL postBuild();
 45
 46private:
 47	bool update(const LLSD& payload, bool passed_filter);
 48	static void toggleClick(void* user_data);
 49	static void onClickNotification(void* user_data);
 50	static void onClickNotificationReject(void* user_data);
 51	LLNotificationChannelPtr mChannelPtr;
 52	LLNotificationChannelPtr mChannelRejectsPtr;
 53};
 54
 55LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) 
 56:	LLLayoutPanel(p)
 57{
 58	mChannelPtr = LLNotifications::instance().getChannel(p.name);
 59	mChannelRejectsPtr = LLNotificationChannelPtr(
 60		LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
 61											!boost::bind(mChannelPtr->getFilter(), _1)));
 62	buildFromFile( "panel_notifications_channel.xml");
 63}
 64
 65BOOL LLNotificationChannelPanel::postBuild()
 66{
 67	LLButton* header_button = getChild<LLButton>("header");
 68	header_button->setLabel(mChannelPtr->getName());
 69	header_button->setClickedCallback(toggleClick, this);
 70
 71	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
 72	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
 73
 74	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
 75	scroll->setDoubleClickCallback(onClickNotification, this);
 76	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
 77	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
 78	scroll->setDoubleClickCallback(onClickNotificationReject, this);
 79	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
 80	return TRUE;
 81}
 82
 83//static
 84void LLNotificationChannelPanel::toggleClick(void *user_data)
 85{
 86	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
 87	if (!self) return;
 88	
 89	LLButton* header_button = self->getChild<LLButton>("header");
 90	
 91	LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
 92	if (stack)
 93	{
 94		stack->collapsePanel(self, header_button->getToggleState());
 95	}
 96
 97	// turn off tab stop for collapsed panel
 98	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
 99	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
100	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
101	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
102}
103
104/*static*/
105void LLNotificationChannelPanel::onClickNotification(void* user_data)
106{
107	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
108	if (!self) return;
109	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected();
110	llassert(firstselected);
111	if (firstselected)
112	{
113		void* data = firstselected->getUserdata();
114		if (data)
115		{
116			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
117		}
118	}
119}
120
121/*static*/
122void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
123{
124	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
125	if (!self) return;
126	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
127	llassert(firstselected);
128	if (firstselected)
129	{
130		void* data = firstselected->getUserdata();
131		if (data)
132		{
133			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
134		}
135	}
136}
137
138bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
139{
140	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
141	if (notification)
142	{
143		LLSD row;
144		row["columns"][0]["value"] = notification->getName();
145		row["columns"][0]["column"] = "name";
146
147		row["columns"][1]["value"] = notification->getMessage();
148		row["columns"][1]["column"] = "content";
149
150		row["columns"][2]["value"] = notification->getDate();
151		row["columns"][2]["column"] = "date";
152		row["columns"][2]["type"] = "date";
153
154		LLScrollListItem* sli = passed_filter ? 
155			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
156			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
157		sli->setUserdata(&(*notification));
158	}
159
160	return false;
161}
162
163//
164// LLFloaterNotificationConsole
165//
166LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
167: LLFloater(key)
168{
169	mCommitCallbackRegistrar.add("ClickAdd",     boost::bind(&LLFloaterNotificationConsole::onClickAdd, this));	
170}
171
172BOOL LLFloaterNotificationConsole::postBuild()
173{
174	// these are in the order of processing
175	addChannel("Unexpired");
176	addChannel("Ignore");
177	addChannel("VisibilityRules");
178	addChannel("Visible", true);
179	// all the ones below attach to the Visible channel
180	addChannel("Persistent");
181	addChannel("Alerts");
182	addChannel("AlertModal");
183	addChannel("Group Notifications");
184	addChannel("Notifications");
185	addChannel("NotificationTips");
186
187//	getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
188
189	LLComboBox* notifications = getChild<LLComboBox>("notification_types");
190	LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
191	for (LLNotifications::TemplateNames::iterator template_it = names.begin();
192		template_it != names.end();
193		++template_it)
194	{
195		notifications->add(*template_it);
196	}
197	notifications->sortByName();
198
199	return TRUE;
200}
201
202void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
203{
204	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
205	LLNotificationChannelPanel::Params p;
206	p.min_dim = NOTIFICATION_PANEL_HEADER_HEIGHT;
207	p.auto_resize = true;
208	p.user_resize = true;
209	p.name = name;
210	LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(p);
211	stack.addPanel(panelp, LLLayoutStack::ANIMATE);
212
213	LLButton& header_button = panelp->getChildRef<LLButton>("header");
214	header_button.setToggleState(!open);
215	stack.collapsePanel(panelp, !open);
216
217	updateResizeLimits();
218}
219
220void LLFloaterNotificationConsole::removeChannel(const std::string& name)
221{
222	LLPanel* panelp = getChild<LLPanel>(name);
223	getChildRef<LLView>("notification_channels").removeChild(panelp);
224	delete panelp;
225
226	updateResizeLimits();
227}
228
229//static 
230void LLFloaterNotificationConsole::updateResizeLimits()
231{
232	const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
233	S32 floater_header_size = floater_params.header_height;
234
235	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
236	setResizeLimits(getMinWidth(), floater_header_size + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
237}
238
239void LLFloaterNotificationConsole::onClickAdd()
240{
241	std::string message_name = getChild<LLComboBox>("notification_types")->getValue().asString();
242	if (!message_name.empty())
243	{
244		LLNotifications::instance().add(message_name, LLSD(), LLSD());
245	}
246}
247
248
249//=============== LLFloaterNotification ================
250
251LLFloaterNotification::LLFloaterNotification(LLNotification* note) 
252:	LLFloater(LLSD()),
253	mNote(note)
254{
255	buildFromFile("floater_notification.xml");
256}
257
258BOOL LLFloaterNotification::postBuild()
259{
260	setTitle(mNote->getName());
261	getChild<LLUICtrl>("payload")->setValue(mNote->getMessage());
262
263	LLComboBox* responses_combo = getChild<LLComboBox>("response");
264	LLCtrlListInterface* response_list = responses_combo->getListInterface();
265	LLNotificationFormPtr form(mNote->getForm());
266	if(!form)
267	{
268		return TRUE;
269	}
270
271	responses_combo->setCommitCallback(onCommitResponse, this);
272
273	LLSD form_sd = form->asLLSD();
274
275	for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
276	{
277		if ( (*form_item)["type"].asString() != "button") continue;
278		std::string text = (*form_item)["text"].asString();
279		response_list->addSimpleElement(text);
280	}
281
282	return TRUE;
283}
284
285void LLFloaterNotification::respond()
286{
287	LLComboBox* responses_combo = getChild<LLComboBox>("response");
288	LLCtrlListInterface* response_list = responses_combo->getListInterface();
289	const std::string& trigger = response_list->getSelectedValue().asString();
290	//llinfos << trigger << llendl;
291
292	LLSD response = mNote->getResponseTemplate();
293	response[trigger] = true;
294	mNote->respond(response);
295}