aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterfriends.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterfriends.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloaterfriends.cpp768
1 files changed, 768 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp
new file mode 100644
index 0000000..207454b
--- /dev/null
+++ b/linden/indra/newview/llfloaterfriends.cpp
@@ -0,0 +1,768 @@
1/**
2 * @file llfloaterfriends.cpp
3 * @author Phoenix
4 * @date 2005-01-13
5 * @brief Implementation of the friends floater
6 *
7 * Copyright (c) 2005-2007, Linden Research, Inc.
8 *
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://secondlife.com/developers/opensource/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 http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30
31#include "llviewerprecompiledheaders.h"
32
33#include "llfloaterfriends.h"
34
35#include <sstream>
36
37#include "lldir.h"
38
39#include "llagent.h"
40#include "llfloateravatarpicker.h"
41#include "llviewerwindow.h"
42#include "llbutton.h"
43#include "llcallingcard.h"
44#include "llfloateravatarinfo.h"
45#include "llinventorymodel.h"
46#include "llnamelistctrl.h"
47#include "llnotify.h"
48#include "llresmgr.h"
49#include "llimview.h"
50#include "llvieweruictrlfactory.h"
51#include "llmenucommands.h"
52#include "llviewercontrol.h"
53#include "llviewermessage.h"
54#include "lltimer.h"
55#include "lltextbox.h"
56
57//Maximum number of people you can select to do an operation on at once.
58#define MAX_FRIEND_SELECT 20
59#define RIGHTS_CHANGE_TIMEOUT 5.0
60
61// simple class to observe the calling cards.
62class LLLocalFriendsObserver : public LLFriendObserver
63{
64public:
65 LLLocalFriendsObserver(LLFloaterFriends* floater) : mFloater(floater) {}
66 virtual ~LLLocalFriendsObserver() { mFloater = NULL; }
67 virtual void changed(U32 mask)
68 {
69 mFloater->updateFriends(mask);
70 }
71protected:
72 LLFloaterFriends* mFloater;
73};
74
75LLFloaterFriends* LLFloaterFriends::sInstance = NULL;
76
77LLFloaterFriends::LLFloaterFriends() :
78 LLFloater("Friends"),
79 LLEventTimer(1000000),
80 mObserver(NULL),
81 mMenuState(0),
82 mShowMaxSelectWarning(TRUE),
83 mAllowRightsChange(TRUE),
84 mNumRightsChanged(0)
85{
86 mTimer.stop();
87 sInstance = this;
88 mObserver = new LLLocalFriendsObserver(this);
89 LLAvatarTracker::instance().addObserver(mObserver);
90 gSavedSettings.setBOOL("ShowFriends", TRUE);
91 // Builds and adds to gFloaterView
92 gUICtrlFactory->buildFloater(this, "floater_friends.xml");
93}
94
95LLFloaterFriends::~LLFloaterFriends()
96{
97 LLAvatarTracker::instance().removeObserver(mObserver);
98 delete mObserver;
99 sInstance = NULL;
100 gSavedSettings.setBOOL("ShowFriends", FALSE);
101}
102
103void LLFloaterFriends::tick()
104{
105 mTimer.stop();
106 mPeriod = 1000000;
107 mAllowRightsChange = TRUE;
108 updateFriends(LLFriendObserver::ADD);
109}
110
111// static
112void LLFloaterFriends::show(void*)
113{
114 if(sInstance)
115 {
116 sInstance->open();
117 }
118 else
119 {
120 LLFloaterFriends* self = new LLFloaterFriends;
121 self->open();
122 }
123}
124
125
126// static
127BOOL LLFloaterFriends::visible(void*)
128{
129 return sInstance && sInstance->getVisible();
130}
131
132
133// static
134void LLFloaterFriends::toggle(void*)
135{
136 if (sInstance)
137 {
138 sInstance->close();
139 }
140 else
141 {
142 show();
143 }
144}
145
146
147void LLFloaterFriends::updateFriends(U32 changed_mask)
148{
149 LLUUID selected_id;
150 LLCtrlListInterface *friends_list = sInstance->childGetListInterface("friend_list");
151 if (!friends_list) return;
152 LLCtrlScrollInterface *friends_scroll = sInstance->childGetScrollInterface("friend_list");
153 if (!friends_scroll) return;
154
155 // We kill the selection warning, otherwise we'll spam with warning popups
156 // if the maximum amount of friends are selected
157 mShowMaxSelectWarning = false;
158
159 LLDynamicArray<LLUUID> selected_friends = sInstance->getSelectedIDs();
160 if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
161 {
162 refreshNames();
163 }
164 else if(changed_mask & LLFriendObserver::POWERS)
165 {
166 --mNumRightsChanged;
167 if(mNumRightsChanged > 0)
168 {
169 mPeriod = RIGHTS_CHANGE_TIMEOUT;
170 mTimer.start();
171 mTimer.reset();
172 mAllowRightsChange = FALSE;
173 }
174 else
175 {
176 tick();
177 }
178 }
179 if(selected_friends.size() > 0)
180 {
181 // only non-null if friends was already found. This may fail,
182 // but we don't really care here, because refreshUI() will
183 // clean up the interface.
184 friends_list->setCurrentByID(selected_id);
185 for(LLDynamicArray<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr)
186 {
187 friends_list->setSelectedByValue(*itr, true);
188 }
189 }
190
191 refreshUI();
192 mShowMaxSelectWarning = true;
193}
194
195// virtual
196BOOL LLFloaterFriends::postBuild()
197{
198
199 mFriendsList = LLUICtrlFactory::getScrollListByName(this, "friend_list");
200 mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
201 mFriendsList->setMaxiumumSelectCallback(onMaximumSelect);
202 childSetCommitCallback("friend_list", onSelectName, this);
203 childSetDoubleClickCallback("friend_list", onClickIM);
204
205 refreshNames();
206
207 childSetCommitCallback("online_status_cb", onClickOnlineStatus, this);
208 childSetCommitCallback("map_status_cb", onClickMapStatus, this);
209 childSetCommitCallback("modify_status_cb", onClickModifyStatus, this);
210 childSetAction("im_btn", onClickIM, this);
211 childSetAction("profile_btn", onClickProfile, this);
212 childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
213 childSetAction("pay_btn", onClickPay, this);
214 childSetAction("add_btn", onClickAddFriend, this);
215 childSetAction("remove_btn", onClickRemove, this);
216 childSetAction("close_btn", onClickClose, this);
217
218 refreshUI();
219 return TRUE;
220}
221
222
223void LLFloaterFriends::addFriend(const std::string& name, const LLUUID& agent_id)
224{
225 LLAvatarTracker& at = LLAvatarTracker::instance();
226 const LLRelationship* relationInfo = at.getBuddyInfo(agent_id);
227 if(!relationInfo) return;
228 BOOL online = relationInfo->isOnline();
229
230 LLSD element;
231 element["id"] = agent_id;
232 element["columns"][LIST_FRIEND_NAME]["column"] = "friend_name";
233 element["columns"][LIST_FRIEND_NAME]["value"] = name.c_str();
234 element["columns"][LIST_FRIEND_NAME]["font"] = "SANSSERIF";
235 element["columns"][LIST_FRIEND_NAME]["font-style"] = "NORMAL";
236 element["columns"][LIST_ONLINE_STATUS]["column"] = "icon_online_status";
237 element["columns"][LIST_ONLINE_STATUS]["type"] = "text";
238 if (online)
239 {
240 element["columns"][LIST_FRIEND_NAME]["font-style"] = "BOLD";
241 element["columns"][LIST_ONLINE_STATUS]["type"] = "icon";
242 element["columns"][LIST_ONLINE_STATUS]["value"] = gViewerArt.getString("icon_avatar_online.tga");
243 }
244
245
246 element["columns"][LIST_VISIBLE_ONLINE]["column"] = "icon_visible_online";
247 element["columns"][LIST_VISIBLE_ONLINE]["type"] = "text";
248 if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
249 {
250 element["columns"][LIST_VISIBLE_ONLINE]["type"] = "icon";
251 element["columns"][LIST_VISIBLE_ONLINE]["value"] = gViewerArt.getString("ff_visible_online.tga");
252 }
253 element["columns"][LIST_VISIBLE_MAP]["column"] = "icon_visible_map";
254 element["columns"][LIST_VISIBLE_MAP]["type"] = "text";
255 if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))
256 {
257 element["columns"][LIST_VISIBLE_MAP]["type"] = "icon";
258 element["columns"][LIST_VISIBLE_MAP]["value"] = gViewerArt.getString("ff_visible_map.tga");
259 }
260 element["columns"][LIST_EDIT_MINE]["column"] = "icon_edit_mine";
261 element["columns"][LIST_EDIT_MINE]["type"] = "text";
262 if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
263 {
264 element["columns"][LIST_EDIT_MINE]["type"] = "icon";
265 element["columns"][LIST_EDIT_MINE]["value"] = gViewerArt.getString("ff_edit_mine.tga");
266 }
267 element["columns"][LIST_EDIT_THEIRS]["column"] = "icon_edit_theirs";
268 element["columns"][LIST_EDIT_THEIRS]["type"] = "text";
269 if(relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS))
270 {
271 element["columns"][LIST_EDIT_THEIRS]["type"] = "icon";
272 element["columns"][LIST_EDIT_THEIRS]["value"] = gViewerArt.getString("ff_edit_theirs.tga");
273 }
274 mFriendsList->addElement(element, ADD_BOTTOM);
275}
276
277void LLFloaterFriends::refreshRightsChangeList(U8 state)
278{
279 LLDynamicArray<LLUUID> friends = getSelectedIDs();
280 const LLRelationship* friend_status = NULL;
281 if(friends.size() > 0) friend_status = LLAvatarTracker::instance().getBuddyInfo(friends[0]);
282
283 LLSD row;
284 bool can_change_visibility = false;
285 bool can_change_modify = false;
286 bool can_change_online_multiple = true;
287 bool can_change_map_multiple = true;
288 LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label");
289 if(!mAllowRightsChange)
290 {
291 if(processing_label)
292 {
293 processing_label->setVisible(true);
294 state = 0;
295 }
296 }
297 else
298 {
299 if(processing_label)
300 {
301 processing_label->setVisible(false);
302 }
303 }
304 if(state == 1)
305 {
306 if(!friend_status->isOnline())
307 {
308 childSetEnabled("offer_teleport_btn", false);
309 }
310 can_change_visibility = true;
311 can_change_modify = true;
312 }
313 else if (state == 2)
314 {
315 can_change_visibility = true;
316 can_change_modify = false;
317 for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
318 {
319 friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
320 if(!friend_status->isOnline())
321 {
322 childSetEnabled("offer_teleport_btn", false);
323 }
324 if(!friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
325 {
326 can_change_online_multiple = false;
327 can_change_map_multiple = false;
328 }
329 else if(!friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))
330 {
331 can_change_map_multiple = false;
332 }
333 }
334
335 }
336
337
338 LLCheckboxCtrl* check;
339 mMenuState = 0;
340
341 check = LLUICtrlFactory::getCheckBoxByName(this, "online_status_cb");
342 check->setEnabled(can_change_visibility);
343 check->set(FALSE);
344 if(!mAllowRightsChange) check->setVisible(FALSE);
345 else check->setVisible(TRUE);
346 if(friend_status)
347 {
348 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) && can_change_online_multiple);
349 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) mMenuState |= LLRelationship::GRANT_ONLINE_STATUS;
350 }
351
352 check = LLUICtrlFactory::getCheckBoxByName(this, "map_status_cb");
353 check->setEnabled(false);
354 check->set(FALSE);
355 if(!mAllowRightsChange) check->setVisible(FALSE);
356 else check->setVisible(TRUE);
357 if(friend_status)
358 {
359 check->setEnabled(friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) && can_change_visibility && can_change_online_multiple);
360 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) && can_change_map_multiple);
361 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION)) mMenuState |= LLRelationship::GRANT_MAP_LOCATION;
362 }
363
364 check = LLUICtrlFactory::getCheckBoxByName(this, "modify_status_cb");
365 check->setEnabled(can_change_modify);
366 check->set(FALSE);
367 if(!mAllowRightsChange) check->setVisible(FALSE);
368 else check->setVisible(TRUE);
369 if(can_change_modify)
370 {
371 if(friend_status)
372 {
373 check->set(friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS));
374 if(friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)) mMenuState |= LLRelationship::GRANT_MODIFY_OBJECTS;
375 }
376 }
377}
378
379void LLFloaterFriends::refreshNames()
380{
381 LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();
382 S32 pos = mFriendsList->getScrollPos();
383 mFriendsList->operateOnAll(LLCtrlListInterface::OP_DELETE);
384
385 LLCollectAllBuddies collect;
386 LLAvatarTracker::instance().applyFunctor(collect);
387 LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
388 LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
389
390 for ( ; it != end; ++it)
391 {
392 const std::string& name = it->first;
393 const LLUUID& agent_id = it->second;
394 addFriend(name, agent_id);
395 }
396 it = collect.mOffline.begin();
397 end = collect.mOffline.end();
398 for ( ; it != end; ++it)
399 {
400 const std::string& name = it->first;
401 const LLUUID& agent_id = it->second;
402 addFriend(name, agent_id);
403 }
404 mFriendsList->selectMultiple(selected_ids);
405 mFriendsList->setScrollPos(pos);
406}
407
408
409void LLFloaterFriends::refreshUI()
410{
411 BOOL single_selected = FALSE;
412 BOOL multiple_selected = FALSE;
413 int num_selected = mFriendsList->getAllSelected().size();
414 if(num_selected > 0)
415 {
416 single_selected = TRUE;
417 if(num_selected > 1)
418 {
419 childSetText("friend_name_label", "Multiple friends...");
420 multiple_selected = TRUE;
421 }
422 else
423 {
424 childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getText() + "...");
425 }
426 }
427 else
428 {
429 childSetText("friend_name_label", "");
430 }
431
432
433 //Options that can only be performed with one friend selected
434 childSetEnabled("profile_btn", single_selected && !multiple_selected);
435 childSetEnabled("pay_btn", single_selected && !multiple_selected);
436
437 //Options that can be performed with up to MAX_FRIEND_SELECT friends selected
438 //(single_selected will always be true in this situations)
439 childSetEnabled("remove_btn", single_selected);
440 childSetEnabled("im_btn", single_selected);
441 childSetEnabled("friend_rights", single_selected);
442
443 //Note: We reset this in refreshRightsChangeList since we already have to iterate
444 //through all selected friends there
445 childSetEnabled("offer_teleport_btn", single_selected);
446
447 refreshRightsChangeList((single_selected + multiple_selected));
448}
449
450// static
451LLDynamicArray<LLUUID> LLFloaterFriends::getSelectedIDs()
452{
453 LLUUID selected_id;
454 LLDynamicArray<LLUUID> friend_ids;
455 if(sInstance)
456 {
457 std::vector<LLScrollListItem*> selected = sInstance->mFriendsList->getAllSelected();
458 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
459 {
460 friend_ids.push_back((*itr)->getUUID());
461 }
462 }
463 return friend_ids;
464}
465
466// static
467void LLFloaterFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
468{
469 if(sInstance)
470 {
471 sInstance->refreshUI();
472 }
473}
474
475//static
476void LLFloaterFriends::onMaximumSelect(void* user_data)
477{
478 LLString::format_map_t args;
479 args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
480 LLNotifyBox::showXml("MaxListSelectMessage", args);
481};
482
483// static
484void LLFloaterFriends::onClickProfile(void* user_data)
485{
486 //llinfos << "LLFloaterFriends::onClickProfile()" << llendl;
487 LLDynamicArray<LLUUID> ids = getSelectedIDs();
488 if(ids.size() > 0)
489 {
490 LLUUID agent_id = ids[0];
491 BOOL online;
492 online = LLAvatarTracker::instance().isBuddyOnline(agent_id);
493 LLFloaterAvatarInfo::showFromFriend(agent_id, online);
494 }
495}
496
497// static
498void LLFloaterFriends::onClickIM(void* user_data)
499{
500 //llinfos << "LLFloaterFriends::onClickIM()" << llendl;
501 LLDynamicArray<LLUUID> ids = getSelectedIDs();
502 if(ids.size() > 0)
503 {
504 if(ids.size() == 1)
505 {
506 LLUUID agent_id = ids[0];
507 const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
508 char first[DB_FIRST_NAME_BUF_SIZE];
509 char last[DB_LAST_NAME_BUF_SIZE];
510 if(info && gCacheName->getName(agent_id, first, last))
511 {
512 char buffer[MAX_STRING];
513 snprintf(buffer, MAX_STRING, "%s %s", first, last);
514 gIMView->setFloaterOpen(TRUE);
515 gIMView->addSession(
516 buffer,
517 IM_NOTHING_SPECIAL,
518 agent_id);
519 }
520 }
521 else
522 {
523 LLUUID session_id;
524 session_id.generate();
525 gIMView->setFloaterOpen(TRUE);
526 gIMView->addSession(
527 "Friends Conference",
528 IM_SESSION_ADD,
529 session_id,
530 ids);
531 }
532 }
533}
534
535// static
536void LLFloaterFriends::requestFriendship(const LLUUID& target_id, const LLString& target_name)
537{
538 // HACK: folder id stored as "message"
539 LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
540 std::string message = calling_card_folder_id.getString();
541
542 send_improved_im(target_id,
543 target_name.c_str(),
544 message.c_str(),
545 IM_ONLINE,
546 IM_FRIENDSHIP_OFFERED);
547}
548
549// static
550void LLFloaterFriends::callbackAddFriend(S32 option, void* user_data)
551{
552 if (option == 0)
553 {
554 LLFloaterFriends* self = (LLFloaterFriends*)user_data;
555 requestFriendship(self->mAddFriendID, self->mAddFriendName);
556 }
557}
558
559// static
560void LLFloaterFriends::onPickAvatar(const std::vector<std::string>& names,
561 const std::vector<LLUUID>& ids,
562 void* user_data)
563{
564 if (names.empty()) return;
565 if (ids.empty()) return;
566
567 LLFloaterFriends* self = (LLFloaterFriends*)user_data;
568 self->mAddFriendID = ids[0];
569 self->mAddFriendName = names[0];
570
571 if(ids[0] == gAgentID)
572 {
573 LLNotifyBox::showXml("AddSelfFriend");
574 return;
575 }
576
577 // TODO: accept a line of text with this dialog
578 LLString::format_map_t args;
579 args["[NAME]"] = names[0];
580 gViewerWindow->alertXml("AddFriend", args, callbackAddFriend, user_data);
581}
582
583// static
584void LLFloaterFriends::onClickAddFriend(void* user_data)
585{
586 LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE);
587}
588
589// static
590void LLFloaterFriends::onClickRemove(void* user_data)
591{
592 //llinfos << "LLFloaterFriends::onClickRemove()" << llendl;
593 LLDynamicArray<LLUUID> ids = getSelectedIDs();
594 LLStringBase<char>::format_map_t args;
595 if(ids.size() > 0)
596 {
597 LLString msgType = "RemoveFromFriends";
598 if(ids.size() == 1)
599 {
600 LLUUID agent_id = ids[0];
601 char first[DB_FIRST_NAME_BUF_SIZE];
602 char last[DB_LAST_NAME_BUF_SIZE];
603 if(gCacheName->getName(agent_id, first, last))
604 {
605 args["[FIRST_NAME]"] = first;
606 args["[LAST_NAME]"] = last;
607 }
608 }
609 else
610 {
611 msgType = "RemoveMultipleFromFriends";
612 }
613 gViewerWindow->alertXml(msgType,
614 args,
615 &handleRemove,
616 (void*)new LLDynamicArray<LLUUID>(ids));
617 }
618}
619
620// static
621void LLFloaterFriends::onClickOfferTeleport(void*)
622{
623 LLDynamicArray<LLUUID> ids = getSelectedIDs();
624 if(ids.size() > 0)
625 {
626 handle_lure(ids);
627 }
628}
629
630// static
631void LLFloaterFriends::onClickPay(void*)
632{
633 LLDynamicArray<LLUUID> ids = getSelectedIDs();
634 if(ids.size() == 1)
635 {
636 handle_pay_by_id(ids[0]);
637 }
638}
639
640// static
641void LLFloaterFriends::onClickClose(void* user_data)
642{
643 //llinfos << "LLFloaterFriends::onClickClose()" << llendl;
644 if(sInstance)
645 {
646 sInstance->onClose(false);
647 }
648}
649
650void LLFloaterFriends::onClickOnlineStatus(LLUICtrl* ctrl, void* user_data)
651{
652 bool checked = ctrl->getValue();
653 sInstance->updateMenuState(LLRelationship::GRANT_ONLINE_STATUS, checked);
654 sInstance->applyRightsToFriends(LLRelationship::GRANT_ONLINE_STATUS, checked);
655}
656
657void LLFloaterFriends::onClickMapStatus(LLUICtrl* ctrl, void* user_data)
658{
659 bool checked = ctrl->getValue();
660 sInstance->updateMenuState(LLRelationship::GRANT_MAP_LOCATION, checked);
661 sInstance->applyRightsToFriends(LLRelationship::GRANT_MAP_LOCATION, checked);
662}
663
664void LLFloaterFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
665{
666 bool checked = ctrl->getValue();
667 LLDynamicArray<LLUUID> ids = getSelectedIDs();
668 LLStringBase<char>::format_map_t args;
669 if(ids.size() > 0)
670 {
671 if(ids.size() == 1)
672 {
673 LLUUID agent_id = ids[0];
674 char first[DB_FIRST_NAME_BUF_SIZE];
675 char last[DB_LAST_NAME_BUF_SIZE];
676 if(gCacheName->getName(agent_id, first, last))
677 {
678 args["[FIRST_NAME]"] = first;
679 args["[LAST_NAME]"] = last;
680 }
681 if(checked) gViewerWindow->alertXml("GrantModifyRights", args, handleModifyRights, NULL);
682 else gViewerWindow->alertXml("RevokeModifyRights", args, handleModifyRights, NULL);
683 }
684 else return;
685 }
686}
687
688void LLFloaterFriends::handleModifyRights(S32 option, void* user_data)
689{
690 if(sInstance)
691 {
692 if(!option)
693 {
694 sInstance->updateMenuState(LLRelationship::GRANT_MODIFY_OBJECTS, !((sInstance->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
695 sInstance->applyRightsToFriends(LLRelationship::GRANT_MODIFY_OBJECTS, ((sInstance->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
696 }
697 sInstance->refreshUI();
698 }
699}
700
701void LLFloaterFriends::updateMenuState(S32 flag, BOOL value)
702{
703 if(value) mMenuState |= flag;
704 else mMenuState &= ~flag;
705}
706
707void LLFloaterFriends::applyRightsToFriends(S32 flag, BOOL value)
708{
709 LLMessageSystem* msg = gMessageSystem;
710 msg->newMessageFast(_PREHASH_GrantUserRights);
711 msg->nextBlockFast(_PREHASH_AgentData);
712 msg->addUUID(_PREHASH_AgentID, gAgent.getID());
713 msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
714
715 LLDynamicArray<LLUUID> ids = getSelectedIDs();
716 S32 rights;
717 for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
718 {
719 rights = LLAvatarTracker::instance().getBuddyInfo(*itr)->getRightsGrantedTo();
720 if(LLAvatarTracker::instance().getBuddyInfo(*itr)->isRightGrantedTo(flag) != (bool)value)
721 {
722 if(value) rights |= flag;
723 else rights &= ~flag;
724 msg->nextBlockFast(_PREHASH_Rights);
725 msg->addUUID(_PREHASH_AgentRelated, *itr);
726 msg->addS32(_PREHASH_RelatedRights, rights);
727 }
728 }
729 mNumRightsChanged = ids.size();
730 gAgent.sendReliableMessage();
731}
732
733
734
735// static
736void LLFloaterFriends::handleRemove(S32 option, void* user_data)
737{
738 LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
739 for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
740 {
741 LLUUID id = (*itr);
742 const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
743 if(ip)
744 {
745 switch(option)
746 {
747 case 0: // YES
748 if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
749 {
750 LLAvatarTracker::instance().empower(id, FALSE);
751 LLAvatarTracker::instance().notifyObservers();
752 }
753 LLAvatarTracker::instance().terminateBuddy(id);
754 LLAvatarTracker::instance().notifyObservers();
755 gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
756 gInventory.notifyObservers();
757 break;
758
759 case 1: // NO
760 default:
761 llinfos << "No removal performed." << llendl;
762 break;
763 }
764 }
765
766 }
767 delete ids;
768}