diff options
Diffstat (limited to 'linden/indra/newview/llfloatermap.cpp')
-rw-r--r-- | linden/indra/newview/llfloatermap.cpp | 894 |
1 files changed, 893 insertions, 1 deletions
diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index 3b1e4c7..85057ee 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp | |||
@@ -43,14 +43,45 @@ | |||
43 | #include "llresizebar.h" | 43 | #include "llresizebar.h" |
44 | #include "lluictrlfactory.h" | 44 | #include "lluictrlfactory.h" |
45 | 45 | ||
46 | // radar | ||
47 | #include "llchat.h" | ||
48 | #include "llfirstuse.h" | ||
49 | #include "llfloateravatarinfo.h" | ||
50 | #include "llfloaterchat.h" | ||
51 | #include "llfloaterfriends.h" | ||
52 | #include "llfloatergroupinvite.h" | ||
53 | #include "llfloatergroups.h" | ||
54 | #include "llfloaterreporter.h" | ||
55 | #include "llimview.h" | ||
56 | #include "llmutelist.h" | ||
57 | #include "llparcel.h" | ||
58 | #include "llregionposition.h" | ||
59 | #include "roles_constants.h" | ||
60 | #include "llscrolllistctrl.h" | ||
61 | #include "lltracker.h" | ||
62 | #include "llviewerobjectlist.h" | ||
63 | #include "llviewermenu.h" | ||
64 | #include "llviewermessage.h" | ||
65 | #include "llviewerparcelmgr.h" | ||
66 | #include "llviewerregion.h" | ||
67 | #include "llviewerwindow.h" | ||
68 | #include "llvoavatar.h" | ||
69 | #include "llworld.h" | ||
70 | |||
46 | LLFloaterMap::LLFloaterMap(const LLSD& key) | 71 | LLFloaterMap::LLFloaterMap(const LLSD& key) |
47 | : | 72 | : |
48 | LLFloater(std::string("minimap")), | 73 | LLFloater(std::string("minimap")), |
49 | mPanelMap(NULL) | 74 | mPanelMap(NULL), |
75 | mUpdate(TRUE), | ||
76 | mSelectedAvatar(LLUUID::null) | ||
77 | |||
50 | { | 78 | { |
51 | LLCallbackMap::map_t factory_map; | 79 | LLCallbackMap::map_t factory_map; |
52 | factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this); | 80 | factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this); |
53 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE); | 81 | LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE); |
82 | |||
83 | mChatAvatars.clear(); | ||
84 | mTypingAvatars.clear(); | ||
54 | } | 85 | } |
55 | 86 | ||
56 | 87 | ||
@@ -66,8 +97,33 @@ BOOL LLFloaterMap::postBuild() | |||
66 | { | 97 | { |
67 | // Send the drag handle to the back, but make sure close stays on top | 98 | // Send the drag handle to the back, but make sure close stays on top |
68 | sendChildToBack(getDragHandle()); | 99 | sendChildToBack(getDragHandle()); |
100 | sendChildToFront(getChild<LLButton>("llfloater_minimize_btn")); | ||
69 | sendChildToFront(getChild<LLButton>("llfloater_close_btn")); | 101 | sendChildToFront(getChild<LLButton>("llfloater_close_btn")); |
70 | setIsChrome(TRUE); | 102 | setIsChrome(TRUE); |
103 | |||
104 | mRadarList = getChild<LLScrollListCtrl>("RadarList"); | ||
105 | childSetCommitCallback("RadarList", onList, this); | ||
106 | mRadarList->setDoubleClickCallback(onClickIM); | ||
107 | |||
108 | childSetFocusChangedCallback("near_me_range", onRangeChange, this); | ||
109 | |||
110 | childSetAction("im_btn", onClickIM, this); | ||
111 | childSetAction("profile_btn", onClickProfile, this); | ||
112 | childSetAction("offer_teleport_btn", onClickOfferTeleport, this); | ||
113 | childSetAction("track_btn", onClickTrack, this); | ||
114 | childSetAction("invite_btn", onClickInvite, this); | ||
115 | childSetAction("add_btn", onClickAddFriend, this); | ||
116 | childSetAction("freeze_btn", onClickFreeze, this); | ||
117 | childSetAction("eject_btn", onClickEject, this); | ||
118 | childSetAction("mute_btn", onClickMute, this); | ||
119 | childSetAction("unmute_btn", onClickUnmute, this); | ||
120 | childSetAction("ar_btn", onClickAR, this); | ||
121 | childSetAction("estate_eject_btn", onClickEjectFromEstate, this); | ||
122 | |||
123 | setDefaultBtn("im_btn"); | ||
124 | |||
125 | populateRadar(); | ||
126 | |||
71 | return TRUE; | 127 | return TRUE; |
72 | } | 128 | } |
73 | 129 | ||
@@ -123,3 +179,839 @@ void LLFloaterMap::draw() | |||
123 | } | 179 | } |
124 | } | 180 | } |
125 | 181 | ||
182 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c) | ||
183 | void LLFloaterMap::open() | ||
184 | { | ||
185 | if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP)) | ||
186 | { | ||
187 | LLFloater::open(); | ||
188 | LLFirstUse::useMiniMap(); | ||
189 | } | ||
190 | } | ||
191 | // [/RLVa:KB] | ||
192 | |||
193 | // TODO: make this detachable | ||
194 | // TODO: make this expand/collapse | ||
195 | |||
196 | /* | ||
197 | * Imprudence Radar | ||
198 | * @brief inworld radar integrated with the minimap | ||
199 | * by McCabe Maxsted | ||
200 | * Estate tab portion by Dale Glass | ||
201 | */ | ||
202 | |||
203 | //static | ||
204 | bool LLFloaterMap::isImpDev(LLUUID agent_id) | ||
205 | { | ||
206 | // We use strings here as avatar keys change across grids. | ||
207 | // Feel free to add/remove yourself. | ||
208 | std::string agent_name = getSelectedName(agent_id); | ||
209 | if (agent_name == "McCabe Maxsted" || | ||
210 | agent_name == "Jacek Antonelli" || | ||
211 | agent_name == "Armin Weatherwax") | ||
212 | { | ||
213 | return true; | ||
214 | } | ||
215 | return false; | ||
216 | } | ||
217 | |||
218 | //static | ||
219 | void LLFloaterMap::updateRadar() | ||
220 | { | ||
221 | LLFloaterMap::getInstance()->populateRadar(); | ||
222 | } | ||
223 | |||
224 | void LLFloaterMap::populateRadar() | ||
225 | { | ||
226 | if (!mUpdate || !LLFloaterMap::getInstance()->getVisible()) | ||
227 | { | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | if (visibleItemsSelected()) | ||
232 | { | ||
233 | mSelectedAvatar = mRadarList->getFirstSelected()->getUUID(); | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | mSelectedAvatar.setNull(); | ||
238 | } | ||
239 | |||
240 | S32 scroll_pos = mRadarList->getScrollPos(); | ||
241 | |||
242 | // clear count | ||
243 | std::stringstream avatar_count; | ||
244 | avatar_count.str(""); | ||
245 | |||
246 | // find what avatars you can see | ||
247 | F32 range = gSavedSettings.getF32("NearMeRange"); | ||
248 | LLVector3d current_pos = gAgent.getPositionGlobal(); | ||
249 | std::vector<LLUUID> avatar_ids; | ||
250 | std::vector<LLVector3d> positions; | ||
251 | LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); | ||
252 | |||
253 | LLSD element; | ||
254 | |||
255 | mRadarList->deleteAllItems(); | ||
256 | |||
257 | if (!avatar_ids.empty()) | ||
258 | { | ||
259 | for (U32 i=0; i<avatar_ids.size(); i++) | ||
260 | { | ||
261 | if (avatar_ids[i] == gAgent.getID() || | ||
262 | avatar_ids[i].isNull()) | ||
263 | { | ||
264 | continue; | ||
265 | } | ||
266 | |||
267 | // Add to list only if we get their name | ||
268 | std::string fullname = getSelectedName(avatar_ids[i]); | ||
269 | if (!fullname.empty()) | ||
270 | { | ||
271 | bool notify_chat = gSavedSettings.getBOOL("MiniMapNotifyChatRange"); | ||
272 | bool notify_sim = gSavedSettings.getBOOL("MiniMapNotifySimRange"); | ||
273 | // [RLVa:KB] - Alternate: Imprudence-1.2.0 | ||
274 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
275 | { | ||
276 | fullname = gRlvHandler.getAnonym(fullname); | ||
277 | notify_chat = false; | ||
278 | notify_sim = false; | ||
279 | } | ||
280 | // [/RLVa:KB] | ||
281 | |||
282 | // check if they're in certain ranges and notify user if we've enabled that | ||
283 | LLVector3d temp = positions[i] - current_pos; | ||
284 | F32 distance = llround((F32)temp.magVec(), 0.1f); | ||
285 | /*char dist[32]; | ||
286 | sprintf(dist, "%.1f", distance); | ||
287 | std::string dist_string = dist;*/ | ||
288 | std::string dist_string = llformat("%.1f", distance); | ||
289 | |||
290 | if (notify_chat) | ||
291 | { | ||
292 | if (distance < 20.0f) | ||
293 | { | ||
294 | if (!isInChatList(avatar_ids[i])) | ||
295 | { | ||
296 | addToChatList(avatar_ids[i], dist_string); | ||
297 | } | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | if (isInChatList(avatar_ids[i])) | ||
302 | { | ||
303 | removeFromChatList(avatar_ids[i]); | ||
304 | } | ||
305 | } | ||
306 | updateChatList(avatar_ids); | ||
307 | } | ||
308 | else if (!mChatAvatars.empty()) | ||
309 | { | ||
310 | mChatAvatars.clear(); | ||
311 | } | ||
312 | |||
313 | if (notify_sim) | ||
314 | { | ||
315 | if (!isInChatList(avatar_ids[i]) && !getInSimAvList(avatar_ids[i])) | ||
316 | { | ||
317 | LLViewerObject *av_obj = gObjectList.findObject(avatar_ids[i]); | ||
318 | if (av_obj != NULL && av_obj->isAvatar()) | ||
319 | { | ||
320 | LLVOAvatar* avatarp = (LLVOAvatar*)av_obj; | ||
321 | if (avatarp != NULL) | ||
322 | { | ||
323 | if (avatarp->getRegion() == gAgent.getRegion()) | ||
324 | { | ||
325 | addToSimAvList(avatar_ids[i], dist_string); | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | updateSimAvList(avatar_ids); | ||
331 | } | ||
332 | else if (!mSimAvatars.empty()) | ||
333 | { | ||
334 | mSimAvatars.clear(); | ||
335 | } | ||
336 | |||
337 | // only display avatars in range | ||
338 | if (distance <= range) | ||
339 | { | ||
340 | // append typing string | ||
341 | std::string typing = ""; | ||
342 | if (isTyping(avatar_ids[i])) | ||
343 | { | ||
344 | typing = getString("is_typing")+ " "; | ||
345 | } | ||
346 | |||
347 | std::string mute_text = LLMuteList::getInstance()->isMuted(avatar_ids[i]) ? getString("is_muted") : ""; | ||
348 | element["id"] = avatar_ids[i]; | ||
349 | element["columns"][0]["column"] = "avatar_name"; | ||
350 | element["columns"][0]["type"] = "text"; | ||
351 | element["columns"][0]["value"] = typing + fullname + " " + mute_text; | ||
352 | element["columns"][1]["column"] = "avatar_distance"; | ||
353 | element["columns"][1]["type"] = "text"; | ||
354 | element["columns"][1]["value"] = dist_string+"m"; | ||
355 | |||
356 | mRadarList->addElement(element, ADD_BOTTOM); | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | |||
361 | mRadarList->sortItems(); | ||
362 | mRadarList->setScrollPos(scroll_pos); | ||
363 | if (mSelectedAvatar.notNull()) | ||
364 | { | ||
365 | mRadarList->selectByID(mSelectedAvatar); | ||
366 | } | ||
367 | avatar_count << (int)avatar_ids.size(); | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | mTypingAvatars.clear(); | ||
372 | mRadarList->addCommentText(getString("no_one_near"), ADD_TOP); | ||
373 | avatar_count << "0"; | ||
374 | } | ||
375 | |||
376 | childSetText("lblAvatarCount", avatar_count.str()); | ||
377 | |||
378 | toggleButtons(); | ||
379 | |||
380 | //llinfos << "mSelectedAvatar: " << mSelectedAvatar.asString() << llendl; | ||
381 | } | ||
382 | |||
383 | void LLFloaterMap::updateChatList(std::vector<LLUUID> agent_ids) | ||
384 | { | ||
385 | std::set<LLUUID>::iterator it; | ||
386 | std::vector<LLUUID>::iterator result; | ||
387 | for (it = mChatAvatars.begin(); it != mChatAvatars.end(); ) | ||
388 | { | ||
389 | result = find(agent_ids.begin(), agent_ids.end(), *it); | ||
390 | if (result == agent_ids.end()) | ||
391 | { | ||
392 | mChatAvatars.erase(it++); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | it++; | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | |||
401 | bool LLFloaterMap::isInChatList(LLUUID agent_id) | ||
402 | { | ||
403 | if (mChatAvatars.count(agent_id) > 0) | ||
404 | { | ||
405 | return true; | ||
406 | } | ||
407 | return false; | ||
408 | } | ||
409 | |||
410 | void LLFloaterMap::addToChatList(LLUUID agent_id, std::string distance) | ||
411 | { | ||
412 | mChatAvatars.insert(agent_id); | ||
413 | LLChat chat; | ||
414 | |||
415 | LLUIString notify = getString("entering_chat_range"); | ||
416 | notify.setArg("[NAME]", getSelectedName(agent_id)); | ||
417 | notify.setArg("[DISTANCE]", distance); | ||
418 | |||
419 | chat.mText = notify; | ||
420 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | ||
421 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
422 | } | ||
423 | |||
424 | void LLFloaterMap::removeFromChatList(LLUUID agent_id) | ||
425 | { | ||
426 | // Do we want to add a notice? | ||
427 | mChatAvatars.erase(agent_id); | ||
428 | } | ||
429 | |||
430 | bool LLFloaterMap::isTyping(LLUUID agent_id) | ||
431 | { | ||
432 | if (mTypingAvatars.count(agent_id) > 0) | ||
433 | { | ||
434 | return true; | ||
435 | } | ||
436 | return false; | ||
437 | } | ||
438 | |||
439 | void LLFloaterMap::updateTypingList(LLUUID agent_id, bool remove) | ||
440 | { | ||
441 | if (remove) | ||
442 | { | ||
443 | if (isTyping(agent_id)) | ||
444 | { | ||
445 | mTypingAvatars.erase(agent_id); | ||
446 | } | ||
447 | } | ||
448 | else | ||
449 | { | ||
450 | mTypingAvatars.insert(agent_id); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | void LLFloaterMap::updateSimAvList(std::vector<LLUUID> agent_ids) | ||
455 | { | ||
456 | std::set<LLUUID>::iterator it; | ||
457 | std::vector<LLUUID>::iterator result; | ||
458 | for (it = mSimAvatars.begin(); it != mSimAvatars.end(); ) | ||
459 | { | ||
460 | result = find(agent_ids.begin(), agent_ids.end(), *it); | ||
461 | if (result == agent_ids.end()) | ||
462 | { | ||
463 | mSimAvatars.erase(it++); | ||
464 | } | ||
465 | else | ||
466 | { | ||
467 | it++; | ||
468 | } | ||
469 | } | ||
470 | } | ||
471 | |||
472 | void LLFloaterMap::addToSimAvList(LLUUID agent_id, std::string distance) | ||
473 | { | ||
474 | mSimAvatars.insert(agent_id); | ||
475 | LLChat chat; | ||
476 | |||
477 | LLUIString notify = getString("entering_sim_range"); | ||
478 | notify.setArg("[NAME]", getSelectedName(agent_id)); | ||
479 | notify.setArg("[DISTANCE]", distance); | ||
480 | |||
481 | chat.mText = notify; | ||
482 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | ||
483 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
484 | } | ||
485 | |||
486 | bool LLFloaterMap::getInSimAvList(LLUUID agent_id) | ||
487 | { | ||
488 | if (mSimAvatars.count(agent_id) > 0) | ||
489 | { | ||
490 | return true; | ||
491 | } | ||
492 | return false; | ||
493 | } | ||
494 | |||
495 | void LLFloaterMap::toggleButtons() | ||
496 | { | ||
497 | BOOL enable = FALSE; | ||
498 | BOOL enable_unmute = FALSE; | ||
499 | BOOL enable_track = FALSE; | ||
500 | BOOL enable_estate = FALSE; | ||
501 | BOOL enable_friend = FALSE; | ||
502 | if (childHasFocus("RadarPanel")) | ||
503 | { | ||
504 | enable = mSelectedAvatar.notNull() ? visibleItemsSelected() : FALSE; | ||
505 | enable_unmute = mSelectedAvatar.notNull() ? LLMuteList::getInstance()->isMuted(mSelectedAvatar) : FALSE; | ||
506 | enable_track = gAgent.isGodlike() || is_agent_mappable(mSelectedAvatar); | ||
507 | enable_estate = isKickable(mSelectedAvatar); | ||
508 | enable_friend = !is_agent_friend(mSelectedAvatar); | ||
509 | } | ||
510 | else | ||
511 | { | ||
512 | mRadarList->deselect(); | ||
513 | } | ||
514 | |||
515 | childSetEnabled("im_btn", enable); | ||
516 | childSetEnabled("profile_btn", enable); | ||
517 | childSetEnabled("offer_teleport_btn", enable); | ||
518 | childSetEnabled("track_btn", enable_track); | ||
519 | childSetEnabled("invite_btn", enable); | ||
520 | childSetEnabled("add_btn", enable); | ||
521 | childSetEnabled("freeze_btn", enable_estate); | ||
522 | childSetEnabled("eject_btn", enable_estate); | ||
523 | childSetEnabled("mute_btn", enable); | ||
524 | childSetEnabled("ar_btn", enable); | ||
525 | childSetEnabled("estate_eject_btn", enable_estate); | ||
526 | |||
527 | if (enable_unmute) | ||
528 | { | ||
529 | childSetVisible("mute_btn", false); | ||
530 | childSetEnabled("unmute_btn", true); | ||
531 | childSetVisible("unmute_btn", true); | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | childSetVisible("mute_btn", true); | ||
536 | childSetVisible("unmute_btn", false); | ||
537 | } | ||
538 | |||
539 | // [RLVa:KB] - Imprudence-1.2.0 | ||
540 | // Bit clumsy, but this way the RLV stuff is in its own separate block and keeps the code above clean - Kitty | ||
541 | if ( (rlv_handler_t::isEnabled()) && (mSelectedAvatar.notNull()) ) | ||
542 | { | ||
543 | if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) | ||
544 | { | ||
545 | childSetEnabled("im_btn", FALSE); | ||
546 | childSetEnabled("profile_btn", FALSE); | ||
547 | childSetEnabled("invite_btn", FALSE); | ||
548 | childSetEnabled("add_btn", FALSE); | ||
549 | childSetEnabled("mute_btn", FALSE); | ||
550 | childSetEnabled("unmute_btn", FALSE); | ||
551 | } | ||
552 | |||
553 | // Even though the avie is in the same sim (so they already know where we are) the tp would just get blocked by different code | ||
554 | // so it's actually less confusing to the user if we just disable the teleport button here so they'll at least have a visual cue | ||
555 | BOOL rlv_enable_tp = (!gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) || (gRlvHandler.isException(RLV_BHVR_TPLURE, mSelectedAvatar)); | ||
556 | if ( (rlv_enable_tp) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) | ||
557 | { | ||
558 | const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(mSelectedAvatar); | ||
559 | if ( ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) ) | ||
560 | rlv_enable_tp = FALSE; | ||
561 | } | ||
562 | childSetEnabled("offer_teleport_btn", rlv_enable_tp); | ||
563 | } | ||
564 | // [/RLVa:KB] | ||
565 | } | ||
566 | |||
567 | BOOL LLFloaterMap::isKickable(const LLUUID &agent_id) | ||
568 | { | ||
569 | if (agent_id.notNull()) | ||
570 | { | ||
571 | LLViewerObject* av_obj = gObjectList.findObject(agent_id); | ||
572 | if (av_obj != NULL && av_obj->isAvatar()) | ||
573 | { | ||
574 | LLVOAvatar* avatar = (LLVOAvatar*)av_obj; | ||
575 | LLViewerRegion* region = avatar->getRegion(); | ||
576 | if (region) | ||
577 | { | ||
578 | const LLVector3& pos = avatar->getPositionRegion(); | ||
579 | const LLVector3d& pos_global = avatar->getPositionGlobal(); | ||
580 | if (LLWorld::getInstance()->positionRegionValidGlobal(pos_global)) | ||
581 | { | ||
582 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel(); | ||
583 | LLViewerParcelMgr::getInstance()->deselectLand(); | ||
584 | |||
585 | BOOL new_value = (region != NULL); | ||
586 | |||
587 | if (new_value) | ||
588 | { | ||
589 | new_value = region->isOwnedSelf(pos); | ||
590 | if (!new_value || region->isOwnedGroup(pos)) | ||
591 | { | ||
592 | new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN); | ||
593 | } | ||
594 | } | ||
595 | return new_value; | ||
596 | } | ||
597 | } | ||
598 | } | ||
599 | } | ||
600 | return FALSE; | ||
601 | } | ||
602 | |||
603 | // static | ||
604 | void LLFloaterMap::onList(LLUICtrl* ctrl, void* user_data) | ||
605 | { | ||
606 | LLFloaterMap* self = (LLFloaterMap*)user_data; | ||
607 | if (self) | ||
608 | { | ||
609 | self->toggleButtons(); | ||
610 | } | ||
611 | } | ||
612 | |||
613 | BOOL LLFloaterMap::visibleItemsSelected() const | ||
614 | { | ||
615 | if (mRadarList->getFirstSelectedIndex() >= 0) | ||
616 | { | ||
617 | return TRUE; | ||
618 | } | ||
619 | return FALSE; | ||
620 | } | ||
621 | |||
622 | // static | ||
623 | void LLFloaterMap::onRangeChange(LLFocusableElement* focus, void* user_data) | ||
624 | { | ||
625 | LLFloaterMap* self = (LLFloaterMap*)user_data; | ||
626 | if (self) | ||
627 | { | ||
628 | self->mUpdate = !(self->childHasFocus("near_me_range")); | ||
629 | } | ||
630 | } | ||
631 | |||
632 | // static | ||
633 | LLUUID LLFloaterMap::getSelected() | ||
634 | { | ||
635 | return LLFloaterMap::getInstance()->mSelectedAvatar; | ||
636 | } | ||
637 | |||
638 | // | ||
639 | // Avatar tab | ||
640 | // | ||
641 | |||
642 | // static | ||
643 | void LLFloaterMap::onClickIM(void* user_data) | ||
644 | { | ||
645 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
646 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
647 | if (item != NULL) | ||
648 | { | ||
649 | LLUUID agent_id = item->getUUID(); | ||
650 | gIMMgr->setFloaterOpen(TRUE); | ||
651 | gIMMgr->addSession(getSelectedName(agent_id), IM_NOTHING_SPECIAL, agent_id); | ||
652 | } | ||
653 | } | ||
654 | |||
655 | // static | ||
656 | void LLFloaterMap::onClickProfile(void* user_data) | ||
657 | { | ||
658 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
659 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
660 | if (item != NULL) | ||
661 | { | ||
662 | LLUUID agent_id = item->getUUID(); | ||
663 | LLFloaterAvatarInfo::show(agent_id); | ||
664 | } | ||
665 | } | ||
666 | |||
667 | // static | ||
668 | void LLFloaterMap::onClickOfferTeleport(void* user_data) | ||
669 | { | ||
670 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
671 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
672 | if (item != NULL) | ||
673 | { | ||
674 | LLUUID agent_id = item->getUUID(); | ||
675 | handle_lure(agent_id); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | // static | ||
680 | void LLFloaterMap::onClickTrack(void* user_data) | ||
681 | { | ||
682 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
683 | LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); | ||
684 | |||
685 | if (LLTracker::TRACKING_AVATAR == tracking_status) | ||
686 | { | ||
687 | LLTracker::stopTracking(NULL); | ||
688 | } | ||
689 | else | ||
690 | { | ||
691 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
692 | if (item != NULL) | ||
693 | { | ||
694 | LLUUID agent_id = item->getUUID(); | ||
695 | LLTracker::trackAvatar(agent_id, getSelectedName(agent_id)); | ||
696 | } | ||
697 | } | ||
698 | } | ||
699 | |||
700 | // static | ||
701 | void LLFloaterMap::onClickInvite(void* user_data) | ||
702 | { | ||
703 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
704 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
705 | if (item != NULL) | ||
706 | { | ||
707 | LLUUID agent_id = item->getUUID(); | ||
708 | LLFloaterGroupPicker* widget; | ||
709 | widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); | ||
710 | if (widget) | ||
711 | { | ||
712 | widget->center(); | ||
713 | widget->setPowersMask(GP_MEMBER_INVITE); | ||
714 | widget->setSelectCallback(callback_invite_to_group, (void *)&agent_id); | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | // static | ||
720 | void LLFloaterMap::callback_invite_to_group(LLUUID group_id, void *user_data) | ||
721 | { | ||
722 | std::vector<LLUUID> agent_ids; | ||
723 | agent_ids.push_back(*(LLUUID *)user_data); | ||
724 | |||
725 | LLFloaterGroupInvite::showForGroup(group_id, &agent_ids); | ||
726 | } | ||
727 | |||
728 | // static | ||
729 | void LLFloaterMap::onClickAddFriend(void* user_data) | ||
730 | { | ||
731 | LLFloaterMap* self = (LLFloaterMap*) user_data; | ||
732 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
733 | if (item != NULL) | ||
734 | { | ||
735 | LLUUID agent_id = item->getUUID(); | ||
736 | LLPanelFriends::requestFriendshipDialog(agent_id, getSelectedName(agent_id)); | ||
737 | } | ||
738 | } | ||
739 | |||
740 | // | ||
741 | // Estate tab | ||
742 | // | ||
743 | |||
744 | //static | ||
745 | std::string LLFloaterMap::getSelectedName(const LLUUID &agent_id) | ||
746 | { | ||
747 | std::string agent_name; | ||
748 | if(gCacheName->getFullName(agent_id, agent_name) && agent_name != " ") | ||
749 | { | ||
750 | return agent_name; | ||
751 | } | ||
752 | return LLStringUtil::null; | ||
753 | } | ||
754 | |||
755 | //static | ||
756 | void LLFloaterMap::callbackFreeze(S32 option, void *user_data) | ||
757 | { | ||
758 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
759 | |||
760 | if ( option == 0 ) | ||
761 | { | ||
762 | sendFreeze(self->mSelectedAvatar, true); | ||
763 | } | ||
764 | else if ( option == 1 ) | ||
765 | { | ||
766 | sendFreeze(self->mSelectedAvatar, false); | ||
767 | } | ||
768 | } | ||
769 | |||
770 | //static | ||
771 | void LLFloaterMap::callbackEject(S32 option, void *user_data) | ||
772 | { | ||
773 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
774 | |||
775 | if ( option == 0 ) | ||
776 | { | ||
777 | sendEject(self->mSelectedAvatar, false); | ||
778 | } | ||
779 | else if ( option == 1 ) | ||
780 | { | ||
781 | sendEject(self->mSelectedAvatar, true); | ||
782 | } | ||
783 | } | ||
784 | |||
785 | //static | ||
786 | void LLFloaterMap::callbackEjectFromEstate(S32 option, void *user_data) | ||
787 | { | ||
788 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
789 | |||
790 | if ( option == 0 ) | ||
791 | { | ||
792 | cmdEstateEject(self->mSelectedAvatar); | ||
793 | } | ||
794 | else if ( option == 1 ) | ||
795 | { | ||
796 | cmdEstateBan(self->mSelectedAvatar); | ||
797 | } | ||
798 | } | ||
799 | |||
800 | void LLFloaterMap::onClickFreeze(void *user_data) | ||
801 | { | ||
802 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
803 | LLStringUtil::format_map_t args; | ||
804 | LLSD payload; | ||
805 | args["[AVATAR_NAME]"] = getSelectedName(self->mSelectedAvatar); | ||
806 | gViewerWindow->alertXml("FreezeAvatarFullname", args, callbackFreeze, user_data); | ||
807 | } | ||
808 | |||
809 | //static | ||
810 | void LLFloaterMap::onClickEject(void *user_data) | ||
811 | { | ||
812 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
813 | LLStringUtil::format_map_t args; | ||
814 | LLSD payload; | ||
815 | args["AVATAR_NAME"] = getSelectedName(self->mSelectedAvatar); | ||
816 | gViewerWindow->alertXml("EjectAvatarFullName", args, callbackEject, user_data); | ||
817 | } | ||
818 | |||
819 | //static | ||
820 | void LLFloaterMap::onClickMute(void *user_data) | ||
821 | { | ||
822 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
823 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
824 | if (item != NULL) | ||
825 | { | ||
826 | LLUUID agent_id = item->getUUID(); | ||
827 | std::string agent_name = getSelectedName(agent_id); | ||
828 | if (LLMuteList::getInstance()->isMuted(agent_id)) | ||
829 | { | ||
830 | //LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
831 | //LLMuteList::getInstance()->remove(mute); | ||
832 | //LLFloaterMute::getInstance()->selectMute(agent_id); | ||
833 | } | ||
834 | else | ||
835 | { | ||
836 | LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
837 | LLMuteList::getInstance()->add(mute); | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | |||
842 | //static | ||
843 | void LLFloaterMap::onClickUnmute(void *user_data) | ||
844 | { | ||
845 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
846 | LLScrollListItem *item = self->mRadarList->getFirstSelected(); | ||
847 | if (item != NULL) | ||
848 | { | ||
849 | LLUUID agent_id = item->getUUID(); | ||
850 | std::string agent_name = getSelectedName(agent_id); | ||
851 | if (LLMuteList::getInstance()->isMuted(agent_id)) | ||
852 | { | ||
853 | LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
854 | LLMuteList::getInstance()->remove(mute); | ||
855 | //LLFloaterMute::getInstance()->selectMute(agent_id); | ||
856 | } | ||
857 | else | ||
858 | { | ||
859 | //LLMute mute(agent_id, agent_name, LLMute::AGENT); | ||
860 | //LLMuteList::getInstance()->add(mute); | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | |||
865 | //static | ||
866 | void LLFloaterMap::onClickEjectFromEstate(void *user_data) | ||
867 | { | ||
868 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
869 | LLStringUtil::format_map_t args; | ||
870 | LLSD payload; | ||
871 | args["EVIL_USER"] = getSelectedName(self->mSelectedAvatar); | ||
872 | gViewerWindow->alertXml("EstateKickUser", args, callbackEjectFromEstate, user_data); | ||
873 | } | ||
874 | |||
875 | //static | ||
876 | void LLFloaterMap::onClickAR(void *user_data) | ||
877 | { | ||
878 | LLFloaterMap *self = (LLFloaterMap*)user_data; | ||
879 | LLUUID agent_id = self->mSelectedAvatar; | ||
880 | |||
881 | if (agent_id.notNull()) | ||
882 | { | ||
883 | LLFloaterReporter::showFromObject(agent_id); | ||
884 | } | ||
885 | } | ||
886 | |||
887 | // static | ||
888 | void LLFloaterMap::cmdEstateEject(const LLUUID &avatar) | ||
889 | { | ||
890 | sendEstateMessage("teleporthomeuser", avatar); | ||
891 | } | ||
892 | |||
893 | // static | ||
894 | void LLFloaterMap::cmdEstateBan(const LLUUID &avatar) | ||
895 | { | ||
896 | sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure | ||
897 | sendEstateBan(avatar); | ||
898 | } | ||
899 | |||
900 | // static | ||
901 | void LLFloaterMap::sendFreeze(const LLUUID& avatar_id, bool freeze) | ||
902 | { | ||
903 | U32 flags = 0x0; | ||
904 | if (!freeze) | ||
905 | { | ||
906 | // unfreeze | ||
907 | flags |= 0x1; | ||
908 | } | ||
909 | |||
910 | LLMessageSystem* msg = gMessageSystem; | ||
911 | LLViewerObject* avatar = gObjectList.findObject(avatar_id); | ||
912 | |||
913 | if (avatar) | ||
914 | { | ||
915 | msg->newMessage("FreezeUser"); | ||
916 | msg->nextBlock("AgentData"); | ||
917 | msg->addUUID("AgentID", gAgent.getID()); | ||
918 | msg->addUUID("SessionID", gAgent.getSessionID()); | ||
919 | msg->nextBlock("Data"); | ||
920 | msg->addUUID("TargetID", avatar_id ); | ||
921 | msg->addU32("Flags", flags ); | ||
922 | msg->sendReliable( avatar->getRegion()->getHost() ); | ||
923 | } | ||
924 | } | ||
925 | |||
926 | // static | ||
927 | void LLFloaterMap::sendEject(const LLUUID& avatar_id, bool ban) | ||
928 | { | ||
929 | LLMessageSystem* msg = gMessageSystem; | ||
930 | LLViewerObject* avatar = gObjectList.findObject(avatar_id); | ||
931 | |||
932 | if (avatar) | ||
933 | { | ||
934 | U32 flags = 0x0; | ||
935 | if ( ban ) | ||
936 | { | ||
937 | // eject and add to ban list | ||
938 | flags |= 0x1; | ||
939 | } | ||
940 | |||
941 | msg->newMessage("EjectUser"); | ||
942 | msg->nextBlock("AgentData"); | ||
943 | msg->addUUID("AgentID", gAgent.getID() ); | ||
944 | msg->addUUID("SessionID", gAgent.getSessionID() ); | ||
945 | msg->nextBlock("Data"); | ||
946 | msg->addUUID("TargetID", avatar_id ); | ||
947 | msg->addU32("Flags", flags ); | ||
948 | msg->sendReliable( avatar->getRegion()->getHost() ); | ||
949 | } | ||
950 | } | ||
951 | |||
952 | // static | ||
953 | void LLFloaterMap::sendEstateMessage(const char* request, const LLUUID &target) | ||
954 | { | ||
955 | |||
956 | LLMessageSystem* msg = gMessageSystem; | ||
957 | LLUUID invoice; | ||
958 | |||
959 | // This seems to provide an ID so that the sim can say which request it's | ||
960 | // replying to. I think this can be ignored for now. | ||
961 | invoice.generate(); | ||
962 | |||
963 | llinfos << "Sending estate request '" << request << "'" << llendl; | ||
964 | msg->newMessage("EstateOwnerMessage"); | ||
965 | msg->nextBlockFast(_PREHASH_AgentData); | ||
966 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
967 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
968 | msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used | ||
969 | msg->nextBlock("MethodData"); | ||
970 | msg->addString("Method", request); | ||
971 | msg->addUUID("Invoice", invoice); | ||
972 | |||
973 | // Agent id | ||
974 | msg->nextBlock("ParamList"); | ||
975 | msg->addString("Parameter", gAgent.getID().asString().c_str()); | ||
976 | |||
977 | // Target | ||
978 | msg->nextBlock("ParamList"); | ||
979 | msg->addString("Parameter", target.asString().c_str()); | ||
980 | |||
981 | msg->sendReliable(gAgent.getRegion()->getHost()); | ||
982 | } | ||
983 | |||
984 | // static | ||
985 | void LLFloaterMap::sendEstateBan(const LLUUID& agent) | ||
986 | { | ||
987 | LLUUID invoice; | ||
988 | U32 flags = ESTATE_ACCESS_BANNED_AGENT_ADD; | ||
989 | |||
990 | invoice.generate(); | ||
991 | |||
992 | LLMessageSystem* msg = gMessageSystem; | ||
993 | msg->newMessage("EstateOwnerMessage"); | ||
994 | msg->nextBlockFast(_PREHASH_AgentData); | ||
995 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
996 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
997 | msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used | ||
998 | |||
999 | msg->nextBlock("MethodData"); | ||
1000 | msg->addString("Method", "estateaccessdelta"); | ||
1001 | msg->addUUID("Invoice", invoice); | ||
1002 | |||
1003 | char buf[MAX_STRING]; /* Flawfinder: ignore*/ | ||
1004 | gAgent.getID().toString(buf); | ||
1005 | msg->nextBlock("ParamList"); | ||
1006 | msg->addString("Parameter", buf); | ||
1007 | |||
1008 | snprintf(buf, MAX_STRING, "%u", flags); /* Flawfinder: ignore */ | ||
1009 | msg->nextBlock("ParamList"); | ||
1010 | msg->addString("Parameter", buf); | ||
1011 | |||
1012 | agent.toString(buf); | ||
1013 | msg->nextBlock("ParamList"); | ||
1014 | msg->addString("Parameter", buf); | ||
1015 | |||
1016 | gAgent.sendReliableMessage(); | ||
1017 | } | ||