diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterfriends.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 768 |
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. | ||
62 | class LLLocalFriendsObserver : public LLFriendObserver | ||
63 | { | ||
64 | public: | ||
65 | LLLocalFriendsObserver(LLFloaterFriends* floater) : mFloater(floater) {} | ||
66 | virtual ~LLLocalFriendsObserver() { mFloater = NULL; } | ||
67 | virtual void changed(U32 mask) | ||
68 | { | ||
69 | mFloater->updateFriends(mask); | ||
70 | } | ||
71 | protected: | ||
72 | LLFloaterFriends* mFloater; | ||
73 | }; | ||
74 | |||
75 | LLFloaterFriends* LLFloaterFriends::sInstance = NULL; | ||
76 | |||
77 | LLFloaterFriends::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 | |||
95 | LLFloaterFriends::~LLFloaterFriends() | ||
96 | { | ||
97 | LLAvatarTracker::instance().removeObserver(mObserver); | ||
98 | delete mObserver; | ||
99 | sInstance = NULL; | ||
100 | gSavedSettings.setBOOL("ShowFriends", FALSE); | ||
101 | } | ||
102 | |||
103 | void LLFloaterFriends::tick() | ||
104 | { | ||
105 | mTimer.stop(); | ||
106 | mPeriod = 1000000; | ||
107 | mAllowRightsChange = TRUE; | ||
108 | updateFriends(LLFriendObserver::ADD); | ||
109 | } | ||
110 | |||
111 | // static | ||
112 | void 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 | ||
127 | BOOL LLFloaterFriends::visible(void*) | ||
128 | { | ||
129 | return sInstance && sInstance->getVisible(); | ||
130 | } | ||
131 | |||
132 | |||
133 | // static | ||
134 | void LLFloaterFriends::toggle(void*) | ||
135 | { | ||
136 | if (sInstance) | ||
137 | { | ||
138 | sInstance->close(); | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | show(); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | |||
147 | void 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 | ||
196 | BOOL 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 | |||
223 | void 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 | |||
277 | void 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 | |||
379 | void 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 | |||
409 | void 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 | ||
451 | LLDynamicArray<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 | ||
467 | void LLFloaterFriends::onSelectName(LLUICtrl* ctrl, void* user_data) | ||
468 | { | ||
469 | if(sInstance) | ||
470 | { | ||
471 | sInstance->refreshUI(); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | //static | ||
476 | void 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 | ||
484 | void 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 | ||
498 | void 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 | ||
536 | void 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 | ||
550 | void 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 | ||
560 | void 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 | ||
584 | void LLFloaterFriends::onClickAddFriend(void* user_data) | ||
585 | { | ||
586 | LLFloaterAvatarPicker::show(onPickAvatar, user_data, FALSE, TRUE); | ||
587 | } | ||
588 | |||
589 | // static | ||
590 | void 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 | ||
621 | void LLFloaterFriends::onClickOfferTeleport(void*) | ||
622 | { | ||
623 | LLDynamicArray<LLUUID> ids = getSelectedIDs(); | ||
624 | if(ids.size() > 0) | ||
625 | { | ||
626 | handle_lure(ids); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | // static | ||
631 | void 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 | ||
641 | void LLFloaterFriends::onClickClose(void* user_data) | ||
642 | { | ||
643 | //llinfos << "LLFloaterFriends::onClickClose()" << llendl; | ||
644 | if(sInstance) | ||
645 | { | ||
646 | sInstance->onClose(false); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | void 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 | |||
657 | void 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 | |||
664 | void 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 | |||
688 | void 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 | |||
701 | void LLFloaterFriends::updateMenuState(S32 flag, BOOL value) | ||
702 | { | ||
703 | if(value) mMenuState |= flag; | ||
704 | else mMenuState &= ~flag; | ||
705 | } | ||
706 | |||
707 | void 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 | ||
736 | void 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 | } | ||