llpanelgrouproles.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:65k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpanelgrouproles.cpp
  3.  * @brief Panel for roles information about a particular group.
  4.  *
  5.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2006-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llcheckboxctrl.h"
  34. #include "llagent.h"
  35. #include "llbutton.h"
  36. #include "llfiltereditor.h"
  37. #include "llfloatergroupinvite.h"
  38. #include "llavataractions.h"
  39. #include "lliconctrl.h"
  40. #include "lllineeditor.h"
  41. #include "llnamelistctrl.h"
  42. #include "llnotifications.h"
  43. #include "llnotificationsutil.h"
  44. #include "llpanelgrouproles.h"
  45. #include "llscrolllistctrl.h"
  46. #include "llscrolllistitem.h"
  47. #include "llscrolllistcell.h"
  48. #include "lltabcontainer.h"
  49. #include "lltextbox.h"
  50. #include "lltexteditor.h"
  51. #include "llviewertexturelist.h"
  52. #include "llviewerwindow.h"
  53. #include "llfocusmgr.h"
  54. #include "roles_constants.h"
  55. static LLRegisterPanelClassWrapper<LLPanelGroupRoles> t_panel_group_roles("panel_group_roles");
  56. bool agentCanRemoveFromRole(const LLUUID& group_id,
  57. const LLUUID& role_id)
  58. {
  59. return gAgent.hasPowerInGroup(group_id, GP_ROLE_REMOVE_MEMBER);
  60. }
  61. bool agentCanAddToRole(const LLUUID& group_id,
  62.    const LLUUID& role_id)
  63. {
  64. if (gAgent.isGodlike())
  65. return true;
  66.     
  67. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
  68. if (!gdatap) 
  69. {
  70. llwarns << "agentCanAddToRole "
  71. << "-- No group data!" << llendl;
  72. return false;
  73. }
  74. //make sure the agent is in the group
  75. LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID());
  76. if (mi == gdatap->mMembers.end())
  77. {
  78. return false;
  79. }
  80. LLGroupMemberData* member_data = (*mi).second;
  81. // Owners can add to any role.
  82. if ( member_data->isInRole(gdatap->mOwnerRole) )
  83. {
  84. return true;
  85. }
  86. // 'Limited assign members' can add to roles the user is in.
  87. if ( gAgent.hasPowerInGroup(group_id, GP_ROLE_ASSIGN_MEMBER_LIMITED) &&
  88. member_data->isInRole(role_id) )
  89. {
  90. return true;
  91. }
  92. // 'assign members' can add to non-owner roles.
  93. if ( gAgent.hasPowerInGroup(group_id, GP_ROLE_ASSIGN_MEMBER) &&
  94.  role_id != gdatap->mOwnerRole )
  95. {
  96. return true;
  97. }
  98. return false;
  99. }
  100. // static
  101. LLPanelGroupRoles::LLPanelGroupRoles()
  102. : LLPanelGroupTab(),
  103. mCurrentTab(NULL),
  104. mRequestedTab( NULL ),
  105. mSubTabContainer( NULL ),
  106. mFirstUse( TRUE ),
  107. mIgnoreTransition( FALSE )
  108. {
  109. }
  110. LLPanelGroupRoles::~LLPanelGroupRoles()
  111. {
  112. }
  113. BOOL LLPanelGroupRoles::postBuild()
  114. {
  115. lldebugs << "LLPanelGroupRoles::postBuild()" << llendl;
  116. mSubTabContainer = getChild<LLTabContainer>("roles_tab_container");
  117. if (!mSubTabContainer) return FALSE;
  118. // Hook up each sub-tabs callback and widgets.
  119. for (S32 i = 0; i < mSubTabContainer->getTabCount(); ++i)
  120. {
  121. LLPanel* panel = mSubTabContainer->getPanelByIndex(i);
  122. LLPanelGroupSubTab* subtabp = dynamic_cast<LLPanelGroupSubTab*>(panel);
  123. if (!subtabp)
  124. {
  125. llwarns << "Invalid subtab panel: " << panel->getName() << llendl;
  126. return FALSE;
  127. }
  128. // Add click callbacks to all the tabs.
  129. mSubTabContainer->setCommitCallback(boost::bind(&LLPanelGroupRoles::handleClickSubTab, this));
  130. // Hand the subtab a pointer to this LLPanelGroupRoles, so that it can
  131. // look around for the widgets it is interested in.
  132. if (!subtabp->postBuildSubTab(this))
  133. return FALSE;
  134. //subtabp->addObserver(this);
  135. }
  136. // Set the current tab to whatever is currently being shown.
  137. mCurrentTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  138. if (!mCurrentTab)
  139. {
  140. // Need to select a tab.
  141. mSubTabContainer->selectFirstTab();
  142. mCurrentTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  143. }
  144. if (!mCurrentTab) return FALSE;
  145. // Act as though this tab was just activated.
  146. mCurrentTab->activate();
  147. // Read apply text from the xml file.
  148. mDefaultNeedsApplyMesg = getString("default_needs_apply_text");
  149. mWantApplyMesg = getString("want_apply_text");
  150. return LLPanelGroupTab::postBuild();
  151. }
  152. BOOL LLPanelGroupRoles::isVisibleByAgent(LLAgent* agentp)
  153. {
  154. /* This power was removed to make group roles simpler
  155. return agentp->hasPowerInGroup(mGroupID, 
  156.    GP_ROLE_CREATE |
  157.    GP_ROLE_DELETE |
  158.    GP_ROLE_PROPERTIES |
  159.    GP_ROLE_VIEW |
  160.    GP_ROLE_ASSIGN_MEMBER |
  161.    GP_ROLE_REMOVE_MEMBER |
  162.    GP_ROLE_CHANGE_ACTIONS |
  163.    GP_MEMBER_INVITE |
  164.    GP_MEMBER_EJECT |
  165.    GP_MEMBER_OPTIONS );
  166. */
  167. return mAllowEdit && agentp->isInGroup(mGroupID);
  168.    
  169. }
  170. void LLPanelGroupRoles::handleClickSubTab()
  171. {
  172. // If we are already handling a transition,
  173. // ignore this.
  174. if (mIgnoreTransition)
  175. {
  176. return;
  177. }
  178. mRequestedTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  179. // Make sure they aren't just clicking the same tab...
  180. if (mRequestedTab == mCurrentTab)
  181. {
  182. return;
  183. }
  184. // Try to switch from the current panel to the panel the user selected.
  185. attemptTransition();
  186. }
  187. BOOL LLPanelGroupRoles::attemptTransition()
  188. {
  189. // Check if the current tab needs to be applied.
  190. std::string mesg;
  191. if (mCurrentTab && mCurrentTab->needsApply(mesg))
  192. {
  193. // If no message was provided, give a generic one.
  194. if (mesg.empty())
  195. {
  196. mesg = mDefaultNeedsApplyMesg;
  197. }
  198. // Create a notify box, telling the user about the unapplied tab.
  199. LLSD args;
  200. args["NEEDS_APPLY_MESSAGE"] = mesg;
  201. args["WANT_APPLY_MESSAGE"] = mWantApplyMesg;
  202. LLNotificationsUtil::add("PanelGroupApply", args, LLSD(),
  203. boost::bind(&LLPanelGroupRoles::handleNotifyCallback, this, _1, _2));
  204. mHasModal = TRUE;
  205. // We need to reselect the current tab, since it isn't finished.
  206. if (mSubTabContainer)
  207. {
  208. mIgnoreTransition = TRUE;
  209. mSubTabContainer->selectTabPanel( mCurrentTab );
  210. mIgnoreTransition = FALSE;
  211. }
  212. // Returning FALSE will block a close action from finishing until
  213. // we get a response back from the user.
  214. return FALSE;
  215. }
  216. else
  217. {
  218. // The current panel didn't have anything it needed to apply.
  219. if (mRequestedTab)
  220. {
  221. transitionToTab();
  222. }
  223. return TRUE;
  224. }
  225. }
  226. void LLPanelGroupRoles::transitionToTab()
  227. {
  228. // Tell the current panel that it is being deactivated.
  229. if (mCurrentTab)
  230. {
  231. mCurrentTab->deactivate();
  232. }
  233. // Tell the new panel that it is being activated.
  234. if (mRequestedTab)
  235. {
  236. // This is now the current tab;
  237. mCurrentTab = mRequestedTab;
  238. mCurrentTab->activate();
  239. }
  240. }
  241. bool LLPanelGroupRoles::handleNotifyCallback(const LLSD& notification, const LLSD& response)
  242. {
  243. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  244. mHasModal = FALSE;
  245. switch (option)
  246. {
  247. case 0: // "Apply Changes"
  248. {
  249. // Try to apply changes, and switch to the requested tab.
  250. std::string apply_mesg;
  251. if ( !apply( apply_mesg ) )
  252. {
  253. // There was a problem doing the apply.
  254. if ( !apply_mesg.empty() )
  255. {
  256. mHasModal = TRUE;
  257. LLSD args;
  258. args["MESSAGE"] = apply_mesg;
  259. LLNotificationsUtil::add("GenericAlert", args, LLSD(), boost::bind(&LLPanelGroupRoles::onModalClose, this, _1, _2));
  260. }
  261. // Skip switching tabs.
  262. break;
  263. }
  264. // This panel's info successfully applied.
  265. // Switch to the next panel.
  266. // No break!  Continue into 'Ignore Changes' which just switches tabs.
  267. mIgnoreTransition = TRUE;
  268. mSubTabContainer->selectTabPanel( mRequestedTab );
  269. mIgnoreTransition = FALSE;
  270. transitionToTab();
  271. break;
  272. }
  273. case 1: // "Ignore Changes"
  274. // Switch to the requested panel without applying changes
  275. cancel();
  276. mIgnoreTransition = TRUE;
  277. mSubTabContainer->selectTabPanel( mRequestedTab );
  278. mIgnoreTransition = FALSE;
  279. transitionToTab();
  280. break;
  281. case 2: // "Cancel"
  282. default:
  283. // Do nothing.  The user is canceling the action.
  284. break;
  285. }
  286. return false;
  287. }
  288. bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& response)
  289. {
  290. mHasModal = FALSE;
  291. return false;
  292. }
  293. bool LLPanelGroupRoles::apply(std::string& mesg)
  294. {
  295. // Pass this along to the currently visible sub tab.
  296. if (!mSubTabContainer) return false;
  297. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  298. if (!panelp) return false;
  299. // Ignore the needs apply message.
  300. std::string ignore_mesg;
  301. if ( !panelp->needsApply(ignore_mesg) )
  302. {
  303. // We don't need to apply anything.
  304. // We're done.
  305. return true;
  306. }
  307. // Try to do the actual apply.
  308. return panelp->apply(mesg);
  309. }
  310. void LLPanelGroupRoles::cancel()
  311. {
  312. // Pass this along to the currently visible sub tab.
  313. if (!mSubTabContainer) return;
  314. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  315. if (!panelp) return;
  316. panelp->cancel();
  317. }
  318. void LLPanelGroupRoles::update(LLGroupChange gc)
  319. {
  320. if (mGroupID.isNull()) return;
  321. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  322. if (panelp)
  323. {
  324. panelp->update(gc);
  325. }
  326. else
  327. {
  328. llwarns << "LLPanelGroupRoles::update() -- No subtab to update!" << llendl;
  329. }
  330. }
  331. void LLPanelGroupRoles::activate()
  332. {
  333. // Start requesting member and role data if needed.
  334. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  335. //if (!gdatap || mFirstUse)
  336. {
  337. // Check member data.
  338. if (!gdatap || !gdatap->isMemberDataComplete() )
  339. {
  340. LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
  341. }
  342. // Check role data.
  343. if (!gdatap || !gdatap->isRoleDataComplete() )
  344. {
  345. // Mildly hackish - clear all pending changes
  346. cancel();
  347. LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
  348. }
  349. // Check role-member mapping data.
  350. if (!gdatap || !gdatap->isRoleMemberDataComplete() )
  351. {
  352. LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
  353. }
  354. // Need this to get base group member powers
  355. if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )
  356. {
  357. LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
  358. }
  359. mFirstUse = FALSE;
  360. }
  361. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  362. if (panelp) panelp->activate();
  363. }
  364. void LLPanelGroupRoles::deactivate()
  365. {
  366. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  367. if (panelp) panelp->deactivate();
  368. }
  369. bool LLPanelGroupRoles::needsApply(std::string& mesg)
  370. {
  371. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  372. if (!panelp) return false;
  373. return panelp->needsApply(mesg);
  374. }
  375. BOOL LLPanelGroupRoles::hasModal()
  376. {
  377. if (mHasModal) return TRUE;
  378. LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
  379. if (!panelp) return FALSE;
  380. return panelp->hasModal();
  381. }
  382. ////////////////////////////
  383. // LLPanelGroupSubTab
  384. ////////////////////////////
  385. LLPanelGroupSubTab::LLPanelGroupSubTab()
  386. : LLPanelGroupTab(),
  387. mHeader(NULL),
  388. mFooter(NULL),
  389. mActivated(false),
  390. mSearchEditor(NULL)
  391. {
  392. }
  393. LLPanelGroupSubTab::~LLPanelGroupSubTab()
  394. {
  395. }
  396. BOOL LLPanelGroupSubTab::postBuildSubTab(LLView* root) 
  397. // Get icons for later use.
  398. mActionIcons.clear();
  399. if (hasString("power_folder_icon"))
  400. {
  401. mActionIcons["folder"] = getString("power_folder_icon");
  402. }
  403. if (hasString("power_all_have_icon"))
  404. {
  405. mActionIcons["full"] = getString("power_all_have_icon");
  406. }
  407. if (hasString("power_partial_icon"))
  408. {
  409. mActionIcons["partial"] = getString("power_partial_icon");
  410. }
  411. return TRUE; 
  412. }
  413. BOOL LLPanelGroupSubTab::postBuild()
  414. {
  415. // Hook up the search widgets.
  416. bool recurse = true;
  417. mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse);
  418. if (!mSearchEditor) 
  419. return FALSE;
  420. mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
  421. return LLPanelGroupTab::postBuild();
  422. }
  423. void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
  424. {
  425. LLPanelGroupTab::setGroupID(id);
  426. if(mSearchEditor)
  427. {
  428. mSearchEditor->clear();
  429. setSearchFilter("");
  430. }
  431. mActivated = false;
  432. }
  433. void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
  434. {
  435. if(mSearchFilter == filter)
  436. return;
  437. mSearchFilter = filter;
  438. LLStringUtil::toLower(mSearchFilter);
  439. update(GC_ALL);
  440. }
  441. void LLPanelGroupSubTab::activate()
  442. {
  443. setOthersVisible(TRUE);
  444. }
  445. void LLPanelGroupSubTab::deactivate()
  446. {
  447. setOthersVisible(FALSE);
  448. }
  449. void LLPanelGroupSubTab::setOthersVisible(BOOL b)
  450. {
  451. if (mHeader)
  452. {
  453. mHeader->setVisible( b );
  454. }
  455. if (mFooter)
  456. {
  457. mFooter->setVisible( b );
  458. }
  459. }
  460. bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action)
  461. {
  462. // If the search filter is empty, everything passes.
  463. if (mSearchFilter.empty()) return true;
  464. LLStringUtil::toLower(action);
  465. std::string::size_type match = action.find(mSearchFilter);
  466. if (std::string::npos == match)
  467. {
  468. // not found
  469. return false;
  470. }
  471. else
  472. {
  473. return true;
  474. }
  475. }
  476. void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, 
  477.   U64 allowed_by_some, 
  478.   U64 allowed_by_all,
  479.   LLUICtrl::commit_callback_t commit_callback,
  480.   BOOL show_all,
  481.   BOOL filter,
  482.   BOOL is_owner_role)
  483. {
  484. if (LLGroupMgr::getInstance()->mRoleActionSets.empty())
  485. {
  486. llwarns << "Can't build action list - no actions found." << llendl;
  487. return;
  488. }
  489. std::vector<LLRoleActionSet*>::iterator ras_it = LLGroupMgr::getInstance()->mRoleActionSets.begin();
  490. std::vector<LLRoleActionSet*>::iterator ras_end = LLGroupMgr::getInstance()->mRoleActionSets.end();
  491. for ( ; ras_it != ras_end; ++ras_it)
  492. {
  493. buildActionCategory(ctrl,
  494. allowed_by_some,
  495. allowed_by_all,
  496. (*ras_it),
  497. commit_callback,
  498. show_all,
  499. filter,
  500. is_owner_role);
  501. }
  502. }
  503. void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
  504.  U64 allowed_by_some,
  505.  U64 allowed_by_all,
  506.  LLRoleActionSet* action_set,
  507.  LLUICtrl::commit_callback_t commit_callback,
  508.  BOOL show_all,
  509.  BOOL filter,
  510.  BOOL is_owner_role)
  511. {
  512. lldebugs << "Building role list for: " << action_set->mActionSetData->mName << llendl;
  513. // See if the allow mask matches anything in this category.
  514. if (show_all || (allowed_by_some & action_set->mActionSetData->mPowerBit))
  515. {
  516. // List all the actions in this category that at least some members have.
  517. LLSD row;
  518. row["columns"][0]["column"] = "icon";
  519. row["columns"][0]["type"] = "icon";
  520. icon_map_t::iterator iter = mActionIcons.find("folder");
  521. if (iter != mActionIcons.end())
  522. {
  523. row["columns"][0]["value"] = (*iter).second;
  524. }
  525. row["columns"][1]["column"] = "action";
  526. row["columns"][1]["type"] = "text";
  527. row["columns"][1]["value"] = action_set->mActionSetData->mName;
  528. row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
  529. LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData);
  530. LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(title_row->getColumn(2)); //?? I have no idea fix getColumn(1) return column spacer...
  531. if (name_textp)
  532. name_textp->setFontStyle(LLFontGL::BOLD);
  533. bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true;
  534. std::vector<LLRoleAction*>::iterator ra_it = action_set->mActions.begin();
  535. std::vector<LLRoleAction*>::iterator ra_end = action_set->mActions.end();
  536. bool items_match_filter = false;
  537. BOOL can_change_actions = (!is_owner_role && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CHANGE_ACTIONS));
  538. for ( ; ra_it != ra_end; ++ra_it)
  539. {
  540. // See if anyone has these action.
  541. if (!show_all && !(allowed_by_some & (*ra_it)->mPowerBit))
  542. {
  543. continue;
  544. }
  545. // See if we are filtering out these actions
  546. // If we aren't using filters, category_matches_filter will be true.
  547. if (!category_matches_filter
  548. && !matchesActionSearchFilter((*ra_it)->mDescription))
  549. {
  550. continue;
  551. }
  552. items_match_filter = true;
  553. // See if everyone has these actions.
  554. bool show_full_strength = false;
  555. if ( (allowed_by_some & (*ra_it)->mPowerBit) == (allowed_by_all & (*ra_it)->mPowerBit) )
  556. {
  557. show_full_strength = true;
  558. }
  559. LLSD row;
  560. S32 column_index = 0;
  561. row["columns"][column_index]["column"] = "icon";
  562. ++column_index;
  563. S32 check_box_index = -1;
  564. if (commit_callback)
  565. {
  566. row["columns"][column_index]["column"] = "checkbox";
  567. row["columns"][column_index]["type"] = "checkbox";
  568. check_box_index = column_index;
  569. ++column_index;
  570. }
  571. else
  572. {
  573. if (show_full_strength)
  574. {
  575. icon_map_t::iterator iter = mActionIcons.find("full");
  576. if (iter != mActionIcons.end())
  577. {
  578. row["columns"][column_index]["column"] = "checkbox";
  579. row["columns"][column_index]["type"] = "icon";
  580. row["columns"][column_index]["value"] = (*iter).second;
  581. ++column_index;
  582. }
  583. }
  584. else
  585. {
  586. icon_map_t::iterator iter = mActionIcons.find("partial");
  587. if (iter != mActionIcons.end())
  588. {
  589. row["columns"][column_index]["column"] = "checkbox";
  590. row["columns"][column_index]["type"] = "icon";
  591. row["columns"][column_index]["value"] = (*iter).second;
  592. ++column_index;
  593. }
  594. row["enabled"] = false;
  595. }
  596. }
  597. row["columns"][column_index]["column"] = "action";
  598. row["columns"][column_index]["value"] = (*ra_it)->mDescription;
  599. row["columns"][column_index]["font"] = "SANSSERIF_SMALL";
  600. LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it));
  601. if (-1 != check_box_index)
  602. {
  603. // Extract the checkbox that was created.
  604. LLScrollListCheck* check_cell = (LLScrollListCheck*) item->getColumn(check_box_index);
  605. LLCheckBoxCtrl* check = check_cell->getCheckBox();
  606. check->setEnabled(can_change_actions);
  607. check->setCommitCallback(commit_callback);
  608. check->setToolTip( check->getLabel() );
  609. if (show_all)
  610. {
  611. check->setTentative(FALSE);
  612. if (allowed_by_some & (*ra_it)->mPowerBit)
  613. {
  614. check->set(TRUE);
  615. }
  616. else
  617. {
  618. check->set(FALSE);
  619. }
  620. }
  621. else
  622. {
  623. check->set(TRUE);
  624. if (show_full_strength)
  625. {
  626. check->setTentative(FALSE);
  627. }
  628. else
  629. {
  630. check->setTentative(TRUE);
  631. }
  632. }
  633. }
  634. }
  635. if (!items_match_filter)
  636. {
  637. S32 title_index = ctrl->getItemIndex(title_row);
  638. ctrl->deleteSingleItem(title_index);
  639. }
  640. }
  641. }
  642. void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)
  643. {
  644. if (mFooter)
  645. {
  646. mFooter->setAllChildrenEnabled(enable);
  647. }
  648. }
  649. ////////////////////////////
  650. // LLPanelGroupMembersSubTab
  651. ////////////////////////////
  652. static LLRegisterPanelClassWrapper<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab");
  653. LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
  654. :  LLPanelGroupSubTab(),
  655. mMembersList(NULL),
  656. mAssignedRolesList(NULL),
  657. mAllowedActionsList(NULL),
  658. mChanged(FALSE),
  659. mPendingMemberUpdate(FALSE),
  660. mHasMatch(FALSE),
  661. mNumOwnerAdditions(0)
  662. {
  663. }
  664. LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
  665. {
  666. }
  667. BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
  668. {
  669. LLPanelGroupSubTab::postBuildSubTab(root);
  670. // Upcast parent so we can ask it for sibling controls.
  671. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
  672. // Look recursively from the parent to find all our widgets.
  673. bool recurse = true;
  674. mHeader = parent->getChild<LLPanel>("members_header", recurse);
  675. mFooter = parent->getChild<LLPanel>("members_footer", recurse);
  676. mMembersList  = parent->getChild<LLNameListCtrl>("member_list", recurse);
  677. mAssignedRolesList = parent->getChild<LLScrollListCtrl>("member_assigned_roles", recurse);
  678. mAllowedActionsList = parent->getChild<LLScrollListCtrl>("member_allowed_actions", recurse);
  679. if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE;
  680. // We want to be notified whenever a member is selected.
  681. mMembersList->setCommitOnSelectionChange(TRUE);
  682. mMembersList->setCommitCallback(onMemberSelect, this);
  683. // Show the member's profile on double click.
  684. mMembersList->setDoubleClickCallback(onMemberDoubleClick, this);
  685. mMembersList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
  686. LLButton* button = parent->getChild<LLButton>("member_invite", recurse);
  687. if ( button )
  688. {
  689. button->setClickedCallback(onInviteMember, this);
  690. button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
  691. }
  692. mEjectBtn = parent->getChild<LLButton>("member_eject", recurse);
  693. if ( mEjectBtn )
  694. {
  695. mEjectBtn->setClickedCallback(onEjectMembers, this);
  696. mEjectBtn->setEnabled(FALSE);
  697. }
  698. return TRUE;
  699. }
  700. void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id)
  701. {
  702. LLPanelGroupSubTab::setGroupID(id);
  703. }
  704. // static
  705. void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data)
  706. {
  707. LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
  708. self->handleMemberSelect();
  709. }
  710. void LLPanelGroupMembersSubTab::handleMemberSelect()
  711. {
  712. lldebugs << "LLPanelGroupMembersSubTab::handleMemberSelect" << llendl;
  713. mAssignedRolesList->deleteAllItems();
  714. mAllowedActionsList->deleteAllItems();
  715. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  716. if (!gdatap) 
  717. {
  718. llwarns << "LLPanelGroupMembersSubTab::handleMemberSelect() "
  719. << "-- No group data!" << llendl;
  720. return;
  721. }
  722. // Check if there is anything selected.
  723. std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
  724. if (selection.empty()) return;
  725. // Build a vector of all selected members, and gather allowed actions.
  726. std::vector<LLUUID> selected_members;
  727. U64 allowed_by_all = 0xffffffffffffLL;
  728. U64 allowed_by_some = 0;
  729. std::vector<LLScrollListItem*>::iterator itor;
  730. for (itor = selection.begin();
  731.  itor != selection.end(); ++itor)
  732. {
  733. LLUUID member_id = (*itor)->getUUID();
  734. selected_members.push_back( member_id );
  735. // Get this member's power mask including any unsaved changes
  736. U64 powers = getAgentPowersBasedOnRoleChanges( member_id );
  737. allowed_by_all &= powers;
  738. allowed_by_some |= powers;
  739. }
  740. std::sort(selected_members.begin(), selected_members.end());
  741. //////////////////////////////////
  742. // Build the allowed actions list.
  743. //////////////////////////////////
  744. buildActionsList(mAllowedActionsList,
  745.  allowed_by_some,
  746.  allowed_by_all,
  747.  NULL,
  748.  FALSE,
  749.  FALSE,
  750.  FALSE);
  751. //////////////////////////////////
  752. // Build the assigned roles list.
  753. //////////////////////////////////
  754. // Add each role to the assigned roles list.
  755. LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin();
  756. LLGroupMgrGroupData::role_list_t::iterator end  = gdatap->mRoles.end();
  757. BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID,
  758. GP_MEMBER_EJECT);
  759. BOOL member_is_owner = FALSE;
  760. for( ; iter != end; ++iter)
  761. {
  762. // Count how many selected users are in this role.
  763. const LLUUID& role_id = iter->first;
  764. LLGroupRoleData* group_role_data = iter->second;
  765. if (group_role_data)
  766. {
  767. const BOOL needs_sort = FALSE;
  768. S32 count = group_role_data->getMembersInRole(
  769. selected_members, needs_sort);
  770. //check if the user has permissions to assign/remove
  771. //members to/from the role (but the ability to add/remove
  772. //should only be based on the "saved" changes to the role
  773. //not in the temp/meta data. -jwolk
  774. BOOL cb_enable = ( (count > 0) ?
  775.    agentCanRemoveFromRole(mGroupID, role_id) :
  776.    agentCanAddToRole(mGroupID, role_id) );
  777. // Owner role has special enabling permissions for removal.
  778. if (cb_enable && (count > 0) && role_id == gdatap->mOwnerRole)
  779. {
  780. // Check if any owners besides this agent are selected.
  781. std::vector<LLUUID>::const_iterator member_iter;
  782. std::vector<LLUUID>::const_iterator member_end =
  783. selected_members.end();
  784. for (member_iter = selected_members.begin();
  785.  member_iter != member_end;
  786.  ++member_iter)
  787. {
  788. // Don't count the agent.
  789. if ((*member_iter) == gAgent.getID()) continue;
  790. // Look up the member data.
  791. LLGroupMgrGroupData::member_list_t::iterator mi = 
  792. gdatap->mMembers.find((*member_iter));
  793. if (mi == gdatap->mMembers.end()) continue;
  794. LLGroupMemberData* member_data = (*mi).second;
  795. // Is the member an owner?
  796. if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
  797. {
  798. // Can't remove other owners.
  799. cb_enable = FALSE;
  800. break;
  801. }
  802. }
  803. }
  804. //now see if there are any role changes for the selected
  805. //members and remember to include them
  806. std::vector<LLUUID>::iterator sel_mem_iter = selected_members.begin();
  807. for (; sel_mem_iter != selected_members.end(); sel_mem_iter++)
  808. {
  809. LLRoleMemberChangeType type;
  810. if ( getRoleChangeType(*sel_mem_iter, role_id, type) )
  811. {
  812. if ( type == RMC_ADD ) count++;
  813. else if ( type == RMC_REMOVE ) count--;
  814. }
  815. }
  816. // If anyone selected is in any role besides 'Everyone' then they can't be ejected.
  817. if (role_id.notNull() && (count > 0))
  818. {
  819. can_eject_members = FALSE;
  820. if (role_id == gdatap->mOwnerRole)
  821. {
  822. member_is_owner = TRUE;
  823. }
  824. }
  825. LLRoleData rd;
  826. if (gdatap->getRoleData(role_id,rd))
  827. {
  828. std::ostringstream label;
  829. label << rd.mRoleName;
  830. // Don't bother showing a count, if there is only 0 or 1.
  831. if (count > 1)
  832. {
  833. label << ": " << count ;
  834. }
  835. LLSD row;
  836. row["id"] = role_id;
  837. row["columns"][0]["column"] = "checkbox";
  838. row["columns"][0]["type"] = "checkbox";
  839. row["columns"][1]["column"] = "role";
  840. row["columns"][1]["value"] = label.str();
  841. if (row["id"].asUUID().isNull())
  842. {
  843. // This is the everyone role, you can't take people out of the everyone role!
  844. row["enabled"] = false;
  845. }
  846. LLScrollListItem* item = mAssignedRolesList->addElement(row);
  847. // Extract the checkbox that was created.
  848. LLScrollListCheck* check_cell = (LLScrollListCheck*) item->getColumn(0);
  849. LLCheckBoxCtrl* check = check_cell->getCheckBox();
  850. check->setCommitCallback(onRoleCheck, this);
  851. check->set( count > 0 );
  852. check->setTentative(
  853. (0 != count)
  854. && (selected_members.size() !=
  855. (std::vector<LLUUID>::size_type)count));
  856. //NOTE: as of right now a user can break the group
  857. //by removing himself from a role if he is the
  858. //last owner.  We should check for this special case
  859. // -jwolk
  860. check->setEnabled(cb_enable);
  861. item->setEnabled(cb_enable);
  862. }
  863. }
  864. else
  865. {
  866. // This could happen if changes are not synced right on sub-panel change.
  867. llwarns << "No group role data for " << iter->second << llendl;
  868. }
  869. }
  870. mAssignedRolesList->setEnabled(TRUE);
  871. if (gAgent.isGodlike())
  872. can_eject_members = TRUE;
  873. if (!can_eject_members && !member_is_owner)
  874. {
  875. // Maybe we can eject them because we are an owner...
  876. LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID());
  877. if (mi != gdatap->mMembers.end())
  878. {
  879. LLGroupMemberData* member_data = (*mi).second;
  880. if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
  881. {
  882. can_eject_members = TRUE;
  883. }
  884. }
  885. }
  886. mEjectBtn->setEnabled(can_eject_members);
  887. }
  888. // static
  889. void LLPanelGroupMembersSubTab::onMemberDoubleClick(void* user_data)
  890. {
  891. LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
  892. self->handleMemberDoubleClick();
  893. }
  894. //static
  895. void LLPanelGroupMembersSubTab::onInviteMember(void *userdata)
  896. {
  897. LLPanelGroupMembersSubTab* selfp = (LLPanelGroupMembersSubTab*) userdata;
  898. if ( selfp )
  899. {
  900. selfp->handleInviteMember();
  901. }
  902. }
  903. void LLPanelGroupMembersSubTab::handleInviteMember()
  904. {
  905. LLFloaterGroupInvite::showForGroup(mGroupID);
  906. }
  907. void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
  908. {
  909. LLPanelGroupMembersSubTab* selfp = (LLPanelGroupMembersSubTab*) userdata;
  910. if ( selfp )
  911. {
  912. selfp->handleEjectMembers();
  913. }
  914. }
  915. void LLPanelGroupMembersSubTab::handleEjectMembers()
  916. {
  917. //send down an eject message
  918. std::vector<LLUUID> selected_members;
  919. std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
  920. if (selection.empty()) return;
  921. std::vector<LLScrollListItem*>::iterator itor;
  922. for (itor = selection.begin() ; 
  923.  itor != selection.end(); ++itor)
  924. {
  925. LLUUID member_id = (*itor)->getUUID();
  926. selected_members.push_back( member_id );
  927. }
  928. mMembersList->deleteSelectedItems();
  929. sendEjectNotifications(mGroupID, selected_members);
  930. LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID,
  931.  selected_members);
  932. }
  933. void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const std::vector<LLUUID>& selected_members)
  934. {
  935. LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
  936. if (group_data)
  937. {
  938. for (std::vector<LLUUID>::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i)
  939. {
  940. LLSD args;
  941. std::string name;
  942. gCacheName->getFullName(*i, name);
  943. args["AVATAR_NAME"] = name;
  944. args["GROUP_NAME"] = group_data->mName;
  945. LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
  946. }
  947. }
  948. }
  949. void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
  950. LLRoleMemberChangeType type)
  951. {
  952. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  953. if (!gdatap) return;
  954. //add that the user is requesting to change the roles for selected
  955. //members
  956. U64 powers_all_have  = 0xffffffffffffLL;
  957. U64 powers_some_have = 0;
  958. BOOL   is_owner_role = ( gdatap->mOwnerRole == role_id );
  959. LLUUID member_id;
  960. std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
  961. if (selection.empty())
  962. {
  963. return;
  964. }
  965. for (std::vector<LLScrollListItem*>::iterator itor = selection.begin() ; 
  966.  itor != selection.end(); ++itor)
  967. {
  968. member_id = (*itor)->getUUID();
  969. //see if we requested a change for this member before
  970. if ( mMemberRoleChangeData.find(member_id) == mMemberRoleChangeData.end() )
  971. {
  972. mMemberRoleChangeData[member_id] = new role_change_data_map_t;
  973. }
  974. role_change_data_map_t* role_change_datap = mMemberRoleChangeData[member_id];
  975. //now check to see if the selected group member
  976. //had changed his association with the selected role before
  977. role_change_data_map_t::iterator  role = role_change_datap->find(role_id);
  978. if ( role != role_change_datap->end() )
  979. {
  980. //see if the new change type cancels out the previous change
  981. if (role->second != type)
  982. {
  983. role_change_datap->erase(role_id);
  984. if ( is_owner_role ) mNumOwnerAdditions--;
  985. }
  986. //else do nothing
  987. if ( role_change_datap->empty() )
  988. {
  989. //the current member now has no role changes
  990. //so erase the role change and erase the member's entry
  991. delete role_change_datap;
  992.                 role_change_datap = NULL;
  993. mMemberRoleChangeData.erase(member_id);
  994. }
  995. }
  996. else
  997. {
  998. //a previously unchanged role is being changed
  999. (*role_change_datap)[role_id] = type;
  1000. if ( is_owner_role && type == RMC_ADD ) mNumOwnerAdditions++;
  1001. }
  1002. //we need to calculate what powers the selected members
  1003. //have (including the role changes we're making)
  1004. //so that we can rebuild the action list
  1005. U64 new_powers = getAgentPowersBasedOnRoleChanges(member_id);
  1006. powers_all_have  &= new_powers;
  1007. powers_some_have |= new_powers;
  1008. }
  1009. mChanged = !mMemberRoleChangeData.empty();
  1010. notifyObservers();
  1011. //alrighty now we need to update the actions list
  1012. //to reflect the changes
  1013. mAllowedActionsList->deleteAllItems();
  1014. buildActionsList(mAllowedActionsList,
  1015.  powers_some_have,
  1016.  powers_all_have,
  1017.  NULL,
  1018.  FALSE,
  1019.  FALSE,
  1020.  FALSE);
  1021. }
  1022. // static 
  1023. void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data)
  1024. {
  1025. LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
  1026. LLCheckBoxCtrl* check_box = static_cast<LLCheckBoxCtrl*>(ctrl);
  1027. if (!check_box || !self) return;
  1028. LLScrollListItem* first_selected =
  1029. self->mAssignedRolesList->getFirstSelected();
  1030. if (first_selected)
  1031. {
  1032. LLUUID role_id = first_selected->getUUID();
  1033. LLRoleMemberChangeType change_type = (check_box->get() ? 
  1034.       RMC_ADD : 
  1035.       RMC_REMOVE);
  1036. self->handleRoleCheck(role_id, change_type);
  1037. }
  1038. }
  1039. void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
  1040. {
  1041. LLScrollListItem* selected = mMembersList->getFirstSelected();
  1042. if (selected)
  1043. {
  1044. LLUUID member_id = selected->getUUID();
  1045. LLAvatarActions::showProfile( member_id );
  1046. }
  1047. }
  1048. void LLPanelGroupMembersSubTab::activate()
  1049. {
  1050. LLPanelGroupSubTab::activate();
  1051. if(!mActivated)
  1052. {
  1053. update(GC_ALL);
  1054. mActivated = true;
  1055. }
  1056. }
  1057. void LLPanelGroupMembersSubTab::deactivate()
  1058. {
  1059. LLPanelGroupSubTab::deactivate();
  1060. }
  1061. bool LLPanelGroupMembersSubTab::needsApply(std::string& mesg)
  1062. {
  1063. return mChanged;
  1064. }
  1065. void LLPanelGroupMembersSubTab::cancel()
  1066. {
  1067. if ( mChanged )
  1068. {
  1069. std::for_each(mMemberRoleChangeData.begin(),
  1070.   mMemberRoleChangeData.end(),
  1071.   DeletePairedPointer());
  1072. mMemberRoleChangeData.clear();
  1073. mChanged = FALSE;
  1074. notifyObservers();
  1075. }
  1076. }
  1077. bool LLPanelGroupMembersSubTab::apply(std::string& mesg)
  1078. {
  1079. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1080. if (!gdatap)
  1081. {
  1082. llwarns << "Unable to get group data for group " << mGroupID << llendl;
  1083. mesg.assign("Unable to save member data.  Try again later.");
  1084. return false;
  1085. }
  1086. if (mChanged)
  1087. {
  1088. //figure out if we are somehow adding an owner or not and alert
  1089. //the user...possibly make it ignorable
  1090. if ( mNumOwnerAdditions > 0 )
  1091. {
  1092. LLRoleData rd;
  1093. LLSD args;
  1094. if ( gdatap->getRoleData(gdatap->mOwnerRole, rd) )
  1095. {
  1096. mHasModal = TRUE;
  1097. args["ROLE_NAME"] = rd.mRoleName;
  1098. LLNotificationsUtil::add("AddGroupOwnerWarning",
  1099. args,
  1100. LLSD(),
  1101. boost::bind(&LLPanelGroupMembersSubTab::addOwnerCB, this, _1, _2));
  1102. }
  1103. else
  1104. {
  1105. llwarns << "Unable to get role information for the owner role in group " << mGroupID << llendl;
  1106. mesg.assign("Unable to retried specific group information.  Try again later");
  1107. return false;
  1108. }
  1109.  
  1110. }
  1111. else
  1112. {
  1113. applyMemberChanges();
  1114. }
  1115. }
  1116. return true;
  1117. }
  1118. bool LLPanelGroupMembersSubTab::addOwnerCB(const LLSD& notification, const LLSD& response)
  1119. {
  1120. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1121. mHasModal = FALSE;
  1122. if (0 == option)
  1123. {
  1124. // User clicked "Yes"
  1125. applyMemberChanges();
  1126. }
  1127. return false;
  1128. }
  1129. void LLPanelGroupMembersSubTab::applyMemberChanges()
  1130. {
  1131. //sucks to do a find again here, but it is in constant time, so, could
  1132. //be worse
  1133. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1134. if (!gdatap)
  1135. {
  1136. llwarns << "Unable to get group data for group " << mGroupID << llendl;
  1137. return;
  1138. }
  1139. //we need to add all of the changed roles data
  1140. //for each member whose role changed
  1141. for (member_role_changes_map_t::iterator member = mMemberRoleChangeData.begin();
  1142.  member != mMemberRoleChangeData.end(); ++member)
  1143. {
  1144. for (role_change_data_map_t::iterator role = member->second->begin();
  1145.  role != member->second->end(); ++role)
  1146. {
  1147. gdatap->changeRoleMember(role->first, //role_id
  1148.  member->first, //member_id
  1149.  role->second); //add/remove
  1150. }
  1151. member->second->clear();
  1152. delete member->second;
  1153. }
  1154. mMemberRoleChangeData.clear();
  1155. LLGroupMgr::getInstance()->sendGroupRoleMemberChanges(mGroupID);
  1156. //force a UI update
  1157. handleMemberSelect();
  1158. mChanged = FALSE;
  1159. mNumOwnerAdditions = 0;
  1160. notifyObservers();
  1161. }
  1162. bool LLPanelGroupMembersSubTab::matchesSearchFilter(const std::string& fullname)
  1163. {
  1164. // If the search filter is empty, everything passes.
  1165. if (mSearchFilter.empty()) return true;
  1166. // Create a full name, and compare it to the search filter.
  1167. std::string fullname_lc(fullname);
  1168. LLStringUtil::toLower(fullname_lc);
  1169. std::string::size_type match = fullname_lc.find(mSearchFilter);
  1170. if (std::string::npos == match)
  1171. {
  1172. // not found
  1173. return false;
  1174. }
  1175. else
  1176. {
  1177. return true;
  1178. }
  1179. }
  1180. U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& agent_id)
  1181. {
  1182. //we loop over all of the changes
  1183. //if we are adding a role, then we simply add the role's powers
  1184. //if we are removing a role, we store that role id away
  1185. //and then we have to build the powers up bases on the roles the agent
  1186. //is in
  1187. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1188. if (!gdatap) 
  1189. {
  1190. llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No group data!" << llendl;
  1191. return GP_NO_POWERS;
  1192. }
  1193. LLGroupMemberData* member_data = gdatap->mMembers[agent_id];
  1194. if ( !member_data )
  1195. {
  1196. llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl;
  1197. return GP_NO_POWERS;
  1198. }
  1199. //see if there are unsaved role changes for this agent
  1200. role_change_data_map_t* role_change_datap = NULL;
  1201. member_role_changes_map_t::iterator member = mMemberRoleChangeData.find(agent_id);
  1202. if ( member != mMemberRoleChangeData.end() )
  1203. {
  1204. //this member has unsaved role changes
  1205. //so grab them
  1206. role_change_datap = (*member).second;
  1207. }
  1208. U64 new_powers = GP_NO_POWERS;
  1209. if ( role_change_datap )
  1210. {
  1211. std::vector<LLUUID> roles_to_be_removed;
  1212. for (role_change_data_map_t::iterator role = role_change_datap->begin();
  1213.  role != role_change_datap->end(); ++ role)
  1214. {
  1215. if ( role->second == RMC_ADD )
  1216. {
  1217. new_powers |= gdatap->getRolePowers(role->first);
  1218. }
  1219. else
  1220. {
  1221. roles_to_be_removed.push_back(role->first);
  1222. }
  1223. }
  1224. //loop over the member's current roles, summing up
  1225. //the powers (not including the role we are removing)
  1226. for (LLGroupMemberData::role_list_t::iterator current_role = member_data->roleBegin();
  1227.  current_role != member_data->roleEnd(); ++current_role)
  1228. {
  1229. bool role_in_remove_list =
  1230. (std::find(roles_to_be_removed.begin(),
  1231.    roles_to_be_removed.end(),
  1232.    current_role->second->getID()) !=
  1233.  roles_to_be_removed.end());
  1234. if ( !role_in_remove_list )
  1235. {
  1236. new_powers |= 
  1237. current_role->second->getRoleData().mRolePowers;
  1238. }
  1239. }
  1240. }
  1241. else
  1242. {
  1243. //there are no changes for this member
  1244. //the member's powers are just the ones stored in the group
  1245. //manager
  1246. new_powers = member_data->getAgentPowers();
  1247. }
  1248. return new_powers;
  1249. }
  1250. //If there is no change, returns false be sure to verify
  1251. //that there is a role change before attempting to get it or else
  1252. //the data will make no sense.  Stores the role change type
  1253. bool LLPanelGroupMembersSubTab::getRoleChangeType(const LLUUID& member_id,
  1254.   const LLUUID& role_id,
  1255.   LLRoleMemberChangeType& type)
  1256. {
  1257. member_role_changes_map_t::iterator member_changes_iter = mMemberRoleChangeData.find(member_id);
  1258. if ( member_changes_iter != mMemberRoleChangeData.end() )
  1259. {
  1260. role_change_data_map_t::iterator role_changes_iter = member_changes_iter->second->find(role_id);
  1261. if ( role_changes_iter != member_changes_iter->second->end() )
  1262. {
  1263. type = role_changes_iter->second;
  1264. return true;
  1265. }
  1266. }
  1267. return false;
  1268. }
  1269. void LLPanelGroupMembersSubTab::draw()
  1270. {
  1271. LLPanelGroupSubTab::draw();
  1272. if (mPendingMemberUpdate)
  1273. {
  1274. updateMembers();
  1275. }
  1276. }
  1277. void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
  1278. {
  1279. if (mGroupID.isNull()) return;
  1280. if ( GC_TITLES == gc || GC_PROPERTIES == gc )
  1281. {
  1282. // Don't care about title or general group properties updates.
  1283. return;
  1284. }
  1285. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1286. if (!gdatap) 
  1287. {
  1288. llwarns << "LLPanelGroupMembersSubTab::update() -- No group data!" << llendl;
  1289. return;
  1290. }
  1291. // Wait for both all data to be retrieved before displaying anything.
  1292. if (   gdatap->isMemberDataComplete() 
  1293. && gdatap->isRoleDataComplete()
  1294. && gdatap->isRoleMemberDataComplete())
  1295. {
  1296. mMemberProgress = gdatap->mMembers.begin();
  1297. mPendingMemberUpdate = TRUE;
  1298. mHasMatch = FALSE;
  1299. }
  1300. else
  1301. {
  1302. // Build a string with info on retrieval progress.
  1303. std::ostringstream retrieved;
  1304. if ( !gdatap->isMemberDataComplete() )
  1305. {
  1306. // Still busy retreiving member list.
  1307. retrieved << "Retrieving member list (" << gdatap->mMembers.size()
  1308.   << " / " << gdatap->mMemberCount << ")...";
  1309. }
  1310. else if( !gdatap->isRoleDataComplete() )
  1311. {
  1312. // Still busy retreiving role list.
  1313. retrieved << "Retrieving role list (" << gdatap->mRoles.size()
  1314.   << " / " << gdatap->mRoleCount << ")...";
  1315. }
  1316. else // (!gdatap->isRoleMemberDataComplete())
  1317. {
  1318. // Still busy retreiving role/member mappings.
  1319. retrieved << "Retrieving role member mappings...";
  1320. }
  1321. mMembersList->setEnabled(FALSE);
  1322. mMembersList->setCommentText(retrieved.str());
  1323. }
  1324. }
  1325. void LLPanelGroupMembersSubTab::updateMembers()
  1326. {
  1327. mPendingMemberUpdate = FALSE;
  1328. // Rebuild the members list.
  1329. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1330. if (!gdatap) 
  1331. {
  1332. llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl;
  1333. return;
  1334. }
  1335. // Make sure all data is still complete.  Incomplete data
  1336. // may occur if we refresh.
  1337. if (   !gdatap->isMemberDataComplete() 
  1338. || !gdatap->isRoleDataComplete()
  1339. || !gdatap->isRoleMemberDataComplete())
  1340. {
  1341. return;
  1342. }
  1343. //cleanup list only for first iretation
  1344. if(mMemberProgress == gdatap->mMembers.begin())
  1345. mMembersList->deleteAllItems();
  1346. LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
  1347. S32 i = 0;
  1348. for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; 
  1349. ++mMemberProgress, ++i)
  1350. {
  1351. if (!mMemberProgress->second)
  1352. continue;
  1353. // Do filtering on name if it is already in the cache.
  1354. bool add_member = true;
  1355. std::string fullname;
  1356. if (gCacheName->getFullName(mMemberProgress->first, fullname))
  1357. {
  1358. if ( !matchesSearchFilter(fullname) )
  1359. {
  1360. add_member = false;
  1361. }
  1362. }
  1363. if (add_member)
  1364. {
  1365. // Build the donated tier string.
  1366. std::ostringstream donated;
  1367. donated << mMemberProgress->second->getContribution() << " sq. m.";
  1368. LLSD row;
  1369. row["id"] = (*mMemberProgress).first;
  1370. row["columns"][0]["column"] = "name";
  1371. // value is filled in by name list control
  1372. row["columns"][1]["column"] = "donated";
  1373. row["columns"][1]["value"] = donated.str();
  1374. row["columns"][2]["column"] = "online";
  1375. row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
  1376. row["columns"][2]["font"] = "SANSSERIF_SMALL";
  1377. LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED);
  1378. LLUUID id = member->getUUID();
  1379. mHasMatch = TRUE;
  1380. }
  1381. }
  1382. if (mMemberProgress == end)
  1383. {
  1384. if (mHasMatch)
  1385. {
  1386. mMembersList->setEnabled(TRUE);
  1387. }
  1388. else
  1389. {
  1390. mMembersList->setEnabled(FALSE);
  1391. mMembersList->setCommentText(std::string("No match."));
  1392. }
  1393. }
  1394. else
  1395. {
  1396. mPendingMemberUpdate = TRUE;
  1397. }
  1398. // This should clear the other two lists, since nothing is selected.
  1399. handleMemberSelect();
  1400. }
  1401. ////////////////////////////
  1402. // LLPanelGroupRolesSubTab
  1403. ////////////////////////////
  1404. static LLRegisterPanelClassWrapper<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab");
  1405. LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
  1406.   : LLPanelGroupSubTab(),
  1407. mRolesList(NULL),
  1408. mAssignedMembersList(NULL),
  1409. mAllowedActionsList(NULL),
  1410. mRoleName(NULL),
  1411. mRoleTitle(NULL),
  1412. mRoleDescription(NULL),
  1413. mMemberVisibleCheck(NULL),
  1414. mDeleteRoleButton(NULL),
  1415. mCreateRoleButton(NULL),
  1416. mHasRoleChange(FALSE)
  1417. {
  1418. }
  1419. LLPanelGroupRolesSubTab::~LLPanelGroupRolesSubTab()
  1420. {
  1421. }
  1422. BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
  1423. {
  1424. LLPanelGroupSubTab::postBuildSubTab(root);
  1425. // Upcast parent so we can ask it for sibling controls.
  1426. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
  1427. // Look recursively from the parent to find all our widgets.
  1428. bool recurse = true;
  1429. mHeader = parent->getChild<LLPanel>("roles_header", recurse);
  1430. mFooter = parent->getChild<LLPanel>("roles_footer", recurse);
  1431. mRolesList  = parent->getChild<LLScrollListCtrl>("role_list", recurse);
  1432. mAssignedMembersList = parent->getChild<LLNameListCtrl>("role_assigned_members", recurse);
  1433. mAllowedActionsList = parent->getChild<LLScrollListCtrl>("role_allowed_actions", recurse);
  1434. mRoleName = parent->getChild<LLLineEditor>("role_name", recurse);
  1435. mRoleTitle = parent->getChild<LLLineEditor>("role_title", recurse);
  1436. mRoleDescription = parent->getChild<LLTextEditor>("role_description", recurse);
  1437. mMemberVisibleCheck = parent->getChild<LLCheckBoxCtrl>("role_visible_in_list", recurse);
  1438. if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList
  1439. || !mRoleName || !mRoleTitle || !mRoleDescription || !mMemberVisibleCheck)
  1440. {
  1441. llwarns << "ARG! element not found." << llendl;
  1442. return FALSE;
  1443. }
  1444. mRemoveEveryoneTxt = getString("cant_delete_role");
  1445. mCreateRoleButton = 
  1446. parent->getChild<LLButton>("role_create", recurse);
  1447. if ( mCreateRoleButton )
  1448. {
  1449. mCreateRoleButton->setClickedCallback(onCreateRole, this);
  1450. mCreateRoleButton->setEnabled(FALSE);
  1451. }
  1452. mDeleteRoleButton =  
  1453. parent->getChild<LLButton>("role_delete", recurse);
  1454. if ( mDeleteRoleButton )
  1455. {
  1456. mDeleteRoleButton->setClickedCallback(onDeleteRole, this);
  1457. mDeleteRoleButton->setEnabled(FALSE);
  1458. }
  1459. mRolesList->setCommitOnSelectionChange(TRUE);
  1460. mRolesList->setCommitCallback(onRoleSelect, this);
  1461. mAssignedMembersList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
  1462. mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange, this);
  1463. mAllowedActionsList->setCommitOnSelectionChange(TRUE);
  1464. mRoleName->setCommitOnFocusLost(TRUE);
  1465. mRoleName->setKeystrokeCallback(onPropertiesKey, this);
  1466. mRoleTitle->setCommitOnFocusLost(TRUE);
  1467. mRoleTitle->setKeystrokeCallback(onPropertiesKey, this);
  1468. mRoleDescription->setCommitOnFocusLost(TRUE);
  1469. mRoleDescription->setCommitCallback(onDescriptionCommit, this);
  1470. mRoleDescription->setFocusReceivedCallback(boost::bind(onDescriptionFocus, _1, this));
  1471. setFooterEnabled(FALSE);
  1472. return TRUE;
  1473. }
  1474. void LLPanelGroupRolesSubTab::activate()
  1475. {
  1476. LLPanelGroupSubTab::activate();
  1477. mRolesList->deselectAllItems();
  1478. mAssignedMembersList->deleteAllItems();
  1479. mAllowedActionsList->deleteAllItems();
  1480. mRoleName->clear();
  1481. mRoleDescription->clear();
  1482. mRoleTitle->clear();
  1483. setFooterEnabled(FALSE);
  1484. mHasRoleChange = FALSE;
  1485. update(GC_ALL);
  1486. }
  1487. void LLPanelGroupRolesSubTab::deactivate()
  1488. {
  1489. lldebugs << "LLPanelGroupRolesSubTab::deactivate()" << llendl;
  1490. LLPanelGroupSubTab::deactivate();
  1491. }
  1492. bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg)
  1493. {
  1494. lldebugs << "LLPanelGroupRolesSubTab::needsApply()" << llendl;
  1495. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1496. return (mHasRoleChange // Text changed in current role
  1497. || (gdatap && gdatap->pendingRoleChanges())); // Pending role changes in the group
  1498. }
  1499. bool LLPanelGroupRolesSubTab::apply(std::string& mesg)
  1500. {
  1501. lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl;
  1502. saveRoleChanges();
  1503. LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID);
  1504. notifyObservers();
  1505. return true;
  1506. }
  1507. void LLPanelGroupRolesSubTab::cancel()
  1508. {
  1509. mHasRoleChange = FALSE;
  1510. LLGroupMgr::getInstance()->cancelGroupRoleChanges(mGroupID);
  1511. notifyObservers();
  1512. }
  1513. LLSD LLPanelGroupRolesSubTab::createRoleItem(const LLUUID& role_id, 
  1514.  std::string name, 
  1515.  std::string title, 
  1516.  S32 members)
  1517. {
  1518. LLSD row;
  1519. row["id"] = role_id;
  1520. row["columns"][0]["column"] = "name";
  1521. row["columns"][0]["value"] = name;
  1522. row["columns"][1]["column"] = "title";
  1523. row["columns"][1]["value"] = title;
  1524. row["columns"][2]["column"] = "members";
  1525. row["columns"][2]["value"] = members;
  1526. return row;
  1527. }
  1528. bool LLPanelGroupRolesSubTab::matchesSearchFilter(std::string rolename, std::string roletitle)
  1529. {
  1530. // If the search filter is empty, everything passes.
  1531. if (mSearchFilter.empty()) return true;
  1532. LLStringUtil::toLower(rolename);
  1533. LLStringUtil::toLower(roletitle);
  1534. std::string::size_type match_name = rolename.find(mSearchFilter);
  1535. std::string::size_type match_title = roletitle.find(mSearchFilter);
  1536. if ( (std::string::npos == match_name)
  1537. && (std::string::npos == match_title))
  1538. {
  1539. // not found
  1540. return false;
  1541. }
  1542. else
  1543. {
  1544. return true;
  1545. }
  1546. }
  1547. void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
  1548. {
  1549. lldebugs << "LLPanelGroupRolesSubTab::update()" << llendl;
  1550. if (mGroupID.isNull()) return;
  1551. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1552. if (!gdatap || !gdatap->isRoleDataComplete())
  1553. {
  1554. LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
  1555. }
  1556. else
  1557. {
  1558. bool had_selection = false;
  1559. LLUUID last_selected;
  1560. if (mRolesList->getFirstSelected())
  1561. {
  1562. last_selected = mRolesList->getFirstSelected()->getUUID();
  1563. had_selection = true;
  1564. }
  1565. mRolesList->deleteAllItems();
  1566. LLScrollListItem* item = NULL;
  1567. LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin();
  1568. LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
  1569. for ( ; rit != end; ++rit)
  1570. {
  1571. LLRoleData rd;
  1572. if (gdatap->getRoleData((*rit).first,rd))
  1573. {
  1574. if (matchesSearchFilter(rd.mRoleName, rd.mRoleTitle))
  1575. {
  1576. // If this is the everyone role, then EVERYONE is in it.
  1577. S32 members_in_role = (*rit).first.isNull() ? gdatap->mMembers.size() : (*rit).second->getTotalMembersInRole();
  1578. LLSD row = createRoleItem((*rit).first,rd.mRoleName, rd.mRoleTitle, members_in_role);
  1579. item = mRolesList->addElement(row, ((*rit).first.isNull()) ? ADD_TOP : ADD_BOTTOM, this);
  1580. if (had_selection && ((*rit).first == last_selected))
  1581. {
  1582. item->setSelected(TRUE);
  1583. }
  1584. }
  1585. }
  1586. else
  1587. {
  1588. llwarns << "LLPanelGroupRolesSubTab::update() No role data for role " << (*rit).first << llendl;
  1589. }
  1590. }
  1591. mRolesList->sortByColumn(std::string("name"), TRUE);
  1592. if ( (gdatap->mRoles.size() < (U32)MAX_ROLES)
  1593. && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE) )
  1594. {
  1595. mCreateRoleButton->setEnabled(TRUE);
  1596. }
  1597. else
  1598. {
  1599. mCreateRoleButton->setEnabled(FALSE);
  1600. }
  1601. if (had_selection)
  1602. {
  1603. handleRoleSelect();
  1604. }
  1605. else
  1606. {
  1607. mAssignedMembersList->deleteAllItems();
  1608. mAllowedActionsList->deleteAllItems();
  1609. mRoleName->clear();
  1610. mRoleDescription->clear();
  1611. mRoleTitle->clear();
  1612. setFooterEnabled(FALSE);
  1613. mDeleteRoleButton->setEnabled(FALSE);
  1614. }
  1615. }
  1616. if (!gdatap || !gdatap->isMemberDataComplete())
  1617. {
  1618. LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
  1619. }
  1620. if (!gdatap || !gdatap->isRoleMemberDataComplete())
  1621. {
  1622. LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID);
  1623. }
  1624. if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)
  1625.     && gdatap
  1626.     && gdatap->isMemberDataComplete()
  1627.     && gdatap->isRoleMemberDataComplete())
  1628. {
  1629. buildMembersList();
  1630. }
  1631. }
  1632. // static
  1633. void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data)
  1634. {
  1635. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1636. self->handleRoleSelect();
  1637. }
  1638. void LLPanelGroupRolesSubTab::handleRoleSelect()
  1639. {
  1640. BOOL can_delete = TRUE;
  1641. lldebugs << "LLPanelGroupRolesSubTab::handleRoleSelect()" << llendl;
  1642. mAssignedMembersList->deleteAllItems();
  1643. mAllowedActionsList->deleteAllItems();
  1644. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1645. if (!gdatap) 
  1646. {
  1647. llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
  1648. << "-- No group data!" << llendl;
  1649. return;
  1650. }
  1651. saveRoleChanges();
  1652. // Check if there is anything selected.
  1653. LLScrollListItem* item = mRolesList->getFirstSelected();
  1654. if (!item)
  1655. {
  1656. setFooterEnabled(FALSE);
  1657. return;
  1658. }
  1659. setFooterEnabled(TRUE);
  1660. LLRoleData rd;
  1661. if (gdatap->getRoleData(item->getUUID(),rd))
  1662. {
  1663. BOOL is_owner_role = ( gdatap->mOwnerRole == item->getUUID() );
  1664. mRoleName->setText(rd.mRoleName);
  1665. mRoleTitle->setText(rd.mRoleTitle);
  1666. mRoleDescription->setText(rd.mRoleDescription);
  1667. mAllowedActionsList->setEnabled(gAgent.hasPowerInGroup(mGroupID,
  1668.    GP_ROLE_CHANGE_ACTIONS));
  1669. buildActionsList(mAllowedActionsList,
  1670.  rd.mRolePowers,
  1671.  0LL,
  1672.  boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false),
  1673.  TRUE,
  1674.  FALSE,
  1675.  is_owner_role);
  1676. mMemberVisibleCheck->set((rd.mRolePowers & GP_MEMBER_VISIBLE_IN_DIR) == GP_MEMBER_VISIBLE_IN_DIR);
  1677. mRoleName->setEnabled(!is_owner_role &&
  1678. gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
  1679. mRoleTitle->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
  1680. mRoleDescription->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
  1681. if ( is_owner_role ) 
  1682. {
  1683. // you can't delete the owner role
  1684. can_delete = FALSE;
  1685. // ... or hide members with this role
  1686. mMemberVisibleCheck->setEnabled(FALSE);
  1687. }
  1688. else
  1689. {
  1690. mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
  1691. }
  1692. if (item->getUUID().isNull())
  1693. {
  1694. // Everyone role, can't edit description or name or delete
  1695. mRoleDescription->setEnabled(FALSE);
  1696. mRoleName->setEnabled(FALSE);
  1697. can_delete = FALSE;
  1698. }
  1699. }
  1700. else
  1701. {
  1702. mRolesList->deselectAllItems();
  1703. mAssignedMembersList->deleteAllItems();
  1704. mAllowedActionsList->deleteAllItems();
  1705. mRoleName->clear();
  1706. mRoleDescription->clear();
  1707. mRoleTitle->clear();
  1708. setFooterEnabled(FALSE);
  1709. can_delete = FALSE;
  1710. }
  1711. mSelectedRole = item->getUUID();
  1712. buildMembersList();
  1713. can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID,
  1714.   GP_ROLE_DELETE);
  1715. mDeleteRoleButton->setEnabled(can_delete);
  1716. }
  1717. void LLPanelGroupRolesSubTab::buildMembersList()
  1718. {
  1719. mAssignedMembersList->deleteAllItems();
  1720. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1721. if (!gdatap) 
  1722. {
  1723. llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
  1724. << "-- No group data!" << llendl;
  1725. return;
  1726. }
  1727. // Check if there is anything selected.
  1728. LLScrollListItem* item = mRolesList->getFirstSelected();
  1729. if (!item) return;
  1730. if (item->getUUID().isNull())
  1731. {
  1732. // Special cased 'Everyone' role
  1733. LLGroupMgrGroupData::member_list_t::iterator mit = gdatap->mMembers.begin();
  1734. LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
  1735. for ( ; mit != end; ++mit)
  1736. {
  1737. mAssignedMembersList->addNameItem((*mit).first);
  1738. }
  1739. }
  1740. else
  1741. {
  1742. LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.find(item->getUUID());
  1743. if (rit != gdatap->mRoles.end())
  1744. {
  1745. LLGroupRoleData* rdatap = (*rit).second;
  1746. if (rdatap)
  1747. {
  1748. std::vector<LLUUID>::const_iterator mit = rdatap->getMembersBegin();
  1749. std::vector<LLUUID>::const_iterator end = rdatap->getMembersEnd();
  1750. for ( ; mit != end; ++mit)
  1751. {
  1752. mAssignedMembersList->addNameItem((*mit));
  1753. }
  1754. }
  1755. }
  1756. }
  1757. }
  1758. struct ActionCBData
  1759. {
  1760. LLPanelGroupRolesSubTab* mSelf;
  1761. LLCheckBoxCtrl*  mCheck;
  1762. };
  1763. void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force)
  1764. {
  1765. LLCheckBoxCtrl* check = dynamic_cast<LLCheckBoxCtrl*>(ctrl);
  1766. if (!check)
  1767. return;
  1768. lldebugs << "LLPanelGroupRolesSubTab::handleActionSelect()" << llendl;
  1769. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1770. if (!gdatap) 
  1771. {
  1772. llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
  1773. << "-- No group data!" << llendl;
  1774. return;
  1775. }
  1776. LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected();
  1777. if (!action_item)
  1778. {
  1779. return;
  1780. }
  1781. LLScrollListItem* role_item = mRolesList->getFirstSelected();
  1782. if (!role_item)
  1783. {
  1784. return;
  1785. }
  1786. LLUUID role_id = role_item->getUUID();
  1787. LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata();
  1788. U64 power = rap->mPowerBit;
  1789. if (check->get())
  1790. {
  1791. if (!force && (    (GP_ROLE_ASSIGN_MEMBER == power)
  1792. || (GP_ROLE_CHANGE_ACTIONS == power) ))
  1793. {
  1794. // Uncheck the item, for now.  It will be
  1795. // checked if they click 'Yes', below.
  1796. check->set(FALSE);
  1797. LLRoleData rd;
  1798. LLSD args;
  1799. if ( gdatap->getRoleData(role_id, rd) )
  1800. {
  1801. args["ACTION_NAME"] = rap->mDescription;
  1802. args["ROLE_NAME"] = rd.mRoleName;
  1803. mHasModal = TRUE;
  1804. std::string warning = "AssignDangerousActionWarning";
  1805. if (GP_ROLE_CHANGE_ACTIONS == power)
  1806. {
  1807. warning = "AssignDangerousAbilityWarning";
  1808. }
  1809. LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check));
  1810. }
  1811. else
  1812. {
  1813. llwarns << "Unable to look up role information for role id: "
  1814. << role_id << llendl;
  1815. }
  1816. }
  1817. else
  1818. {
  1819. gdatap->addRolePower(role_id,power);
  1820. }
  1821. }
  1822. else
  1823. {
  1824. gdatap->removeRolePower(role_id,power);
  1825. }
  1826. mHasRoleChange = TRUE;
  1827. notifyObservers();
  1828. }
  1829. bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check)
  1830. {
  1831. if (!check) return false;
  1832. mHasModal = FALSE;
  1833. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1834. if (0 == option)
  1835. {
  1836. // User clicked "Yes"
  1837. check->set(TRUE);
  1838. const bool force_add = true;
  1839. handleActionCheck(check, force_add);
  1840. }
  1841. return false;
  1842. }
  1843. // static
  1844. void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data)
  1845. {
  1846. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1847. if (!self) return;
  1848. self->mHasRoleChange = TRUE;
  1849. self->notifyObservers();
  1850. }
  1851. // static 
  1852. void LLPanelGroupRolesSubTab::onDescriptionFocus(LLFocusableElement* ctrl, void* user_data)
  1853. {
  1854. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1855. if (!self) return;
  1856. self->mHasRoleChange = TRUE;
  1857. self->notifyObservers();
  1858. }
  1859. // static 
  1860. void LLPanelGroupRolesSubTab::onDescriptionCommit(LLUICtrl* ctrl, void* user_data)
  1861. {
  1862. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1863. if (!self) return;
  1864. self->mHasRoleChange = TRUE;
  1865. self->notifyObservers();
  1866. }
  1867. // static 
  1868. void LLPanelGroupRolesSubTab::onMemberVisibilityChange(LLUICtrl* ctrl, void* user_data)
  1869. {
  1870. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1871. LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl);
  1872. if (!check || !self) return;
  1873. self->handleMemberVisibilityChange(check->get());
  1874. }
  1875. void LLPanelGroupRolesSubTab::handleMemberVisibilityChange(bool value)
  1876. {
  1877. lldebugs << "LLPanelGroupRolesSubTab::handleMemberVisibilityChange()" << llendl;
  1878. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1879. if (!gdatap) 
  1880. {
  1881. llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
  1882. << "-- No group data!" << llendl;
  1883. return;
  1884. }
  1885. LLScrollListItem* role_item = mRolesList->getFirstSelected();
  1886. if (!role_item)
  1887. {
  1888. return;
  1889. }
  1890. if (value)
  1891. {
  1892. gdatap->addRolePower(role_item->getUUID(),GP_MEMBER_VISIBLE_IN_DIR);
  1893. }
  1894. else
  1895. {
  1896. gdatap->removeRolePower(role_item->getUUID(),GP_MEMBER_VISIBLE_IN_DIR);
  1897. }
  1898. }
  1899. // static 
  1900. void LLPanelGroupRolesSubTab::onCreateRole(void* user_data)
  1901. {
  1902. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1903. if (!self) return;
  1904. self->handleCreateRole();
  1905. }
  1906. void LLPanelGroupRolesSubTab::handleCreateRole()
  1907. {
  1908. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1909. if (!gdatap) return;
  1910. LLUUID new_role_id;
  1911. new_role_id.generate();
  1912. LLRoleData rd;
  1913. rd.mRoleName = "New Role";
  1914. gdatap->createRole(new_role_id,rd);
  1915. mRolesList->deselectAllItems(TRUE);
  1916. LLSD row;
  1917. row["id"] = new_role_id;
  1918. row["columns"][0]["column"] = "name";
  1919. row["columns"][0]["value"] = rd.mRoleName;
  1920. mRolesList->addElement(row, ADD_BOTTOM, this);
  1921. mRolesList->selectByID(new_role_id);
  1922. // put focus on name field and select its contents
  1923. if(mRoleName)
  1924. {
  1925. mRoleName->setFocus(TRUE);
  1926. mRoleName->onTabInto();
  1927. gFocusMgr.triggerFocusFlash();
  1928. }
  1929. notifyObservers();
  1930. }
  1931. // static 
  1932. void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data)
  1933. {
  1934. LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
  1935. if (!self) return;
  1936. self->handleDeleteRole();
  1937. }
  1938. void LLPanelGroupRolesSubTab::handleDeleteRole()
  1939. {
  1940. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1941. if (!gdatap) return;
  1942. LLScrollListItem* role_item = mRolesList->getFirstSelected();
  1943. if (!role_item)
  1944. {
  1945. return;
  1946. }
  1947. if (role_item->getUUID().isNull() || role_item->getUUID() == gdatap->mOwnerRole)
  1948. {
  1949. LLSD args;
  1950. args["MESSAGE"] = mRemoveEveryoneTxt;
  1951. LLNotificationsUtil::add("GenericAlert", args);
  1952. return;
  1953. }
  1954. gdatap->deleteRole(role_item->getUUID());
  1955. mRolesList->deleteSingleItem(mRolesList->getFirstSelectedIndex());
  1956. mRolesList->selectFirstItem();
  1957. notifyObservers();
  1958. }
  1959. void LLPanelGroupRolesSubTab::saveRoleChanges()
  1960. {
  1961. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  1962. if (!gdatap) return;
  1963. if (mHasRoleChange)
  1964. {
  1965. LLRoleData rd;
  1966. if (!gdatap->getRoleData(mSelectedRole,rd)) return;
  1967. rd.mRoleName = mRoleName->getText();
  1968. rd.mRoleDescription = mRoleDescription->getText();
  1969. rd.mRoleTitle = mRoleTitle->getText();
  1970. gdatap->setRoleData(mSelectedRole,rd);
  1971. mRolesList->deleteSingleItem(mRolesList->getItemIndex(mSelectedRole));
  1972. LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,0);
  1973. LLScrollListItem* item = mRolesList->addElement(row, ADD_BOTTOM, this);
  1974. item->setSelected(TRUE);
  1975. mHasRoleChange = FALSE;
  1976. }
  1977. }
  1978. ////////////////////////////
  1979. // LLPanelGroupActionsSubTab
  1980. ////////////////////////////
  1981. static LLRegisterPanelClassWrapper<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab");
  1982. LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab()
  1983. : LLPanelGroupSubTab()
  1984. {
  1985. }
  1986. LLPanelGroupActionsSubTab::~LLPanelGroupActionsSubTab()
  1987. {
  1988. }
  1989. BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
  1990. {
  1991. LLPanelGroupSubTab::postBuildSubTab(root);
  1992. // Upcast parent so we can ask it for sibling controls.
  1993. LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
  1994. // Look recursively from the parent to find all our widgets.
  1995. bool recurse = true;
  1996. mHeader = parent->getChild<LLPanel>("actions_header", recurse);
  1997. mFooter = parent->getChild<LLPanel>("actions_footer", recurse);
  1998. mActionDescription = parent->getChild<LLTextEditor>("action_description", recurse);
  1999. mActionList = parent->getChild<LLScrollListCtrl>("action_list",recurse);
  2000. mActionRoles = parent->getChild<LLScrollListCtrl>("action_roles",recurse);
  2001. mActionMembers  = parent->getChild<LLNameListCtrl>("action_members",recurse);
  2002. if (!mActionList || !mActionDescription || !mActionRoles || !mActionMembers) return FALSE;
  2003. mActionList->setCommitOnSelectionChange(TRUE);
  2004. mActionList->setCommitCallback(boost::bind(&LLPanelGroupActionsSubTab::handleActionSelect, this));
  2005. mActionList->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
  2006. update(GC_ALL);
  2007. return TRUE;
  2008. }
  2009. void LLPanelGroupActionsSubTab::activate()
  2010. {
  2011. LLPanelGroupSubTab::activate();
  2012. update(GC_ALL);
  2013. }
  2014. void LLPanelGroupActionsSubTab::deactivate()
  2015. {
  2016. lldebugs << "LLPanelGroupActionsSubTab::deactivate()" << llendl;
  2017. LLPanelGroupSubTab::deactivate();
  2018. }
  2019. bool LLPanelGroupActionsSubTab::needsApply(std::string& mesg)
  2020. {
  2021. lldebugs << "LLPanelGroupActionsSubTab::needsApply()" << llendl;
  2022. return false;
  2023. }
  2024. bool LLPanelGroupActionsSubTab::apply(std::string& mesg)
  2025. {
  2026. lldebugs << "LLPanelGroupActionsSubTab::apply()" << llendl;
  2027. return true;
  2028. }
  2029. void LLPanelGroupActionsSubTab::update(LLGroupChange gc)
  2030. {
  2031. lldebugs << "LLPanelGroupActionsSubTab::update()" << llendl;
  2032. if (mGroupID.isNull()) return;
  2033. mActionList->deselectAllItems();
  2034. mActionMembers->deleteAllItems();
  2035. mActionRoles->deleteAllItems();
  2036. mActionDescription->clear();
  2037. mActionList->deleteAllItems();
  2038. buildActionsList(mActionList,
  2039.  GP_ALL_POWERS,
  2040.  GP_ALL_POWERS,
  2041.  NULL,
  2042.  FALSE,
  2043.  TRUE,
  2044.  FALSE);
  2045. }
  2046. void LLPanelGroupActionsSubTab::handleActionSelect()
  2047. {
  2048. mActionMembers->deleteAllItems();
  2049. mActionRoles->deleteAllItems();
  2050. U64 power_mask = GP_NO_POWERS;
  2051. std::vector<LLScrollListItem*> selection = 
  2052. mActionList->getAllSelected();
  2053. if (selection.empty()) return;
  2054. LLRoleAction* rap;
  2055. std::vector<LLScrollListItem*>::iterator itor;
  2056. for (itor = selection.begin() ; 
  2057.  itor != selection.end(); ++itor)
  2058. {
  2059. rap = (LLRoleAction*)( (*itor)->getUserdata() );
  2060. power_mask |= rap->mPowerBit;
  2061. }
  2062. if (selection.size() == 1)
  2063. {
  2064. LLScrollListItem* item = selection[0];
  2065. rap = (LLRoleAction*)(item->getUserdata());
  2066. if (rap->mLongDescription.empty())
  2067. {
  2068. mActionDescription->setText(rap->mDescription);
  2069. }
  2070. else
  2071. {
  2072. mActionDescription->setText(rap->mLongDescription);
  2073. }
  2074. }
  2075. else
  2076. {
  2077. mActionDescription->clear();
  2078. }
  2079. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  2080. if (!gdatap) return;
  2081. if (gdatap->isMemberDataComplete())
  2082. {
  2083. LLGroupMgrGroupData::member_list_t::iterator it = gdatap->mMembers.begin();
  2084. LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
  2085. LLGroupMemberData* gmd;
  2086. for ( ; it != end; ++it)
  2087. {
  2088. gmd = (*it).second;
  2089. if (!gmd) continue;
  2090. if ((gmd->getAgentPowers() & power_mask) == power_mask)
  2091. {
  2092. mActionMembers->addNameItem(gmd->getID());
  2093. }
  2094. }
  2095. }
  2096. else
  2097. {
  2098. LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
  2099. }
  2100. if (gdatap->isRoleDataComplete())
  2101. {
  2102. LLGroupMgrGroupData::role_list_t::iterator it = gdatap->mRoles.begin();
  2103. LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
  2104. LLGroupRoleData* rmd;
  2105. for ( ; it != end; ++it)
  2106. {
  2107. rmd = (*it).second;
  2108. if (!rmd) continue;
  2109. if ((rmd->getRoleData().mRolePowers & power_mask) == power_mask)
  2110. {
  2111. mActionRoles->addSimpleElement(rmd->getRoleData().mRoleName);
  2112. }
  2113. }
  2114. }
  2115. else
  2116. {
  2117. LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
  2118. }
  2119. }
  2120. void LLPanelGroupRoles::setGroupID(const LLUUID& id)
  2121. {
  2122. LLPanelGroupTab::setGroupID(id);
  2123. LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab");
  2124. LLPanelGroupRolesSubTab*  group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab");
  2125. LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab");
  2126. if(group_members_tab) group_members_tab->setGroupID(id);
  2127. if(group_roles_tab) group_roles_tab->setGroupID(id);
  2128. if(group_actions_tab) group_actions_tab->setGroupID(id);
  2129. LLButton* button = getChild<LLButton>("member_invite");
  2130. if ( button )
  2131. button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
  2132. if(mSubTabContainer)
  2133. mSubTabContainer->selectTab(0);
  2134. activate();
  2135. }