/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. #include "llviewerprecompiledheaders.h"
  27. #include "llfloaternotificationsconsole.h"
  28. #include "llnotifications.h"
  29. #include "lluictrlfactory.h"
  30. #include "llbutton.h"
  31. #include "llscrolllistctrl.h"
  32. #include "llscrolllistitem.h"
  33. #include "llpanel.h"
  34. #include "llcombobox.h"
  35. const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
  36. const S32 HEADER_PADDING = 38;
  37. class LLNotificationChannelPanel : public LLLayoutPanel
  38. {
  39. public:
  40. LLNotificationChannelPanel(const Params& p);
  41. BOOL postBuild();
  42. private:
  43. bool update(const LLSD& payload, bool passed_filter);
  44. static void toggleClick(void* user_data);
  45. static void onClickNotification(void* user_data);
  46. static void onClickNotificationReject(void* user_data);
  47. LLNotificationChannelPtr mChannelPtr;
  48. LLNotificationChannelPtr mChannelRejectsPtr;
  49. };
  50. LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p)
  51. : LLLayoutPanel(p)
  52. {
  53. mChannelPtr = LLNotifications::instance().getChannel(p.name);
  54. mChannelRejectsPtr = LLNotificationChannelPtr(
  55. LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
  56. !boost::bind(mChannelPtr->getFilter(), _1)));
  57. buildFromFile( "panel_notifications_channel.xml");
  58. }
  59. BOOL LLNotificationChannelPanel::postBuild()
  60. {
  61. LLButton* header_button = getChild<LLButton>("header");
  62. header_button->setLabel(mChannelPtr->getName());
  63. header_button->setClickedCallback(toggleClick, this);
  64. mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
  65. mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
  66. LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
  67. scroll->setDoubleClickCallback(onClickNotification, this);
  68. scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
  69. scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
  70. scroll->setDoubleClickCallback(onClickNotificationReject, this);
  71. scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
  72. return TRUE;
  73. }
  74. //static
  75. void LLNotificationChannelPanel::toggleClick(void *user_data)
  76. {
  77. LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
  78. if (!self) return;
  79. LLButton* header_button = self->getChild<LLButton>("header");
  80. LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
  81. if (stack)
  82. {
  83. stack->collapsePanel(self, header_button->getToggleState());
  84. }
  85. // turn off tab stop for collapsed panel
  86. self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
  87. self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
  88. self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
  89. self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
  90. }
  91. /*static*/
  92. void LLNotificationChannelPanel::onClickNotification(void* user_data)
  93. {
  94. LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
  95. if (!self) return;
  96. LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected();
  97. llassert(firstselected);
  98. if (firstselected)
  99. {
  100. void* data = firstselected->getUserdata();
  101. if (data)
  102. {
  103. gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
  104. }
  105. }
  106. }
  107. /*static*/
  108. void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
  109. {
  110. LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
  111. if (!self) return;
  112. LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
  113. llassert(firstselected);
  114. if (firstselected)
  115. {
  116. void* data = firstselected->getUserdata();
  117. if (data)
  118. {
  119. gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
  120. }
  121. }
  122. }
  123. bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
  124. {
  125. LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
  126. if (notification)
  127. {
  128. LLSD row;
  129. row["columns"][0]["value"] = notification->getName();
  130. row["columns"][0]["column"] = "name";
  131. row["columns"][1]["value"] = notification->getMessage();
  132. row["columns"][1]["column"] = "content";
  133. row["columns"][2]["value"] = notification->getDate();
  134. row["columns"][2]["column"] = "date";
  135. row["columns"][2]["type"] = "date";
  136. LLScrollListItem* sli = passed_filter ?
  137. getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
  138. getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
  139. sli->setUserdata(&(*notification));
  140. }
  141. return false;
  142. }
  143. //
  144. // LLFloaterNotificationConsole
  145. //
  146. LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
  147. : LLFloater(key)
  148. {
  149. mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this));
  150. }
  151. BOOL LLFloaterNotificationConsole::postBuild()
  152. {
  153. // these are in the order of processing
  154. addChannel("Unexpired");
  155. addChannel("Ignore");
  156. addChannel("VisibilityRules");
  157. addChannel("Visible", true);
  158. // all the ones below attach to the Visible channel
  159. addChannel("Persistent");
  160. addChannel("Alerts");
  161. addChannel("AlertModal");
  162. addChannel("Group Notifications");
  163. addChannel("Notifications");
  164. addChannel("NotificationTips");
  165. // getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
  166. LLComboBox* notifications = getChild<LLComboBox>("notification_types");
  167. LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
  168. for (LLNotifications::TemplateNames::iterator template_it = names.begin();
  169. template_it != names.end();
  170. ++template_it)
  171. {
  172. notifications->add(*template_it);
  173. }
  174. notifications->sortByName();
  175. return TRUE;
  176. }
  177. void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
  178. {
  179. LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
  180. LLNotificationChannelPanel::Params p;
  181. p.min_dim = NOTIFICATION_PANEL_HEADER_HEIGHT;
  182. p.auto_resize = true;
  183. p.user_resize = true;
  184. p.name = name;
  185. LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(p);
  186. stack.addPanel(panelp, LLLayoutStack::ANIMATE);
  187. LLButton& header_button = panelp->getChildRef<LLButton>("header");
  188. header_button.setToggleState(!open);
  189. stack.collapsePanel(panelp, !open);
  190. updateResizeLimits();
  191. }
  192. void LLFloaterNotificationConsole::removeChannel(const std::string& name)
  193. {
  194. LLPanel* panelp = getChild<LLPanel>(name);
  195. getChildRef<LLView>("notification_channels").removeChild(panelp);
  196. delete panelp;
  197. updateResizeLimits();
  198. }
  199. //static
  200. void LLFloaterNotificationConsole::updateResizeLimits()
  201. {
  202. const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
  203. S32 floater_header_size = floater_params.header_height;
  204. LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
  205. setResizeLimits(getMinWidth(), floater_header_size + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
  206. }
  207. void LLFloaterNotificationConsole::onClickAdd()
  208. {
  209. std::string message_name = getChild<LLComboBox>("notification_types")->getValue().asString();
  210. if (!message_name.empty())
  211. {
  212. LLNotifications::instance().add(message_name, LLSD(), LLSD());
  213. }
  214. }
  215. //=============== LLFloaterNotification ================
  216. LLFloaterNotification::LLFloaterNotification(LLNotification* note)
  217. : LLFloater(LLSD()),
  218. mNote(note)
  219. {
  220. buildFromFile("floater_notification.xml");
  221. }
  222. BOOL LLFloaterNotification::postBuild()
  223. {
  224. setTitle(mNote->getName());
  225. getChild<LLUICtrl>("payload")->setValue(mNote->getMessage());
  226. LLComboBox* responses_combo = getChild<LLComboBox>("response");
  227. LLCtrlListInterface* response_list = responses_combo->getListInterface();
  228. LLNotificationFormPtr form(mNote->getForm());
  229. if(!form)
  230. {
  231. return TRUE;
  232. }
  233. responses_combo->setCommitCallback(onCommitResponse, this);
  234. LLSD form_sd = form->asLLSD();
  235. for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
  236. {
  237. if ( (*form_item)["type"].asString() != "button") continue;
  238. std::string text = (*form_item)["text"].asString();
  239. response_list->addSimpleElement(text);
  240. }
  241. return TRUE;
  242. }
  243. void LLFloaterNotification::respond()
  244. {
  245. LLComboBox* responses_combo = getChild<LLComboBox>("response");
  246. LLCtrlListInterface* response_list = responses_combo->getListInterface();
  247. const std::string& trigger = response_list->getSelectedValue().asString();
  248. //llinfos << trigger << llendl;
  249. LLSD response = mNote->getResponseTemplate();
  250. response[trigger] = true;
  251. mNote->respond(response);
  252. }