00001
00035 #include "llviewerprecompiledheaders.h"
00036
00037 #include "llfloaterfriends.h"
00038
00039 #include <sstream>
00040
00041 #include "lldir.h"
00042
00043 #include "llagent.h"
00044 #include "llfloateravatarpicker.h"
00045 #include "llviewerwindow.h"
00046 #include "llbutton.h"
00047 #include "llcallingcard.h"
00048 #include "llfloateravatarinfo.h"
00049 #include "llinventorymodel.h"
00050 #include "llnamelistctrl.h"
00051 #include "llnotify.h"
00052 #include "llresmgr.h"
00053 #include "llimview.h"
00054 #include "lluictrlfactory.h"
00055 #include "llmenucommands.h"
00056 #include "llviewercontrol.h"
00057 #include "llviewermessage.h"
00058 #include "lltimer.h"
00059 #include "lltextbox.h"
00060
00061
00062 #define MAX_FRIEND_SELECT 20
00063 #define DEFAULT_PERIOD 5.0
00064 #define RIGHTS_CHANGE_TIMEOUT 5.0
00065 #define OBSERVER_TIMEOUT 0.5
00066
00067
00068 class LLLocalFriendsObserver : public LLFriendObserver, public LLEventTimer
00069 {
00070 public:
00071 LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater), LLEventTimer(OBSERVER_TIMEOUT)
00072 {
00073 mEventTimer.stop();
00074 }
00075 virtual ~LLLocalFriendsObserver()
00076 {
00077 mFloater = NULL;
00078 }
00079 virtual void changed(U32 mask)
00080 {
00081
00082
00083 mEventTimer.start();
00084
00085
00086 mMask |= mask;
00087 }
00088 virtual BOOL tick()
00089 {
00090 mFloater->updateFriends(mMask);
00091
00092 mEventTimer.stop();
00093 mMask = 0;
00094
00095 return FALSE;
00096 }
00097
00098 protected:
00099 LLPanelFriends* mFloater;
00100 U32 mMask;
00101 };
00102
00103 LLPanelFriends::LLPanelFriends() :
00104 LLPanel(),
00105 LLEventTimer(DEFAULT_PERIOD),
00106 mObserver(NULL),
00107 mShowMaxSelectWarning(TRUE),
00108 mAllowRightsChange(TRUE),
00109 mNumRightsChanged(0)
00110 {
00111 mEventTimer.stop();
00112 mObserver = new LLLocalFriendsObserver(this);
00113 LLAvatarTracker::instance().addObserver(mObserver);
00114 }
00115
00116 LLPanelFriends::~LLPanelFriends()
00117 {
00118 LLAvatarTracker::instance().removeObserver(mObserver);
00119 delete mObserver;
00120 }
00121
00122 BOOL LLPanelFriends::tick()
00123 {
00124 mEventTimer.stop();
00125 mPeriod = DEFAULT_PERIOD;
00126 mAllowRightsChange = TRUE;
00127 updateFriends(LLFriendObserver::ADD);
00128 return FALSE;
00129 }
00130
00131 void LLPanelFriends::updateFriends(U32 changed_mask)
00132 {
00133 LLUUID selected_id;
00134 LLCtrlListInterface *friends_list = childGetListInterface("friend_list");
00135 if (!friends_list) return;
00136 LLCtrlScrollInterface *friends_scroll = childGetScrollInterface("friend_list");
00137 if (!friends_scroll) return;
00138
00139
00140
00141 mShowMaxSelectWarning = false;
00142
00143 LLDynamicArray<LLUUID> selected_friends = getSelectedIDs();
00144 if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
00145 {
00146 refreshNames();
00147 }
00148 else if(changed_mask & LLFriendObserver::POWERS)
00149 {
00150 --mNumRightsChanged;
00151 if(mNumRightsChanged > 0)
00152 {
00153 mPeriod = RIGHTS_CHANGE_TIMEOUT;
00154 mEventTimer.start();
00155 mAllowRightsChange = FALSE;
00156 }
00157 else
00158 {
00159 tick();
00160 }
00161 }
00162 if(selected_friends.size() > 0)
00163 {
00164
00165
00166
00167 friends_list->setCurrentByID(selected_id);
00168 for(LLDynamicArray<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr)
00169 {
00170 friends_list->setSelectedByValue(*itr, true);
00171 }
00172 }
00173
00174 refreshUI();
00175 mShowMaxSelectWarning = true;
00176 }
00177
00178
00179 BOOL LLPanelFriends::postBuild()
00180 {
00181 mFriendsList = getChild<LLScrollListCtrl>("friend_list");
00182 mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
00183 mFriendsList->setMaximumSelectCallback(onMaximumSelect);
00184 mFriendsList->setCommitOnSelectionChange(TRUE);
00185 childSetCommitCallback("friend_list", onSelectName, this);
00186 childSetDoubleClickCallback("friend_list", onClickIM);
00187
00188 refreshNames();
00189
00190 childSetAction("im_btn", onClickIM, this);
00191 childSetAction("profile_btn", onClickProfile, this);
00192 childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
00193 childSetAction("pay_btn", onClickPay, this);
00194 childSetAction("add_btn", onClickAddFriend, this);
00195 childSetAction("remove_btn", onClickRemove, this);
00196
00197 setDefaultBtn("im_btn");
00198
00199 updateFriends(LLFriendObserver::ADD);
00200 refreshUI();
00201
00202
00203 mFriendsList->sortByColumn("friend_name", TRUE);
00204 mFriendsList->sortByColumn("icon_online_status", FALSE);
00205
00206 return TRUE;
00207 }
00208
00209
00210 BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
00211 {
00212 LLAvatarTracker& at = LLAvatarTracker::instance();
00213 const LLRelationship* relationInfo = at.getBuddyInfo(agent_id);
00214 if(!relationInfo) return FALSE;
00215 BOOL online = relationInfo->isOnline();
00216
00217 std::string fullname;
00218 BOOL have_name = gCacheName->getFullName(agent_id, fullname);
00219
00220 LLSD element;
00221 element["id"] = agent_id;
00222 LLSD& friend_column = element["columns"][LIST_FRIEND_NAME];
00223 friend_column["column"] = "friend_name";
00224 friend_column["value"] = fullname;
00225 friend_column["font"] = "SANSSERIF";
00226 friend_column["font-style"] = "NORMAL";
00227
00228 LLSD& online_status_column = element["columns"][LIST_ONLINE_STATUS];
00229 online_status_column["column"] = "icon_online_status";
00230 online_status_column["type"] = "icon";
00231
00232 if (online)
00233 {
00234 friend_column["font-style"] = "BOLD";
00235 online_status_column["value"] = "icon_avatar_online.tga";
00236 }
00237
00238 LLSD& online_column = element["columns"][LIST_VISIBLE_ONLINE];
00239 online_column["column"] = "icon_visible_online";
00240 online_column["type"] = "checkbox";
00241 online_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS);
00242
00243 LLSD& visible_map_column = element["columns"][LIST_VISIBLE_MAP];
00244 visible_map_column["column"] = "icon_visible_map";
00245 visible_map_column["type"] = "checkbox";
00246 visible_map_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION);
00247
00248 LLSD& edit_my_object_column = element["columns"][LIST_EDIT_MINE];
00249 edit_my_object_column["column"] = "icon_edit_mine";
00250 edit_my_object_column["type"] = "checkbox";
00251 edit_my_object_column["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
00252
00253 LLSD& edit_their_object_column = element["columns"][LIST_EDIT_THEIRS];
00254 edit_their_object_column["column"] = "icon_edit_theirs";
00255 edit_their_object_column["type"] = "checkbox";
00256 edit_their_object_column["enabled"] = "";
00257 edit_their_object_column["value"] = relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS);
00258
00259 LLSD& update_gen_column = element["columns"][LIST_FRIEND_UPDATE_GEN];
00260 update_gen_column["column"] = "friend_last_update_generation";
00261 update_gen_column["value"] = have_name ? relationInfo->getChangeSerialNum() : -1;
00262
00263 mFriendsList->addElement(element, ADD_BOTTOM);
00264 return have_name;
00265 }
00266
00267
00268 BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationship* info)
00269 {
00270 if (!info) return FALSE;
00271 LLScrollListItem* itemp = mFriendsList->getItem(agent_id);
00272 if (!itemp) return FALSE;
00273
00274 std::string fullname;
00275 BOOL have_name = gCacheName->getFullName(agent_id, fullname);
00276
00277 itemp->getColumn(LIST_ONLINE_STATUS)->setValue(info->isOnline() ? "icon_avatar_online.tga" : LLString::null);
00278 itemp->getColumn(LIST_FRIEND_NAME)->setValue(fullname);
00279
00280 ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle(info->isOnline() ? LLFontGL::BOLD : LLFontGL::NORMAL);
00281 itemp->getColumn(LIST_VISIBLE_ONLINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
00282 itemp->getColumn(LIST_VISIBLE_MAP)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION));
00283 itemp->getColumn(LIST_EDIT_MINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS));
00284 S32 change_generation = have_name ? info->getChangeSerialNum() : -1;
00285 itemp->getColumn(LIST_FRIEND_UPDATE_GEN)->setValue(change_generation);
00286
00287
00288 itemp->setEnabled(TRUE);
00289
00290
00291 mFriendsList->sortItems();
00292
00293 return have_name;
00294 }
00295
00296 void LLPanelFriends::refreshRightsChangeList()
00297 {
00298 LLDynamicArray<LLUUID> friends = getSelectedIDs();
00299 S32 num_selected = friends.size();
00300
00301 bool can_offer_teleport = num_selected >= 1;
00302 bool selected_friends_online = true;
00303
00304 LLTextBox* processing_label = getChild<LLTextBox>("process_rights_label");
00305
00306 if(!mAllowRightsChange)
00307 {
00308 if(processing_label)
00309 {
00310 processing_label->setVisible(true);
00311
00312 friends.clear();
00313 num_selected = 0;
00314 }
00315 }
00316 else if(processing_label)
00317 {
00318 processing_label->setVisible(false);
00319 }
00320
00321 const LLRelationship* friend_status = NULL;
00322 for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
00323 {
00324 friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
00325 if (friend_status)
00326 {
00327 if(!friend_status->isOnline())
00328 {
00329 can_offer_teleport = false;
00330 selected_friends_online = false;
00331 }
00332 }
00333 else
00334 {
00335 can_offer_teleport = false;
00336 }
00337 }
00338
00339 if (num_selected == 0)
00340 {
00341 childSetEnabled("im_btn", FALSE);
00342 childSetEnabled("offer_teleport_btn", FALSE);
00343 }
00344 else
00345 {
00346
00347
00348
00349 childSetEnabled("im_btn", selected_friends_online || num_selected == 1);
00350 childSetEnabled("offer_teleport_btn", can_offer_teleport);
00351 }
00352 }
00353
00354 struct SortFriendsByID
00355 {
00356 bool operator() (const LLScrollListItem* const a, const LLScrollListItem* const b) const
00357 {
00358 return a->getValue().asUUID() < b->getValue().asUUID();
00359 }
00360 };
00361
00362 void LLPanelFriends::refreshNames()
00363 {
00364 LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();
00365 S32 pos = mFriendsList->getScrollPos();
00366
00367
00368 LLAvatarTracker::buddy_map_t all_buddies;
00369 LLAvatarTracker::instance().copyBuddyList(all_buddies);
00370
00371
00372 std::vector<LLScrollListItem*> items = mFriendsList->getAllData();
00373 std::sort(items.begin(), items.end(), SortFriendsByID());
00374
00375 std::vector<LLScrollListItem*>::iterator item_it = items.begin();
00376 std::vector<LLScrollListItem*>::iterator item_end = items.end();
00377
00378 BOOL have_names = TRUE;
00379 LLAvatarTracker::buddy_map_t::iterator buddy_it;
00380 for (buddy_it = all_buddies.begin() ; buddy_it != all_buddies.end(); ++buddy_it)
00381 {
00382
00383 while(item_it != item_end && buddy_it->first > (*item_it)->getValue().asUUID())
00384 {
00385 mFriendsList->deleteItems((*item_it)->getValue());
00386 ++item_it;
00387 }
00388
00389
00390 if (item_it != item_end && buddy_it->first == (*item_it)->getValue().asUUID())
00391 {
00392 const LLRelationship* info = buddy_it->second;
00393 if (!info)
00394 {
00395 ++item_it;
00396 continue;
00397 }
00398
00399 S32 last_change_generation = (*item_it)->getColumn(LIST_FRIEND_UPDATE_GEN)->getValue().asInteger();
00400 if (last_change_generation < info->getChangeSerialNum())
00401 {
00402
00403 have_names &= updateFriendItem(buddy_it->first, info);
00404 }
00405 ++item_it;
00406 }
00407
00408 else
00409 {
00410 have_names &= addFriend(buddy_it->first);
00411 }
00412 }
00413 if (!have_names)
00414 {
00415 mEventTimer.start();
00416 }
00417
00418 mFriendsList->sortItems();
00419
00420
00421 mFriendsList->selectMultiple(selected_ids);
00422 mFriendsList->setScrollPos(pos);
00423 }
00424
00425
00426 void LLPanelFriends::refreshUI()
00427 {
00428 BOOL single_selected = FALSE;
00429 BOOL multiple_selected = FALSE;
00430 int num_selected = mFriendsList->getAllSelected().size();
00431 if(num_selected > 0)
00432 {
00433 single_selected = TRUE;
00434 if(num_selected > 1)
00435 {
00436 childSetText("friend_name_label", getString("Multiple"));
00437 multiple_selected = TRUE;
00438 }
00439 else
00440 {
00441 childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getValue().asString() + "...");
00442 }
00443 }
00444 else
00445 {
00446 childSetText("friend_name_label", LLString::null);
00447 }
00448
00449
00450
00451 childSetEnabled("profile_btn", single_selected && !multiple_selected);
00452 childSetEnabled("pay_btn", single_selected && !multiple_selected);
00453
00454
00455
00456 childSetEnabled("remove_btn", single_selected);
00457 childSetEnabled("im_btn", single_selected);
00458 childSetEnabled("friend_rights", single_selected);
00459
00460 refreshRightsChangeList();
00461 }
00462
00463 LLDynamicArray<LLUUID> LLPanelFriends::getSelectedIDs()
00464 {
00465 LLUUID selected_id;
00466 LLDynamicArray<LLUUID> friend_ids;
00467 std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
00468 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
00469 {
00470 friend_ids.push_back((*itr)->getUUID());
00471 }
00472 return friend_ids;
00473 }
00474
00475
00476 void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
00477 {
00478 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00479
00480 if(panelp)
00481 {
00482 panelp->refreshUI();
00483
00484 panelp->applyRightsToFriends();
00485 }
00486 }
00487
00488
00489 void LLPanelFriends::onMaximumSelect(void* user_data)
00490 {
00491 LLString::format_map_t args;
00492 args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
00493 LLNotifyBox::showXml("MaxListSelectMessage", args);
00494 };
00495
00496
00497 void LLPanelFriends::onClickProfile(void* user_data)
00498 {
00499 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00500
00501
00502 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00503 if(ids.size() > 0)
00504 {
00505 LLUUID agent_id = ids[0];
00506 BOOL online;
00507 online = LLAvatarTracker::instance().isBuddyOnline(agent_id);
00508 LLFloaterAvatarInfo::showFromFriend(agent_id, online);
00509 }
00510 }
00511
00512
00513 void LLPanelFriends::onClickIM(void* user_data)
00514 {
00515 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00516
00517
00518 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00519 if(ids.size() > 0)
00520 {
00521 if(ids.size() == 1)
00522 {
00523 LLUUID agent_id = ids[0];
00524 const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
00525 std::string fullname;
00526 if(info && gCacheName->getFullName(agent_id, fullname))
00527 {
00528 gIMMgr->setFloaterOpen(TRUE);
00529 gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id);
00530 }
00531 }
00532 else
00533 {
00534 gIMMgr->setFloaterOpen(TRUE);
00535 gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], ids);
00536 }
00537 make_ui_sound("UISndStartIM");
00538 }
00539 }
00540
00541
00542 void LLPanelFriends::requestFriendship(const LLUUID& target_id, const LLString& target_name)
00543 {
00544
00545 LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
00546 std::string message = calling_card_folder_id.asString();
00547 send_improved_im(target_id,
00548 target_name.c_str(),
00549 message.c_str(),
00550 IM_ONLINE,
00551 IM_FRIENDSHIP_OFFERED);
00552 }
00553
00554 struct LLAddFriendData
00555 {
00556 LLUUID mID;
00557 std::string mName;
00558 };
00559
00560
00561 void LLPanelFriends::callbackAddFriend(S32 option, void* data)
00562 {
00563 LLAddFriendData* add = (LLAddFriendData*)data;
00564 if (option == 0)
00565 {
00566 requestFriendship(add->mID, add->mName);
00567 }
00568 delete add;
00569 }
00570
00571
00572 void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
00573 const std::vector<LLUUID>& ids,
00574 void* )
00575 {
00576 if (names.empty()) return;
00577 if (ids.empty()) return;
00578 requestFriendshipDialog(ids[0], names[0]);
00579 }
00580
00581
00582 void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
00583 const std::string& name)
00584 {
00585 if(id == gAgentID)
00586 {
00587 LLNotifyBox::showXml("AddSelfFriend");
00588 return;
00589 }
00590
00591 LLAddFriendData* data = new LLAddFriendData();
00592 data->mID = id;
00593 data->mName = name;
00594
00595
00596 LLString::format_map_t args;
00597 args["[NAME]"] = name;
00598 gViewerWindow->alertXml("AddFriend", args, callbackAddFriend, data);
00599 }
00600
00601
00602 void LLPanelFriends::onClickAddFriend(void* user_data)
00603 {
00604 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00605 LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
00606 LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE);
00607 if (root_floater)
00608 {
00609 root_floater->addDependentFloater(picker);
00610 }
00611 }
00612
00613
00614 void LLPanelFriends::onClickRemove(void* user_data)
00615 {
00616 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00617
00618
00619 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00620 LLStringBase<char>::format_map_t args;
00621 if(ids.size() > 0)
00622 {
00623 LLString msgType = "RemoveFromFriends";
00624 if(ids.size() == 1)
00625 {
00626 LLUUID agent_id = ids[0];
00627 std::string first, last;
00628 if(gCacheName->getName(agent_id, first, last))
00629 {
00630 args["[FIRST_NAME]"] = first;
00631 args["[LAST_NAME]"] = last;
00632 }
00633 }
00634 else
00635 {
00636 msgType = "RemoveMultipleFromFriends";
00637 }
00638 gViewerWindow->alertXml(msgType,
00639 args,
00640 &handleRemove,
00641 (void*)new LLDynamicArray<LLUUID>(ids));
00642 }
00643 }
00644
00645
00646 void LLPanelFriends::onClickOfferTeleport(void* user_data)
00647 {
00648 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00649
00650 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00651 if(ids.size() > 0)
00652 {
00653 handle_lure(ids);
00654 }
00655 }
00656
00657
00658 void LLPanelFriends::onClickPay(void* user_data)
00659 {
00660 LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00661
00662 LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00663 if(ids.size() == 1)
00664 {
00665 handle_pay_by_id(ids[0]);
00666 }
00667 }
00668
00669 void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command)
00670 {
00671 if (ids.empty()) return;
00672
00673 LLStringBase<char>::format_map_t args;
00674 if(ids.size() > 0)
00675 {
00676
00677 rights_map_t* rights = new rights_map_t(ids);
00678
00679 std::pair<LLPanelFriends*, rights_map_t*>* user_data = new std::pair<LLPanelFriends*, rights_map_t*>(this, rights);
00680
00681
00682 if(ids.size() == 1)
00683 {
00684 LLUUID agent_id = ids.begin()->first;
00685 std::string first, last;
00686 if(gCacheName->getName(agent_id, first, last))
00687 {
00688 args["[FIRST_NAME]"] = first;
00689 args["[LAST_NAME]"] = last;
00690 }
00691 if (command == GRANT)
00692 {
00693 gViewerWindow->alertXml("GrantModifyRights", args, modifyRightsConfirmation, user_data);
00694 }
00695 else
00696 {
00697 gViewerWindow->alertXml("RevokeModifyRights", args, modifyRightsConfirmation, user_data);
00698 }
00699 }
00700 else
00701 {
00702 if (command == GRANT)
00703 {
00704 gViewerWindow->alertXml("GrantModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
00705 }
00706 else
00707 {
00708 gViewerWindow->alertXml("RevokeModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
00709 }
00710 }
00711 }
00712 }
00713
00714
00715 void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data)
00716 {
00717 std::pair<LLPanelFriends*, rights_map_t*>* data = (std::pair<LLPanelFriends*, rights_map_t*>*)user_data;
00718 LLPanelFriends* panelp = data->first;
00719
00720 if(panelp)
00721 {
00722 if(0 == option)
00723 {
00724 panelp->sendRightsGrant(*(data->second));
00725 }
00726 else
00727 {
00728
00729 rights_map_t* rights = data->second;
00730 rights_map_t::iterator rights_it;
00731 for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
00732 {
00733 const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
00734 panelp->updateFriendItem(rights_it->first, info);
00735 }
00736 }
00737 panelp->refreshUI();
00738 }
00739
00740 delete data->second;
00741 delete data;
00742 }
00743
00744 void LLPanelFriends::applyRightsToFriends()
00745 {
00746 BOOL rights_changed = FALSE;
00747
00748
00749 rights_map_t rights_updates;
00750
00751 BOOL need_confirmation = FALSE;
00752 EGrantRevoke confirmation_type = GRANT;
00753
00754
00755 std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
00756 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
00757 {
00758 LLUUID id = (*itr)->getValue();
00759 const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(id);
00760 if (buddy_relationship == NULL) continue;
00761
00762 bool show_online_staus = (*itr)->getColumn(LIST_VISIBLE_ONLINE)->getValue().asBoolean();
00763 bool show_map_location = (*itr)->getColumn(LIST_VISIBLE_MAP)->getValue().asBoolean();
00764 bool allow_modify_objects = (*itr)->getColumn(LIST_EDIT_MINE)->getValue().asBoolean();
00765
00766 S32 rights = buddy_relationship->getRightsGrantedTo();
00767 if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) != show_online_staus)
00768 {
00769 rights_changed = TRUE;
00770 if(show_online_staus)
00771 {
00772 rights |= LLRelationship::GRANT_ONLINE_STATUS;
00773 }
00774 else
00775 {
00776
00777 rights &= ~LLRelationship::GRANT_ONLINE_STATUS;
00778 rights &= ~LLRelationship::GRANT_MAP_LOCATION;
00779
00780 (*itr)->getColumn(LIST_VISIBLE_MAP)->setValue(FALSE);
00781 }
00782 }
00783 if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) != show_map_location)
00784 {
00785 rights_changed = TRUE;
00786 if(show_map_location)
00787 {
00788
00789 rights |= LLRelationship::GRANT_MAP_LOCATION;
00790 rights |= LLRelationship::GRANT_ONLINE_STATUS;
00791 (*itr)->getColumn(LIST_VISIBLE_ONLINE)->setValue(TRUE);
00792 }
00793 else
00794 {
00795 rights &= ~LLRelationship::GRANT_MAP_LOCATION;
00796 }
00797 }
00798
00799
00800 if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
00801 {
00802 rights_changed = TRUE;
00803 need_confirmation = TRUE;
00804
00805 if(allow_modify_objects)
00806 {
00807 rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
00808 confirmation_type = GRANT;
00809 }
00810 else
00811 {
00812 rights &= ~LLRelationship::GRANT_MODIFY_OBJECTS;
00813 confirmation_type = REVOKE;
00814 }
00815 }
00816
00817 if (rights_changed)
00818 {
00819 rights_updates.insert(std::make_pair(id, rights));
00820
00821
00822 (*itr)->setEnabled(FALSE);
00823 }
00824 }
00825
00826
00827 if (need_confirmation)
00828 {
00829 confirmModifyRights(rights_updates, confirmation_type);
00830 }
00831 else
00832 {
00833 sendRightsGrant(rights_updates);
00834 }
00835 }
00836
00837 void LLPanelFriends::sendRightsGrant(rights_map_t& ids)
00838 {
00839 if (ids.empty()) return;
00840
00841 LLMessageSystem* msg = gMessageSystem;
00842
00843
00844 msg->newMessageFast(_PREHASH_GrantUserRights);
00845 msg->nextBlockFast(_PREHASH_AgentData);
00846 msg->addUUID(_PREHASH_AgentID, gAgent.getID());
00847 msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
00848
00849 rights_map_t::iterator id_it;
00850 rights_map_t::iterator end_it = ids.end();
00851 for(id_it = ids.begin(); id_it != end_it; ++id_it)
00852 {
00853 msg->nextBlockFast(_PREHASH_Rights);
00854 msg->addUUID(_PREHASH_AgentRelated, id_it->first);
00855 msg->addS32(_PREHASH_RelatedRights, id_it->second);
00856 }
00857
00858 mNumRightsChanged = ids.size();
00859 gAgent.sendReliableMessage();
00860 }
00861
00862
00863
00864
00865 void LLPanelFriends::handleRemove(S32 option, void* user_data)
00866 {
00867 LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
00868 for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
00869 {
00870 LLUUID id = (*itr);
00871 const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
00872 if(ip)
00873 {
00874 switch(option)
00875 {
00876 case 0:
00877 if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
00878 {
00879 LLAvatarTracker::instance().empower(id, FALSE);
00880 LLAvatarTracker::instance().notifyObservers();
00881 }
00882 LLAvatarTracker::instance().terminateBuddy(id);
00883 LLAvatarTracker::instance().notifyObservers();
00884 gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
00885 gInventory.notifyObservers();
00886 break;
00887
00888 case 1:
00889 default:
00890 llinfos << "No removal performed." << llendl;
00891 break;
00892 }
00893 }
00894
00895 }
00896 delete ids;
00897 }