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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llpanelgroupinvite.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2006-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. #include "llviewerprecompiledheaders.h"
  32. #include "llpanelgroupinvite.h"
  33. #include "llagent.h"
  34. #include "llfloateravatarpicker.h"
  35. #include "llbutton.h"
  36. #include "llcallingcard.h"
  37. #include "llcombobox.h"
  38. #include "llgroupactions.h"
  39. #include "llgroupmgr.h"
  40. #include "llnamelistctrl.h"
  41. #include "llnotificationsutil.h"
  42. #include "llscrolllistitem.h"
  43. #include "llspinctrl.h"
  44. #include "lltextbox.h"
  45. #include "llviewerobject.h"
  46. #include "llviewerobjectlist.h"
  47. #include "lluictrlfactory.h"
  48. #include "llviewerwindow.h"
  49. class LLPanelGroupInvite::impl
  50. {
  51. public:
  52. impl(const LLUUID& group_id);
  53. ~impl();
  54. void addUsers(const std::vector<std::string>& names,
  55.   const std::vector<LLUUID>& agent_ids);
  56. void submitInvitations();
  57. void addRoleNames(LLGroupMgrGroupData* gdatap);
  58. void handleRemove();
  59. void handleSelection();
  60. static void callbackClickCancel(void* userdata);
  61. static void callbackClickOK(void* userdata);
  62. static void callbackClickAdd(void* userdata);
  63. static void callbackClickRemove(void* userdata);
  64. static void callbackSelect(LLUICtrl* ctrl, void* userdata);
  65. static void callbackAddUsers(const std::vector<std::string>& names,
  66.  const std::vector<LLUUID>& agent_ids,
  67.  void* user_data);
  68. bool inviteOwnerCallback(const LLSD& notification, const LLSD& response);
  69. public:
  70. LLUUID mGroupID;
  71. std::string mLoadingText;
  72. LLNameListCtrl *mInvitees;
  73. LLComboBox      *mRoleNames;
  74. LLButton *mOKButton;
  75.   LLButton *mRemoveButton;
  76. LLTextBox *mGroupName;
  77. std::string mOwnerWarning;
  78. std::string mAlreadyInGroup;
  79. bool mConfirmedOwnerInvite;
  80. void (*mCloseCallback)(void* data);
  81. void* mCloseCallbackUserData;
  82. };
  83. LLPanelGroupInvite::impl::impl(const LLUUID& group_id):
  84. mGroupID( group_id ),
  85. mLoadingText (),
  86. mInvitees ( NULL ),
  87. mRoleNames( NULL ),
  88. mOKButton ( NULL ),
  89. mRemoveButton( NULL ),
  90. mGroupName( NULL ),
  91. mConfirmedOwnerInvite( false ),
  92. mCloseCallback( NULL ),
  93. mCloseCallbackUserData( NULL )
  94. {
  95. }
  96. LLPanelGroupInvite::impl::~impl()
  97. {
  98. }
  99. void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
  100. const std::vector<LLUUID>& agent_ids)
  101. {
  102. std::string name;
  103. LLUUID id;
  104. for (S32 i = 0; i < (S32)names.size(); i++)
  105. {
  106. name = names[i];
  107. id = agent_ids[i];
  108. // Make sure this agent isn't already in the list.
  109. bool already_in_list = false;
  110. std::vector<LLScrollListItem*> items = mInvitees->getAllData();
  111. for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
  112.  iter != items.end(); ++iter)
  113. {
  114. LLScrollListItem* item = *iter;
  115. if (item->getUUID() == id)
  116. {
  117. already_in_list = true;
  118. break;
  119. }
  120. }
  121. if (already_in_list)
  122. {
  123. continue;
  124. }
  125. //add the name to the names list
  126. LLSD row;
  127. row["id"] = id;
  128. row["columns"][0]["value"] = name;
  129. mInvitees->addElement(row);
  130. }
  131. }
  132. void LLPanelGroupInvite::impl::submitInvitations()
  133. {
  134. std::map<LLUUID, LLUUID> role_member_pairs;
  135. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
  136. // Default to everyone role.
  137. LLUUID role_id = LLUUID::null;
  138. if (mRoleNames)
  139. {
  140. role_id = mRoleNames->getCurrentID();
  141. // owner role: display confirmation and wait for callback
  142. if ((role_id == gdatap->mOwnerRole) && (!mConfirmedOwnerInvite))
  143. {
  144. LLSD args;
  145. args["MESSAGE"] = mOwnerWarning;
  146. LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupInvite::impl::inviteOwnerCallback, this, _1, _2));
  147. return; // we'll be called again if user confirms
  148. }
  149. }
  150. bool already_in_group = false;
  151. //loop over the users
  152. std::vector<LLScrollListItem*> items = mInvitees->getAllData();
  153. for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
  154.  iter != items.end(); ++iter)
  155. {
  156. LLScrollListItem* item = *iter;
  157. if(LLGroupActions::isAvatarMemberOfGroup(mGroupID, item->getUUID()))
  158. {
  159. already_in_group = true;
  160. continue;
  161. }
  162. role_member_pairs[item->getUUID()] = role_id;
  163. }
  164. LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs);
  165. if(already_in_group)
  166. {
  167. LLSD msg;
  168. msg["MESSAGE"] = mAlreadyInGroup;
  169. LLNotificationsUtil::add("GenericAlert", msg);
  170. }
  171. //then close
  172. (*mCloseCallback)(mCloseCallbackUserData);
  173. }
  174. bool LLPanelGroupInvite::impl::inviteOwnerCallback(const LLSD& notification, const LLSD& response)
  175. {
  176. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  177. switch(option)
  178. {
  179. case 0:
  180. // user confirmed that they really want a new group owner
  181. mConfirmedOwnerInvite = true;
  182. submitInvitations();
  183. break;
  184. case 1:
  185. // fall through
  186. default:
  187. break;
  188. }
  189. return false;
  190. }
  191. void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap)
  192. {
  193. LLGroupMgrGroupData::member_list_t::iterator agent_iter =
  194. gdatap->mMembers.find(gAgent.getID());
  195. //get the member data for the agent if it exists
  196. if ( agent_iter != gdatap->mMembers.end() )
  197. {
  198. LLGroupMemberData* member_data = (*agent_iter).second;
  199. //loop over the agent's roles in the group
  200. //then add those roles to the list of roles that the agent
  201. //can invite people to be
  202. if ( member_data && mRoleNames)
  203. {
  204. //if the user is the owner then we add
  205. //all of the roles in the group
  206. //else if they have the add to roles power
  207. //we add every role but owner,
  208. //else if they have the limited add to roles power
  209. //we add every role the user is in
  210. //else we just add to everyone
  211. bool is_owner   = member_data->isInRole(gdatap->mOwnerRole);
  212. bool can_assign_any = gAgent.hasPowerInGroup(mGroupID,
  213.  GP_ROLE_ASSIGN_MEMBER);
  214. bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID,
  215.  GP_ROLE_ASSIGN_MEMBER_LIMITED);
  216. LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.begin();
  217. LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end();
  218. //populate the role list
  219. for ( ; rit != end; ++rit)
  220. {
  221. LLUUID role_id = (*rit).first;
  222. LLRoleData rd;
  223. if ( gdatap->getRoleData(role_id,rd) )
  224. {
  225. // Owners can add any role.
  226. if ( is_owner 
  227. // Even 'can_assign_any' can't add owner role.
  228.  || (can_assign_any && role_id != gdatap->mOwnerRole)
  229. // Add all roles user is in
  230.  || (can_assign_limited && member_data->isInRole(role_id))
  231. // Everyone role.
  232.  || role_id == LLUUID::null )
  233. {
  234. mRoleNames->add(rd.mRoleName,
  235. role_id,
  236. ADD_BOTTOM);
  237. }
  238. }
  239. }
  240. }//end if member data is not null
  241. }//end if agent is in the group
  242. }
  243. //static
  244. void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
  245. {
  246. LLPanelGroupInvite* panelp = (LLPanelGroupInvite*) userdata;
  247. if ( panelp )
  248. {
  249. //Right now this is hard coded with some knowledge that it is part
  250. //of a floater since the avatar picker needs to be added as a dependent
  251. //floater to the parent floater.
  252. //Soon the avatar picker will be embedded into this panel
  253. //instead of being it's own separate floater.  But that is next week.
  254. //This will do for now. -jwolk May 10, 2006
  255. LLFloater* parentp;
  256. parentp = gFloaterView->getParentFloater(panelp);
  257. parentp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(impl::callbackAddUsers, _1, _2,
  258. panelp->mImplementation),
  259.  TRUE));
  260. }
  261. }
  262. //static
  263. void LLPanelGroupInvite::impl::callbackClickRemove(void* userdata)
  264. {
  265. impl* selfp = (impl*) userdata;
  266. if ( selfp ) selfp->handleRemove();
  267. }
  268. void LLPanelGroupInvite::impl::handleRemove()
  269. {
  270. // Check if there is anything selected.
  271. std::vector<LLScrollListItem*> selection = 
  272. mInvitees->getAllSelected();
  273. if (selection.empty()) return;
  274. // Remove all selected invitees.
  275. mInvitees->deleteSelectedItems();
  276. mRemoveButton->setEnabled(FALSE);
  277. }
  278. // static
  279. void LLPanelGroupInvite::impl::callbackSelect(
  280. LLUICtrl* ctrl, void* userdata)
  281. {
  282. impl* selfp = (impl*) userdata;
  283. if ( selfp ) selfp->handleSelection();
  284. }
  285. void LLPanelGroupInvite::impl::handleSelection()
  286. {
  287. // Check if there is anything selected.
  288. std::vector<LLScrollListItem*> selection = 
  289. mInvitees->getAllSelected();
  290. if (selection.empty())
  291. {
  292. mRemoveButton->setEnabled(FALSE);
  293. }
  294. else
  295. {
  296. mRemoveButton->setEnabled(TRUE);
  297. }
  298. }
  299. void LLPanelGroupInvite::impl::callbackClickCancel(void* userdata)
  300. {
  301. impl* selfp = (impl*) userdata;
  302. if ( selfp ) 
  303. {
  304. (*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData);
  305. }
  306. }
  307. void LLPanelGroupInvite::impl::callbackClickOK(void* userdata)
  308. {
  309. impl* selfp = (impl*) userdata;
  310. if ( selfp ) selfp->submitInvitations();
  311. }
  312. //static
  313. void LLPanelGroupInvite::impl::callbackAddUsers(const std::vector<std::string>& names,
  314. const std::vector<LLUUID>& ids,
  315. void* user_data)
  316. {
  317. impl* selfp = (impl*) user_data;
  318. if ( selfp) selfp->addUsers(names, ids);
  319. }
  320. LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id)
  321. : LLPanel(),
  322.   mImplementation(new impl(group_id)),
  323.   mPendingUpdate(FALSE)
  324. {
  325. // Pass on construction of this panel to the control factory.
  326. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_invite.xml");
  327. }
  328. LLPanelGroupInvite::~LLPanelGroupInvite()
  329. {
  330. delete mImplementation;
  331. }
  332. void LLPanelGroupInvite::setCloseCallback(void (*close_callback)(void*),
  333.   void* data)
  334. {
  335. mImplementation->mCloseCallback         = close_callback;
  336. mImplementation->mCloseCallbackUserData = data;
  337. }
  338. void LLPanelGroupInvite::clear()
  339. {
  340. mStoreSelected = LLUUID::null;
  341. mImplementation->mInvitees->deleteAllItems();
  342. mImplementation->mRoleNames->clear();
  343. mImplementation->mRoleNames->removeall();
  344. mImplementation->mOKButton->setEnabled(FALSE);
  345. }
  346. void LLPanelGroupInvite::addUsers(std::vector<LLUUID>& agent_ids)
  347. {
  348. std::vector<std::string> names;
  349. for (S32 i = 0; i < (S32)agent_ids.size(); i++)
  350. {
  351. LLUUID agent_id = agent_ids[i];
  352. LLViewerObject* dest = gObjectList.findObject(agent_id);
  353. std::string fullname;
  354. if(dest && dest->isAvatar())
  355. {
  356. LLNameValue* nvfirst = dest->getNVPair("FirstName");
  357. LLNameValue* nvlast = dest->getNVPair("LastName");
  358. if(nvfirst && nvlast)
  359. {
  360. fullname = std::string(nvfirst->getString()) + " " + std::string(nvlast->getString());
  361. }
  362. if (!fullname.empty())
  363. {
  364. names.push_back(fullname);
  365. else 
  366. {
  367. llwarns << "llPanelGroupInvite: Selected avatar has no name: " << dest->getID() << llendl;
  368. names.push_back("(Unknown)");
  369. }
  370. }
  371. else
  372. {
  373. //looks like user try to invite offline friend
  374. //for offline avatar_id gObjectList.findObject() will return null
  375. //so we need to do this additional search in avatar tracker, see EXT-4732
  376. if (LLAvatarTracker::instance().isBuddy(agent_id))
  377. {
  378. if (!gCacheName->getFullName(agent_id, fullname))
  379. {
  380. // actually it should happen, just in case
  381. gCacheName->get(LLUUID(agent_id), false, boost::bind(
  382. &LLPanelGroupInvite::addUserCallback, this, _1, _2,
  383. _3));
  384. // for this special case!
  385. //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
  386. // removed id will be added in callback
  387. agent_ids.erase(agent_ids.begin() + i);
  388. }
  389. else
  390. {
  391. names.push_back(fullname);
  392. }
  393. }
  394. }
  395. }
  396. mImplementation->addUsers(names, agent_ids);
  397. }
  398. void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& first_name, const std::string& last_name)
  399. {
  400. std::vector<std::string> names;
  401. std::vector<LLUUID> agent_ids;
  402. std::string full_name = first_name + " " + last_name;
  403. agent_ids.push_back(id);
  404. names.push_back(first_name + " " + last_name);
  405. mImplementation->addUsers(names, agent_ids);
  406. }
  407. void LLPanelGroupInvite::draw()
  408. {
  409. LLPanel::draw();
  410. if (mPendingUpdate)
  411. {
  412. updateLists();
  413. }
  414. }
  415.  
  416. void LLPanelGroupInvite::update()
  417. {
  418. mPendingUpdate = FALSE;
  419. if (mImplementation->mGroupName) 
  420. {
  421. mImplementation->mGroupName->setText(mImplementation->mLoadingText);
  422. }
  423. if ( mImplementation->mRoleNames ) 
  424. {
  425. mStoreSelected = mImplementation->mRoleNames->getCurrentID();
  426. mImplementation->mRoleNames->clear();
  427. mImplementation->mRoleNames->removeall();
  428. mImplementation->mRoleNames->add(mImplementation->mLoadingText, LLUUID::null, ADD_BOTTOM);
  429. mImplementation->mRoleNames->setCurrentByID(LLUUID::null);
  430. }
  431. updateLists();
  432. }
  433. void LLPanelGroupInvite::updateLists()
  434. {
  435. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID);
  436. bool waiting = false;
  437. if (gdatap) 
  438. {
  439. if (gdatap->isGroupPropertiesDataComplete()) 
  440. {
  441. if (mImplementation->mGroupName) 
  442. {
  443. mImplementation->mGroupName->setText(gdatap->mName);
  444. }
  445. else 
  446. {
  447. waiting = true;
  448. }
  449. if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete()) 
  450. {
  451. if ( mImplementation->mRoleNames )
  452. {
  453. mImplementation->mRoleNames->clear();
  454. mImplementation->mRoleNames->removeall();
  455. //add the role names and select the everybody role by default
  456. mImplementation->addRoleNames(gdatap);
  457. mImplementation->mRoleNames->setCurrentByID(mStoreSelected);
  458. }
  459. else 
  460. {
  461. waiting = true;
  462. }
  463. else 
  464. {
  465. waiting = true;
  466. }
  467. if (waiting) 
  468. {
  469. if (!mPendingUpdate) 
  470. {
  471. LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
  472. LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
  473. LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
  474. }
  475. mPendingUpdate = TRUE;
  476. else
  477. {
  478. mPendingUpdate = FALSE;
  479. if (mImplementation->mOKButton && mImplementation->mRoleNames->getItemCount()) 
  480. {
  481. mImplementation->mOKButton->setEnabled(TRUE);
  482. }
  483. }
  484. }
  485. BOOL LLPanelGroupInvite::postBuild()
  486. {
  487. BOOL recurse = TRUE;
  488. mImplementation->mLoadingText = getString("loading");
  489. mImplementation->mRoleNames = getChild<LLComboBox>("role_name",
  490.    recurse);
  491. mImplementation->mGroupName = getChild<LLTextBox>("group_name_text", recurse);
  492. mImplementation->mInvitees = 
  493. getChild<LLNameListCtrl>("invitee_list", recurse);
  494. if ( mImplementation->mInvitees )
  495. {
  496. mImplementation->mInvitees->setCommitOnSelectionChange(TRUE);
  497. mImplementation->mInvitees->setCommitCallback(impl::callbackSelect, mImplementation);
  498. }
  499. LLButton* button = getChild<LLButton>("add_button", recurse);
  500. if ( button )
  501. {
  502. // default to opening avatarpicker automatically
  503. // (*impl::callbackClickAdd)((void*)this);
  504. button->setClickedCallback(impl::callbackClickAdd, this);
  505. }
  506. mImplementation->mRemoveButton = 
  507. getChild<LLButton>("remove_button", recurse);
  508. if ( mImplementation->mRemoveButton )
  509. {
  510. mImplementation->mRemoveButton->setClickedCallback(impl::callbackClickRemove, mImplementation);
  511. mImplementation->mRemoveButton->setEnabled(FALSE);
  512. }
  513. mImplementation->mOKButton = 
  514. getChild<LLButton>("ok_button", recurse);
  515. if ( mImplementation->mOKButton )
  516.   {
  517. mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation);
  518. mImplementation->mOKButton->setEnabled(FALSE);
  519.   }
  520. button = getChild<LLButton>("cancel_button", recurse);
  521. if ( button )
  522. {
  523. button->setClickedCallback(impl::callbackClickCancel, mImplementation);
  524. }
  525. mImplementation->mOwnerWarning = getString("confirm_invite_owner_str");
  526. mImplementation->mAlreadyInGroup = getString("already_in_group");
  527. update();
  528. return (mImplementation->mRoleNames &&
  529. mImplementation->mInvitees &&
  530. mImplementation->mRemoveButton);
  531. }