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