llfloaterfriends.cpp

Go to the documentation of this file.
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 "llvieweruictrlfactory.h"
00055 #include "llmenucommands.h"
00056 #include "llviewercontrol.h"
00057 #include "llviewermessage.h"
00058 #include "lltimer.h"
00059 #include "lltextbox.h"
00060 
00061 //Maximum number of people you can select to do an operation on at once.
00062 #define MAX_FRIEND_SELECT 20
00063 #define RIGHTS_CHANGE_TIMEOUT 5.0
00064 
00065 // simple class to observe the calling cards.
00066 class LLLocalFriendsObserver : public LLFriendObserver
00067 {
00068 public:
00069         LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater) {}
00070         virtual ~LLLocalFriendsObserver() { mFloater = NULL; }
00071         virtual void changed(U32 mask)
00072         {
00073                 mFloater->updateFriends(mask);
00074         }
00075 protected:
00076         LLPanelFriends* mFloater;
00077 };
00078 
00079 LLPanelFriends::LLPanelFriends() :
00080         LLPanel(),
00081         LLEventTimer(1000000),
00082         mObserver(NULL),
00083         mMenuState(0),
00084         mShowMaxSelectWarning(TRUE),
00085         mAllowRightsChange(TRUE),
00086         mNumRightsChanged(0)
00087 {
00088         mEventTimer.stop();
00089         mObserver = new LLLocalFriendsObserver(this);
00090         LLAvatarTracker::instance().addObserver(mObserver);
00091 }
00092 
00093 LLPanelFriends::~LLPanelFriends()
00094 {
00095         LLAvatarTracker::instance().removeObserver(mObserver);
00096         delete mObserver;
00097 }
00098 
00099 BOOL LLPanelFriends::tick()
00100 {
00101         mEventTimer.stop();
00102         mPeriod = 1000000;
00103         mAllowRightsChange = TRUE;
00104         updateFriends(LLFriendObserver::ADD);
00105         return FALSE;
00106 }
00107 
00108 void LLPanelFriends::updateFriends(U32 changed_mask)
00109 {
00110         LLUUID selected_id;
00111         LLCtrlListInterface *friends_list = childGetListInterface("friend_list");
00112         if (!friends_list) return;
00113         LLCtrlScrollInterface *friends_scroll = childGetScrollInterface("friend_list");
00114         if (!friends_scroll) return;
00115         
00116         // We kill the selection warning, otherwise we'll spam with warning popups
00117         // if the maximum amount of friends are selected
00118         mShowMaxSelectWarning = false;
00119 
00120         LLDynamicArray<LLUUID> selected_friends = getSelectedIDs();
00121         if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
00122         {
00123                 refreshNames();
00124         }
00125         else if(changed_mask & LLFriendObserver::POWERS)
00126         {
00127                 --mNumRightsChanged;
00128                 if(mNumRightsChanged > 0)
00129                 {
00130                         mPeriod = RIGHTS_CHANGE_TIMEOUT;        
00131                         mEventTimer.start();
00132                         mEventTimer.reset();
00133                         mAllowRightsChange = FALSE;
00134                 }
00135                 else
00136                 {
00137                         tick();
00138                 }
00139         }
00140         if(selected_friends.size() > 0)
00141         {
00142                 // only non-null if friends was already found. This may fail,
00143                 // but we don't really care here, because refreshUI() will
00144                 // clean up the interface.
00145                 friends_list->setCurrentByID(selected_id);
00146                 for(LLDynamicArray<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr)
00147                 {
00148                         friends_list->setSelectedByValue(*itr, true);
00149                 }
00150         }
00151 
00152         refreshUI();
00153         mShowMaxSelectWarning = true;
00154 }
00155 
00156 // virtual
00157 BOOL LLPanelFriends::postBuild()
00158 {
00159         mFriendsList = LLUICtrlFactory::getScrollListByName(this, "friend_list");
00160         mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
00161         mFriendsList->setMaxiumumSelectCallback(onMaximumSelect);
00162         mFriendsList->setCommitOnSelectionChange(TRUE);
00163         childSetCommitCallback("friend_list", onSelectName, this);
00164         childSetDoubleClickCallback("friend_list", onClickIM);
00165 
00166         refreshNames();
00167 
00168         childSetCommitCallback("online_status_cb", onClickOnlineStatus, this);
00169         childSetCommitCallback("map_status_cb", onClickMapStatus, this);
00170         childSetCommitCallback("modify_status_cb", onClickModifyStatus, this);
00171         childSetAction("im_btn", onClickIM, this);
00172         childSetAction("profile_btn", onClickProfile, this);
00173         childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
00174         childSetAction("pay_btn", onClickPay, this);
00175         childSetAction("add_btn", onClickAddFriend, this);
00176         childSetAction("remove_btn", onClickRemove, this);
00177 
00178         setDefaultBtn("im_btn");
00179 
00180         updateFriends(LLFriendObserver::ADD);
00181         refreshUI();
00182 
00183         return TRUE;
00184 }
00185 
00186 
00187 void LLPanelFriends::addFriend(const std::string& name, const LLUUID& agent_id)
00188 {
00189         LLAvatarTracker& at = LLAvatarTracker::instance();
00190         const LLRelationship* relationInfo = at.getBuddyInfo(agent_id);
00191         if(!relationInfo) return;
00192         BOOL online = relationInfo->isOnline();
00193 
00194         LLSD element;
00195         element["id"] = agent_id;
00196         element["columns"][LIST_FRIEND_NAME]["column"] = "friend_name";
00197         element["columns"][LIST_FRIEND_NAME]["value"] = name.c_str();
00198         element["columns"][LIST_FRIEND_NAME]["font"] = "SANSSERIF";
00199         element["columns"][LIST_FRIEND_NAME]["font-style"] = "NORMAL";  
00200         element["columns"][LIST_ONLINE_STATUS]["column"] = "icon_online_status";
00201         element["columns"][LIST_ONLINE_STATUS]["type"] = "text";
00202         if (online)
00203         {
00204                 element["columns"][LIST_FRIEND_NAME]["font-style"] = "BOLD";    
00205                 element["columns"][LIST_ONLINE_STATUS]["type"] = "icon";
00206                 element["columns"][LIST_ONLINE_STATUS]["value"] = gViewerArt.getString("icon_avatar_online.tga");               
00207         }
00208 
00209 
00210         element["columns"][LIST_VISIBLE_ONLINE]["column"] = "icon_visible_online";
00211         element["columns"][LIST_VISIBLE_ONLINE]["type"] = "text";
00212         if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
00213         {
00214                 element["columns"][LIST_VISIBLE_ONLINE]["type"] = "icon";
00215                 element["columns"][LIST_VISIBLE_ONLINE]["value"] = gViewerArt.getString("ff_visible_online.tga");
00216         }
00217         element["columns"][LIST_VISIBLE_MAP]["column"] = "icon_visible_map";
00218         element["columns"][LIST_VISIBLE_MAP]["type"] = "text";
00219         if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))
00220         {
00221                 element["columns"][LIST_VISIBLE_MAP]["type"] = "icon";
00222                 element["columns"][LIST_VISIBLE_MAP]["value"] = gViewerArt.getString("ff_visible_map.tga");
00223         }
00224         element["columns"][LIST_EDIT_MINE]["column"] = "icon_edit_mine";
00225         element["columns"][LIST_EDIT_MINE]["type"] = "text";
00226         if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
00227         {
00228                 element["columns"][LIST_EDIT_MINE]["type"] = "icon";
00229                 element["columns"][LIST_EDIT_MINE]["value"] = gViewerArt.getString("ff_edit_mine.tga");
00230         }
00231         element["columns"][LIST_EDIT_THEIRS]["column"] = "icon_edit_theirs";
00232         element["columns"][LIST_EDIT_THEIRS]["type"] = "text";
00233         if(relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS))
00234         {
00235                 element["columns"][LIST_EDIT_THEIRS]["type"] = "icon";
00236                 element["columns"][LIST_EDIT_THEIRS]["value"] = gViewerArt.getString("ff_edit_theirs.tga");
00237         }
00238         mFriendsList->addElement(element, ADD_BOTTOM);
00239 }
00240 
00241 void LLPanelFriends::refreshRightsChangeList()
00242 {
00243         LLDynamicArray<LLUUID> friends = getSelectedIDs();
00244         S32 num_selected = friends.size();
00245 
00246         LLSD row;
00247         bool can_offer_teleport = num_selected >= 1;
00248 
00249         // aggregate permissions over all selected friends
00250         bool friends_see_online = true;
00251         bool friends_see_on_map = true;
00252         bool friends_modify_objects = true;
00253 
00254         // do at least some of the friends selected have these rights?
00255         bool some_friends_see_online = false;
00256         bool some_friends_see_on_map = false;
00257         bool some_friends_modify_objects = false;
00258 
00259         bool selected_friends_online = true;
00260 
00261         LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label");
00262 
00263         if(!mAllowRightsChange)
00264         {
00265                 if(processing_label)
00266                 {
00267                         processing_label->setVisible(true);
00268                         // ignore selection for now
00269                         friends.clear();
00270                         num_selected = 0;
00271                 }
00272         }
00273         else
00274         {
00275                 if(processing_label)
00276                 {
00277                         processing_label->setVisible(false);
00278                 }
00279         }
00280 
00281         const LLRelationship* friend_status = NULL;
00282         for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
00283         {
00284                 friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
00285                 if (friend_status)
00286                 {
00287                         bool can_see_online = friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS);
00288                         bool can_see_on_map = friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION);
00289                         bool can_modify_objects = friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
00290 
00291                         // aggregate rights of this friend into total selection
00292                         friends_see_online &= can_see_online;
00293                         friends_see_on_map &= can_see_on_map;
00294                         friends_modify_objects &= can_modify_objects;
00295 
00296                         // can at least one of your selected friends do any of these?
00297                         some_friends_see_online |= can_see_online;
00298                         some_friends_see_on_map |= can_see_on_map;
00299                         some_friends_modify_objects |= can_modify_objects;
00300 
00301                         if(!friend_status->isOnline())
00302                         {
00303                                 can_offer_teleport = false;
00304                                 selected_friends_online = false;
00305                         }
00306                 }
00307                 else // missing buddy info, don't allow any operations
00308                 {
00309                         can_offer_teleport = false;
00310 
00311                         friends_see_online = false;
00312                         friends_see_on_map = false;
00313                         friends_modify_objects = false;
00314 
00315                         some_friends_see_online = false;
00316                         some_friends_see_on_map = false;
00317                         some_friends_modify_objects = false;
00318                 }
00319         }
00320         
00321 
00322         // seeing a friend on the map requires seeing online status as a prerequisite
00323         friends_see_on_map &= friends_see_online;
00324 
00325         mMenuState = 0;
00326 
00327         // make checkboxes visible after we have finished processing rights
00328         childSetVisible("online_status_cb", mAllowRightsChange);
00329         childSetVisible("map_status_cb", mAllowRightsChange);
00330         childSetVisible("modify_status_cb", mAllowRightsChange);
00331 
00332         if (num_selected == 0)  // nothing selected
00333         {
00334                 childSetEnabled("im_btn", FALSE);
00335                 childSetEnabled("offer_teleport_btn", FALSE);
00336 
00337                 childSetEnabled("online_status_cb", FALSE);
00338                 childSetValue("online_status_cb", FALSE);
00339                 childSetTentative("online_status_cb", FALSE);
00340 
00341                 childSetEnabled("map_status_cb", FALSE);
00342                 childSetValue("map_status_cb", FALSE);
00343                 childSetTentative("map_status_cb", FALSE);
00344 
00345                 childSetEnabled("modify_status_cb", FALSE);
00346                 childSetValue("modify_status_cb", FALSE);
00347                 childSetTentative("modify_status_cb", FALSE);
00348         }
00349         else // we have at least one friend selected...
00350         {
00351                 // only allow IMs to groups when everyone in the group is online
00352                 // to be consistent with context menus in inventory and because otherwise
00353                 // offline friends would be silently dropped from the session
00354                 childSetEnabled("im_btn", selected_friends_online || num_selected == 1);
00355 
00356                 childSetEnabled("offer_teleport_btn", can_offer_teleport);
00357 
00358                 childSetEnabled("online_status_cb", TRUE);
00359                 childSetValue("online_status_cb", some_friends_see_online);
00360                 childSetTentative("online_status_cb", some_friends_see_online != friends_see_online);
00361                 if (friends_see_online)
00362                 {
00363                         mMenuState |= LLRelationship::GRANT_ONLINE_STATUS;
00364                 }
00365 
00366                 childSetEnabled("map_status_cb", TRUE);
00367                 childSetValue("map_status_cb", some_friends_see_on_map);
00368                 childSetTentative("map_status_cb", some_friends_see_on_map != friends_see_on_map);
00369                 if(friends_see_on_map) 
00370                 {
00371                         mMenuState |= LLRelationship::GRANT_MAP_LOCATION;
00372                 }
00373 
00374                 // for now, don't allow modify rights change for multiple select
00375                 childSetEnabled("modify_status_cb", num_selected == 1);
00376                 childSetValue("modify_status_cb", some_friends_modify_objects);
00377                 childSetTentative("modify_status_cb", some_friends_modify_objects != friends_modify_objects);
00378                 if(friends_modify_objects) 
00379                 {
00380                         mMenuState |= LLRelationship::GRANT_MODIFY_OBJECTS;
00381                 }
00382         }
00383 }
00384 
00385 void LLPanelFriends::refreshNames()
00386 {
00387         LLDynamicArray<LLUUID> selected_ids = getSelectedIDs(); 
00388         S32 pos = mFriendsList->getScrollPos(); 
00389         mFriendsList->operateOnAll(LLCtrlListInterface::OP_DELETE);
00390         
00391         LLCollectAllBuddies collect;
00392         LLAvatarTracker::instance().applyFunctor(collect);
00393         LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
00394         LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
00395         
00396         for ( ; it != end; ++it)
00397         {
00398                 const std::string& name = it->first;
00399                 const LLUUID& agent_id = it->second;
00400                 addFriend(name, agent_id);
00401         }
00402         it = collect.mOffline.begin();
00403         end = collect.mOffline.end();
00404         for ( ; it != end; ++it)
00405         {
00406                 const std::string& name = it->first;
00407                 const LLUUID& agent_id = it->second;
00408                 addFriend(name, agent_id);
00409         }
00410         mFriendsList->selectMultiple(selected_ids);
00411         mFriendsList->setScrollPos(pos);
00412 }
00413 
00414 
00415 void LLPanelFriends::refreshUI()
00416 {       
00417         BOOL single_selected = FALSE;
00418         BOOL multiple_selected = FALSE;
00419         int num_selected = mFriendsList->getAllSelected().size();
00420         if(num_selected > 0)
00421         {
00422                 single_selected = TRUE;
00423                 if(num_selected > 1)
00424                 {
00425                         childSetText("friend_name_label", childGetText("Multiple"));
00426                         multiple_selected = TRUE;               
00427                 }
00428                 else
00429                 {                       
00430                         childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getText() + "...");
00431                 }
00432         }
00433         else
00434         {
00435                 childSetText("friend_name_label", LLString::null);
00436         }
00437 
00438 
00439         //Options that can only be performed with one friend selected
00440         childSetEnabled("profile_btn", single_selected && !multiple_selected);
00441         childSetEnabled("pay_btn", single_selected && !multiple_selected);
00442 
00443         //Options that can be performed with up to MAX_FRIEND_SELECT friends selected
00444         //(single_selected will always be true in this situations)
00445         childSetEnabled("remove_btn", single_selected);
00446         childSetEnabled("im_btn", single_selected);
00447         childSetEnabled("friend_rights", single_selected);
00448 
00449         refreshRightsChangeList();
00450 }
00451 
00452 LLDynamicArray<LLUUID> LLPanelFriends::getSelectedIDs()
00453 {
00454         LLUUID selected_id;
00455         LLDynamicArray<LLUUID> friend_ids;
00456         std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
00457         for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
00458         {
00459                 friend_ids.push_back((*itr)->getUUID());
00460         }
00461         return friend_ids;
00462 }
00463 
00464 // static
00465 void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
00466 {
00467         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00468 
00469         if(panelp)
00470         {
00471                 panelp->refreshUI();
00472         }
00473 }
00474 
00475 //static
00476 void LLPanelFriends::onMaximumSelect(void* user_data)
00477 {
00478         LLString::format_map_t args;
00479         args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
00480         LLNotifyBox::showXml("MaxListSelectMessage", args);
00481 };
00482 
00483 // static
00484 void LLPanelFriends::onClickProfile(void* user_data)
00485 {
00486         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00487 
00488         //llinfos << "LLPanelFriends::onClickProfile()" << llendl;
00489         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00490         if(ids.size() > 0)
00491         {
00492                 LLUUID agent_id = ids[0];
00493                 BOOL online;
00494                 online = LLAvatarTracker::instance().isBuddyOnline(agent_id);
00495                 LLFloaterAvatarInfo::showFromFriend(agent_id, online);
00496         }
00497 }
00498 
00499 // static
00500 void LLPanelFriends::onClickIM(void* user_data)
00501 {
00502         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00503 
00504         //llinfos << "LLPanelFriends::onClickIM()" << llendl;
00505         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00506         if(ids.size() > 0)
00507         {
00508                 if(ids.size() == 1)
00509                 {
00510                         LLUUID agent_id = ids[0];
00511                         const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
00512                         char first[DB_FIRST_NAME_BUF_SIZE];     /* Flawfinder: ignore */
00513                         char last[DB_LAST_NAME_BUF_SIZE];       /* Flawfinder: ignore */
00514                         if(info && gCacheName->getName(agent_id, first, last))
00515                         {
00516                                 char buffer[MAX_STRING];        /* Flawfinder: ignore */
00517                                 snprintf(buffer, MAX_STRING, "%s %s", first, last);     /* Flawfinder: ignore */
00518                                 gIMMgr->setFloaterOpen(TRUE);
00519                                 gIMMgr->addSession(
00520                                         buffer,
00521                                         IM_NOTHING_SPECIAL,
00522                                         agent_id);
00523                         }               
00524                 }
00525                 else
00526                 {
00527                         gIMMgr->setFloaterOpen(TRUE);
00528                         gIMMgr->addSession("Friends Conference",
00529                                                                 IM_SESSION_CONFERENCE_START,
00530                                                                 ids[0],
00531                                                                 ids);
00532                 }
00533                 make_ui_sound("UISndStartIM");
00534         }
00535 }
00536 
00537 // static
00538 void LLPanelFriends::requestFriendship(const LLUUID& target_id, const LLString& target_name)
00539 {
00540         // HACK: folder id stored as "message"
00541         LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
00542         std::string message = calling_card_folder_id.asString();
00543         send_improved_im(target_id,
00544                                          target_name.c_str(),
00545                                          message.c_str(),
00546                                          IM_ONLINE,
00547                                          IM_FRIENDSHIP_OFFERED);
00548 }
00549 
00550 struct LLAddFriendData
00551 {
00552         LLUUID mID;
00553         std::string mName;
00554 };
00555 
00556 // static
00557 void LLPanelFriends::callbackAddFriend(S32 option, void* data)
00558 {
00559         LLAddFriendData* add = (LLAddFriendData*)data;
00560         if (option == 0)
00561         {
00562                 requestFriendship(add->mID, add->mName);
00563         }
00564         delete add;
00565 }
00566 
00567 // static
00568 void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
00569                                                                         const std::vector<LLUUID>& ids,
00570                                                                         void* )
00571 {
00572         if (names.empty()) return;
00573         if (ids.empty()) return;
00574         requestFriendshipDialog(ids[0], names[0]);
00575 }
00576 
00577 // static
00578 void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
00579                                                                                            const std::string& name)
00580 {
00581         if(id == gAgentID)
00582         {
00583                 LLNotifyBox::showXml("AddSelfFriend");
00584                 return;
00585         }
00586 
00587         LLAddFriendData* data = new LLAddFriendData();
00588         data->mID = id;
00589         data->mName = name;
00590         
00591         // TODO: accept a line of text with this dialog
00592         LLString::format_map_t args;
00593         args["[NAME]"] = name;
00594         gViewerWindow->alertXml("AddFriend", args, callbackAddFriend, data);
00595 }
00596 
00597 // static
00598 void LLPanelFriends::onClickAddFriend(void* user_data)
00599 {
00600         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00601         LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
00602         LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE);
00603         if (root_floater)
00604         {
00605                 root_floater->addDependentFloater(picker);
00606         }
00607 }
00608 
00609 // static
00610 void LLPanelFriends::onClickRemove(void* user_data)
00611 {
00612         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00613 
00614         //llinfos << "LLPanelFriends::onClickRemove()" << llendl;
00615         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00616         LLStringBase<char>::format_map_t args;
00617         if(ids.size() > 0)
00618         {
00619                 LLString msgType = "RemoveFromFriends";
00620                 if(ids.size() == 1)
00621                 {
00622                         LLUUID agent_id = ids[0];
00623                         char first[DB_FIRST_NAME_BUF_SIZE];             /*Flawfinder: ignore*/
00624                         char last[DB_LAST_NAME_BUF_SIZE];               /*Flawfinder: ignore*/
00625                         if(gCacheName->getName(agent_id, first, last))
00626                         {
00627                                 args["[FIRST_NAME]"] = first;
00628                                 args["[LAST_NAME]"] = last;     
00629                         }
00630                 }
00631                 else
00632                 {
00633                         msgType = "RemoveMultipleFromFriends";
00634                 }
00635                 gViewerWindow->alertXml(msgType,
00636                         args,
00637                         &handleRemove,
00638                         (void*)new LLDynamicArray<LLUUID>(ids));
00639         }
00640 }
00641 
00642 // static
00643 void LLPanelFriends::onClickOfferTeleport(void* user_data)
00644 {
00645         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00646 
00647         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00648         if(ids.size() > 0)
00649         {       
00650                 handle_lure(ids);
00651         }
00652 }
00653 
00654 // static
00655 void LLPanelFriends::onClickPay(void* user_data)
00656 {
00657         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00658 
00659         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00660         if(ids.size() == 1)
00661         {       
00662                 handle_pay_by_id(ids[0]);
00663         }
00664 }
00665 
00666 void LLPanelFriends::onClickOnlineStatus(LLUICtrl* ctrl, void* user_data)
00667 {
00668         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00669 
00670         bool checked = ctrl->getValue();
00671         panelp->updateMenuState(LLRelationship::GRANT_ONLINE_STATUS, checked);
00672         panelp->applyRightsToFriends(LLRelationship::GRANT_ONLINE_STATUS, checked);
00673 }
00674 
00675 void LLPanelFriends::onClickMapStatus(LLUICtrl* ctrl, void* user_data)
00676 {
00677         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00678         bool checked = ctrl->getValue();
00679         panelp->updateMenuState(LLRelationship::GRANT_MAP_LOCATION, checked);
00680         panelp->applyRightsToFriends(LLRelationship::GRANT_MAP_LOCATION, checked);
00681 }
00682 
00683 void LLPanelFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
00684 {
00685         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00686 
00687         bool checked = ctrl->getValue();
00688         LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
00689         LLStringBase<char>::format_map_t args;
00690         if(ids.size() > 0)
00691         {
00692                 if(ids.size() == 1)
00693                 {
00694                         LLUUID agent_id = ids[0];
00695                         char first[DB_FIRST_NAME_BUF_SIZE];             /*Flawfinder: ignore*/
00696                         char last[DB_LAST_NAME_BUF_SIZE];               /*Flawfinder: ignore*/
00697                         if(gCacheName->getName(agent_id, first, last))
00698                         {
00699                                 args["[FIRST_NAME]"] = first;
00700                                 args["[LAST_NAME]"] = last;     
00701                         }
00702                         if(checked) gViewerWindow->alertXml("GrantModifyRights", args, handleModifyRights, user_data);
00703                         else gViewerWindow->alertXml("RevokeModifyRights", args, handleModifyRights, user_data);
00704                 }
00705                 else return;
00706         }
00707 }
00708 
00709 void LLPanelFriends::handleModifyRights(S32 option, void* user_data)
00710 {
00711         LLPanelFriends* panelp = (LLPanelFriends*)user_data;
00712 
00713         if(panelp)
00714         {
00715                 if(!option)
00716                 {
00717                         panelp->updateMenuState(LLRelationship::GRANT_MODIFY_OBJECTS, !((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
00718                         panelp->applyRightsToFriends(LLRelationship::GRANT_MODIFY_OBJECTS, ((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
00719                 }
00720                 panelp->refreshUI();
00721         }
00722 }
00723 
00724 void LLPanelFriends::updateMenuState(S32 flag, BOOL value)
00725 {
00726         if(value) mMenuState |= flag;
00727         else mMenuState &= ~flag;
00728 }
00729 
00730 void LLPanelFriends::applyRightsToFriends(S32 flag, BOOL value)
00731 {
00732         LLMessageSystem* msg = gMessageSystem;
00733         msg->newMessageFast(_PREHASH_GrantUserRights);
00734         msg->nextBlockFast(_PREHASH_AgentData);
00735         msg->addUUID(_PREHASH_AgentID, gAgent.getID());
00736         msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
00737 
00738         LLDynamicArray<LLUUID> ids = getSelectedIDs();
00739         S32 rights;
00740         for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
00741         {
00742                 rights = LLAvatarTracker::instance().getBuddyInfo(*itr)->getRightsGrantedTo();
00743                 if(LLAvatarTracker::instance().getBuddyInfo(*itr)->isRightGrantedTo(flag) != (bool)value)
00744                 {
00745                         if(value) rights |= flag;
00746                         else rights &= ~flag;
00747                         msg->nextBlockFast(_PREHASH_Rights);
00748                         msg->addUUID(_PREHASH_AgentRelated, *itr);
00749                         msg->addS32(_PREHASH_RelatedRights, rights);
00750                 }
00751         }
00752         mNumRightsChanged = ids.size();
00753         gAgent.sendReliableMessage();
00754 }
00755 
00756 
00757 
00758 // static
00759 void LLPanelFriends::handleRemove(S32 option, void* user_data)
00760 {
00761         LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
00762         for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
00763         {
00764                 LLUUID id = (*itr);
00765                 const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
00766                 if(ip)
00767                 {                       
00768                         switch(option)
00769                         {
00770                         case 0: // YES
00771                                 if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
00772                                 {
00773                                         LLAvatarTracker::instance().empower(id, FALSE);
00774                                         LLAvatarTracker::instance().notifyObservers();
00775                                 }
00776                                 LLAvatarTracker::instance().terminateBuddy(id);
00777                                 LLAvatarTracker::instance().notifyObservers();
00778                                 gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
00779                                 gInventory.notifyObservers();
00780                                 break;
00781 
00782                         case 1: // NO
00783                         default:
00784                                 llinfos << "No removal performed." << llendl;
00785                                 break;
00786                         }
00787                 }
00788                 
00789         }
00790         delete ids;
00791 }

Generated on Thu Jul 1 06:08:33 2010 for Second Life Viewer by  doxygen 1.4.7