PageRenderTime 23ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llpanelgroup.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 625 lines | 467 code | 121 blank | 37 comment | 91 complexity | 2e6ef479ba7784547169e382ebbd5d0c MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpanelgroup.cpp
  3. *
  4. * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #include "llviewerprecompiledheaders.h"
  26. #include "llpanelgroup.h"
  27. // Library includes
  28. #include "llbutton.h"
  29. #include "llfloatersidepanelcontainer.h"
  30. #include "lltabcontainer.h"
  31. #include "lltextbox.h"
  32. #include "lluictrlfactory.h"
  33. // Viewer includes
  34. #include "llviewermessage.h"
  35. #include "llviewerwindow.h"
  36. #include "llappviewer.h"
  37. #include "llnotificationsutil.h"
  38. #include "llfloaterreg.h"
  39. #include "llfloater.h"
  40. #include "llgroupactions.h"
  41. #include "llagent.h"
  42. #include "llsidetraypanelcontainer.h"
  43. #include "llpanelgroupnotices.h"
  44. #include "llpanelgroupgeneral.h"
  45. #include "llaccordionctrltab.h"
  46. #include "llaccordionctrl.h"
  47. #include "lltrans.h"
  48. static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray");
  49. LLPanelGroupTab::LLPanelGroupTab()
  50. : LLPanel(),
  51. mAllowEdit(TRUE),
  52. mHasModal(FALSE)
  53. {
  54. mGroupID = LLUUID::null;
  55. }
  56. LLPanelGroupTab::~LLPanelGroupTab()
  57. {
  58. }
  59. BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp)
  60. {
  61. //default to being visible
  62. return TRUE;
  63. }
  64. BOOL LLPanelGroupTab::postBuild()
  65. {
  66. return TRUE;
  67. }
  68. LLPanelGroup::LLPanelGroup()
  69. : LLPanel(),
  70. LLGroupMgrObserver( LLUUID() ),
  71. mSkipRefresh(FALSE),
  72. mButtonJoin(NULL)
  73. {
  74. // Set up the factory callbacks.
  75. // Roles sub tabs
  76. LLGroupMgr::getInstance()->addObserver(this);
  77. }
  78. LLPanelGroup::~LLPanelGroup()
  79. {
  80. LLGroupMgr::getInstance()->removeObserver(this);
  81. if(LLVoiceClient::instanceExists())
  82. {
  83. LLVoiceClient::getInstance()->removeObserver(this);
  84. }
  85. }
  86. void LLPanelGroup::onOpen(const LLSD& key)
  87. {
  88. if(!key.has("group_id"))
  89. return;
  90. LLUUID group_id = key["group_id"];
  91. if(!key.has("action"))
  92. {
  93. setGroupID(group_id);
  94. getChild<LLAccordionCtrl>("groups_accordion")->expandDefaultTab();
  95. return;
  96. }
  97. std::string str_action = key["action"];
  98. if(str_action == "refresh")
  99. {
  100. if(mID == group_id || group_id == LLUUID::null)
  101. refreshData();
  102. }
  103. else if(str_action == "close")
  104. {
  105. onBackBtnClick();
  106. }
  107. else if(str_action == "create")
  108. {
  109. setGroupID(LLUUID::null);
  110. }
  111. else if(str_action == "refresh_notices")
  112. {
  113. LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
  114. if(panel_notices)
  115. panel_notices->refreshNotices();
  116. }
  117. }
  118. BOOL LLPanelGroup::postBuild()
  119. {
  120. mDefaultNeedsApplyMesg = getString("default_needs_apply_text");
  121. mWantApplyMesg = getString("want_apply_text");
  122. LLButton* button;
  123. button = getChild<LLButton>("btn_apply");
  124. button->setClickedCallback(onBtnApply, this);
  125. button->setVisible(true);
  126. button->setEnabled(false);
  127. button = getChild<LLButton>("btn_call");
  128. button->setClickedCallback(onBtnGroupCallClicked, this);
  129. button = getChild<LLButton>("btn_chat");
  130. button->setClickedCallback(onBtnGroupChatClicked, this);
  131. button = getChild<LLButton>("btn_cancel");
  132. button->setVisible(false); button->setEnabled(true);
  133. button = getChild<LLButton>("btn_refresh");
  134. button->setClickedCallback(onBtnRefresh, this);
  135. getChild<LLButton>("btn_create")->setVisible(false);
  136. childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
  137. childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
  138. childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL);
  139. LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
  140. LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
  141. LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
  142. LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
  143. if(panel_general) mTabs.push_back(panel_general);
  144. if(panel_roles) mTabs.push_back(panel_roles);
  145. if(panel_notices) mTabs.push_back(panel_notices);
  146. if(panel_land) mTabs.push_back(panel_land);
  147. if(panel_general)
  148. {
  149. panel_general->setupCtrls(this);
  150. button = panel_general->getChild<LLButton>("btn_join");
  151. button->setVisible(false);
  152. button->setEnabled(true);
  153. mButtonJoin = button;
  154. mButtonJoin->setCommitCallback(boost::bind(&LLPanelGroup::onBtnJoin,this));
  155. mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
  156. }
  157. LLVoiceClient::getInstance()->addObserver(this);
  158. return TRUE;
  159. }
  160. void LLPanelGroup::reposButton(const std::string& name)
  161. {
  162. LLButton* button = findChild<LLButton>(name);
  163. if(!button)
  164. return;
  165. LLRect btn_rect = button->getRect();
  166. btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
  167. button->setRect(btn_rect);
  168. }
  169. void LLPanelGroup::reposButtons()
  170. {
  171. LLButton* button_refresh = findChild<LLButton>("btn_refresh");
  172. LLButton* button_cancel = findChild<LLButton>("btn_cancel");
  173. if(button_refresh && button_cancel && button_refresh->getVisible() && button_cancel->getVisible())
  174. {
  175. LLRect btn_refresh_rect = button_refresh->getRect();
  176. LLRect btn_cancel_rect = button_cancel->getRect();
  177. btn_refresh_rect.setLeftTopAndSize( btn_cancel_rect.mLeft + btn_cancel_rect.getWidth() + 2,
  178. btn_refresh_rect.getHeight() + 2, btn_refresh_rect.getWidth(), btn_refresh_rect.getHeight());
  179. button_refresh->setRect(btn_refresh_rect);
  180. }
  181. reposButton("btn_apply");
  182. reposButton("btn_create");
  183. reposButton("btn_refresh");
  184. reposButton("btn_cancel");
  185. reposButton("btn_chat");
  186. reposButton("btn_call");
  187. }
  188. void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
  189. {
  190. LLPanel::reshape(width, height, called_from_parent );
  191. reposButtons();
  192. }
  193. void LLPanelGroup::onBackBtnClick()
  194. {
  195. LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
  196. if(parent)
  197. {
  198. parent->openPreviousPanel();
  199. }
  200. }
  201. void LLPanelGroup::onBtnCreate()
  202. {
  203. LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel");
  204. if(!panel_general)
  205. return;
  206. std::string apply_mesg;
  207. if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
  208. return;
  209. if ( !apply_mesg.empty() )
  210. {
  211. LLSD args;
  212. args["MESSAGE"] = apply_mesg;
  213. LLNotificationsUtil::add("GenericAlert", args);
  214. }
  215. }
  216. void LLPanelGroup::onBtnRefresh(void* user_data)
  217. {
  218. LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
  219. self->refreshData();
  220. }
  221. void LLPanelGroup::onBtnApply(void* user_data)
  222. {
  223. LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
  224. self->apply();
  225. }
  226. void LLPanelGroup::onBtnGroupCallClicked(void* user_data)
  227. {
  228. LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
  229. self->callGroup();
  230. }
  231. void LLPanelGroup::onBtnGroupChatClicked(void* user_data)
  232. {
  233. LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
  234. self->chatGroup();
  235. }
  236. void LLPanelGroup::onBtnJoin()
  237. {
  238. lldebugs << "joining group: " << mID << llendl;
  239. LLGroupActions::join(mID);
  240. }
  241. void LLPanelGroup::onBtnCancel()
  242. {
  243. onBackBtnClick();
  244. }
  245. void LLPanelGroup::changed(LLGroupChange gc)
  246. {
  247. for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
  248. (*it)->update(gc);
  249. update(gc);
  250. }
  251. // virtual
  252. void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal)
  253. {
  254. if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
  255. {
  256. return;
  257. }
  258. childSetEnabled("btn_call", LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking());
  259. }
  260. void LLPanelGroup::notifyObservers()
  261. {
  262. changed(GC_ALL);
  263. }
  264. void LLPanelGroup::update(LLGroupChange gc)
  265. {
  266. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
  267. if(gdatap)
  268. {
  269. std::string group_name = gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName;
  270. childSetValue("group_name", group_name);
  271. childSetToolTip("group_name",group_name);
  272. LLGroupData agent_gdatap;
  273. bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
  274. bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;
  275. mButtonJoin->setVisible(join_btn_visible);
  276. mJoinText->setVisible(join_btn_visible);
  277. if(join_btn_visible)
  278. {
  279. LLStringUtil::format_map_t string_args;
  280. std::string fee_buff;
  281. if(gdatap->mMembershipFee)
  282. {
  283. string_args["[AMOUNT]"] = llformat("%d", gdatap->mMembershipFee);
  284. fee_buff = getString("group_join_btn", string_args);
  285. }
  286. else
  287. {
  288. fee_buff = getString("group_join_free", string_args);
  289. }
  290. mJoinText->setValue(fee_buff);
  291. }
  292. }
  293. }
  294. void LLPanelGroup::setGroupID(const LLUUID& group_id)
  295. {
  296. std::string str_group_id;
  297. group_id.toString(str_group_id);
  298. bool is_same_id = group_id == mID;
  299. LLGroupMgr::getInstance()->removeObserver(this);
  300. mID = group_id;
  301. LLGroupMgr::getInstance()->addObserver(this);
  302. for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
  303. (*it)->setGroupID(group_id);
  304. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
  305. if(gdatap)
  306. {
  307. std::string group_name = gdatap->mName.empty() ? LLTrans::getString("LoadingData") : gdatap->mName;
  308. childSetValue("group_name", group_name);
  309. childSetToolTip("group_name",group_name);
  310. }
  311. LLButton* button_apply = findChild<LLButton>("btn_apply");
  312. LLButton* button_refresh = findChild<LLButton>("btn_refresh");
  313. LLButton* button_create = findChild<LLButton>("btn_create");
  314. LLButton* button_cancel = findChild<LLButton>("btn_cancel");
  315. LLButton* button_call = findChild<LLButton>("btn_call");
  316. LLButton* button_chat = findChild<LLButton>("btn_chat");
  317. bool is_null_group_id = group_id == LLUUID::null;
  318. if(button_apply)
  319. button_apply->setVisible(!is_null_group_id);
  320. if(button_refresh)
  321. button_refresh->setVisible(!is_null_group_id);
  322. if(button_create)
  323. button_create->setVisible(is_null_group_id);
  324. if(button_cancel)
  325. button_cancel->setVisible(!is_null_group_id);
  326. if(button_call)
  327. button_call->setVisible(!is_null_group_id);
  328. if(button_chat)
  329. button_chat->setVisible(!is_null_group_id);
  330. getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id);
  331. LLAccordionCtrl* tab_ctrl = getChild<LLAccordionCtrl>("groups_accordion");
  332. tab_ctrl->reset();
  333. LLAccordionCtrlTab* tab_general = getChild<LLAccordionCtrlTab>("group_general_tab");
  334. LLAccordionCtrlTab* tab_roles = getChild<LLAccordionCtrlTab>("group_roles_tab");
  335. LLAccordionCtrlTab* tab_notices = getChild<LLAccordionCtrlTab>("group_notices_tab");
  336. LLAccordionCtrlTab* tab_land = getChild<LLAccordionCtrlTab>("group_land_tab");
  337. if(mButtonJoin)
  338. mButtonJoin->setVisible(false);
  339. if(is_null_group_id)//creating new group
  340. {
  341. if(!tab_general->getDisplayChildren())
  342. tab_general->changeOpenClose(tab_general->getDisplayChildren());
  343. if(tab_roles->getDisplayChildren())
  344. tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
  345. if(tab_notices->getDisplayChildren())
  346. tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
  347. if(tab_land->getDisplayChildren())
  348. tab_land->changeOpenClose(tab_land->getDisplayChildren());
  349. tab_roles->setVisible(false);
  350. tab_notices->setVisible(false);
  351. tab_land->setVisible(false);
  352. getChild<LLUICtrl>("group_name")->setVisible(false);
  353. getChild<LLUICtrl>("group_name_editor")->setVisible(true);
  354. if(button_call)
  355. button_call->setVisible(false);
  356. if(button_chat)
  357. button_chat->setVisible(false);
  358. }
  359. else
  360. {
  361. if(!is_same_id)
  362. {
  363. if(!tab_general->getDisplayChildren())
  364. tab_general->changeOpenClose(tab_general->getDisplayChildren());
  365. if(tab_roles->getDisplayChildren())
  366. tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
  367. if(tab_notices->getDisplayChildren())
  368. tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
  369. if(tab_land->getDisplayChildren())
  370. tab_land->changeOpenClose(tab_land->getDisplayChildren());
  371. }
  372. LLGroupData agent_gdatap;
  373. bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlike();
  374. tab_roles->setVisible(is_member);
  375. tab_notices->setVisible(is_member);
  376. tab_land->setVisible(is_member);
  377. getChild<LLUICtrl>("group_name")->setVisible(true);
  378. getChild<LLUICtrl>("group_name_editor")->setVisible(false);
  379. if(button_apply)
  380. button_apply->setVisible(is_member);
  381. if(button_call)
  382. button_call->setVisible(is_member);
  383. if(button_chat)
  384. button_chat->setVisible(is_member);
  385. }
  386. tab_ctrl->arrange();
  387. reposButtons();
  388. update(GC_ALL);//show/hide "join" button if data is already ready
  389. }
  390. bool LLPanelGroup::apply(LLPanelGroupTab* tab)
  391. {
  392. if(!tab)
  393. return false;
  394. std::string mesg;
  395. if ( !tab->needsApply(mesg) )
  396. return true;
  397. std::string apply_mesg;
  398. if(tab->apply( apply_mesg ) )
  399. {
  400. //we skip refreshing group after ew manually apply changes since its very annoying
  401. //for those who are editing group
  402. mSkipRefresh = TRUE;
  403. return true;
  404. }
  405. if ( !apply_mesg.empty() )
  406. {
  407. LLSD args;
  408. args["MESSAGE"] = apply_mesg;
  409. LLNotificationsUtil::add("GenericAlert", args);
  410. }
  411. return false;
  412. }
  413. bool LLPanelGroup::apply()
  414. {
  415. return apply(findChild<LLPanelGroupTab>("group_general_tab_panel"))
  416. && apply(findChild<LLPanelGroupTab>("group_roles_tab_panel"))
  417. && apply(findChild<LLPanelGroupTab>("group_notices_tab_panel"))
  418. && apply(findChild<LLPanelGroupTab>("group_land_tab_panel"))
  419. ;
  420. }
  421. // virtual
  422. void LLPanelGroup::draw()
  423. {
  424. LLPanel::draw();
  425. if (mRefreshTimer.hasExpired())
  426. {
  427. mRefreshTimer.stop();
  428. childEnable("btn_refresh");
  429. childEnable("groups_accordion");
  430. }
  431. LLButton* button_apply = findChild<LLButton>("btn_apply");
  432. if(button_apply && button_apply->getVisible())
  433. {
  434. bool enable = false;
  435. std::string mesg;
  436. for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
  437. enable = enable || (*it)->needsApply(mesg);
  438. childSetEnabled("btn_apply", enable);
  439. }
  440. }
  441. void LLPanelGroup::refreshData()
  442. {
  443. if(mSkipRefresh)
  444. {
  445. mSkipRefresh = FALSE;
  446. return;
  447. }
  448. LLGroupMgr::getInstance()->clearGroupData(getID());
  449. setGroupID(getID());
  450. // 5 second timeout
  451. childDisable("btn_refresh");
  452. childDisable("groups_accordion");
  453. mRefreshTimer.start();
  454. mRefreshTimer.setTimerExpirySec(5);
  455. }
  456. void LLPanelGroup::callGroup()
  457. {
  458. LLGroupActions::startCall(getID());
  459. }
  460. void LLPanelGroup::chatGroup()
  461. {
  462. LLGroupActions::startIM(getID());
  463. }
  464. void LLPanelGroup::showNotice(const std::string& subject,
  465. const std::string& message,
  466. const bool& has_inventory,
  467. const std::string& inventory_name,
  468. LLOfferInfo* inventory_offer)
  469. {
  470. LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
  471. if(!panel_notices)
  472. {
  473. // We need to clean up that inventory offer.
  474. if (inventory_offer)
  475. {
  476. inventory_offer->forceResponse(IOR_DECLINE);
  477. }
  478. return;
  479. }
  480. panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
  481. }
  482. //static
  483. void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id)
  484. {
  485. LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray");
  486. if(!panel)
  487. return;
  488. panel->setGroupID(group_id);
  489. }
  490. //static
  491. void LLPanelGroup::showNotice(const std::string& subject,
  492. const std::string& message,
  493. const LLUUID& group_id,
  494. const bool& has_inventory,
  495. const std::string& inventory_name,
  496. LLOfferInfo* inventory_offer)
  497. {
  498. LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray");
  499. if(!panel)
  500. return;
  501. if(panel->getID() != group_id)//???? only for current group_id or switch panels? FIXME
  502. return;
  503. panel->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
  504. }