aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloatermap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llfloatermap.cpp')
-rw-r--r--linden/indra/newview/llfloatermap.cpp624
1 files changed, 622 insertions, 2 deletions
diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp
index 8714d4f..29a95c2 100644
--- a/linden/indra/newview/llfloatermap.cpp
+++ b/linden/indra/newview/llfloatermap.cpp
@@ -42,14 +42,39 @@
42#include "llresizebar.h" 42#include "llresizebar.h"
43#include "lluictrlfactory.h" 43#include "lluictrlfactory.h"
44 44
45// radar
46#include "llfloateravatarinfo.h"
47#include "llfloaterfriends.h"
48#include "llfloatergroupinvite.h"
49#include "llfloatergroups.h"
50#include "llfloaterreporter.h"
51#include "llimview.h"
52#include "llmutelist.h"
53#include "roles_constants.h"
54#include "llscrolllistctrl.h"
55#include "lltracker.h"
56#include "llviewerobjectlist.h"
57#include "llviewermessage.h"
58#include "llviewerregion.h"
59#include "llviewerwindow.h"
60#include "llworld.h"
61
62LLFloaterMap* LLFloaterMap::sInstance = NULL;
63
45LLFloaterMap::LLFloaterMap(const LLSD& key) 64LLFloaterMap::LLFloaterMap(const LLSD& key)
46 : 65 :
47 LLFloater(std::string("minimap")), 66 LLFloater(std::string("minimap")),
48 mPanelMap(NULL) 67 mPanelMap(NULL),
68 mUpdate(TRUE)
49{ 69{
50 LLCallbackMap::map_t factory_map; 70 LLCallbackMap::map_t factory_map;
51 factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this); 71 factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this);
52 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE); 72 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE);
73
74 mSelectedAvatar.setNull();
75 mAvatars.clear();
76
77 sInstance = this;
53} 78}
54 79
55 80
@@ -67,12 +92,37 @@ BOOL LLFloaterMap::postBuild()
67 sendChildToBack(getDragHandle()); 92 sendChildToBack(getDragHandle());
68 sendChildToFront(getChild<LLButton>("llfloater_close_btn")); 93 sendChildToFront(getChild<LLButton>("llfloater_close_btn"));
69 setIsChrome(TRUE); 94 setIsChrome(TRUE);
95
96 mRadarList = getChild<LLScrollListCtrl>("RadarList");
97 childSetCommitCallback("RadarList", onList, this);
98 mRadarList->setDoubleClickCallback(onClickIM);
99
100 childSetFocusChangedCallback("near_me_range", onRangeChange, this);
101
102 childSetAction("im_btn", onClickIM, this);
103 childSetAction("profile_btn", onClickProfile, this);
104 childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
105 childSetAction("track_btn", onClickTrack, this);
106 childSetAction("invite_btn", onClickInvite, this);
107 childSetAction("add_btn", onClickAddFriend, this);
108 childSetAction("freeze_btn", onClickFreeze, this);
109 childSetAction("eject_btn", onClickEject, this);
110 childSetAction("mute_btn", onClickMute, this);
111 childSetAction("unmute_btn", onClickUnmute, this);
112 childSetAction("ar_btn", onClickAR, this);
113 childSetAction("estate_eject_btn", onClickEjectFromEstate, this);
114
115 setDefaultBtn("im_btn");
116
117 populateRadar();
118
70 return TRUE; 119 return TRUE;
71} 120}
72 121
73 122
74LLFloaterMap::~LLFloaterMap() 123LLFloaterMap::~LLFloaterMap()
75{ 124{
125 sInstance = NULL;
76} 126}
77 127
78 128
@@ -122,7 +172,6 @@ void LLFloaterMap::draw()
122 } 172 }
123} 173}
124 174
125
126// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c) 175// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-05 (RLVa-1.0.0c)
127void LLFloaterMap::open() 176void LLFloaterMap::open()
128{ 177{
@@ -132,3 +181,574 @@ void LLFloaterMap::open()
132 } 181 }
133} 182}
134// [/RLVa:KB] 183// [/RLVa:KB]
184
185// TODO: make this detachable
186// TODO: make this expand/collapse
187
188/*
189* Imprudence Radar
190* @brief inworld radar integrated with the minimap
191* by McCabe Maxsted
192* Estate tab portion by Dale Glass
193*/
194
195//static
196void LLFloaterMap::updateRadar()
197{
198 LLFloaterMap* self = sInstance;
199 self->populateRadar();
200}
201
202void LLFloaterMap::populateRadar()
203{
204 if (!mUpdate)
205 {
206 return;
207 }
208
209 if (visibleItemsSelected())
210 {
211 mSelectedAvatar = mRadarList->getSelectedValue().asUUID();
212 }
213 else
214 {
215 mSelectedAvatar.setNull();
216 }
217
218 S32 scroll_pos = mRadarList->getScrollPos();
219
220 LLVector3d current_pos = gAgent.getPositionGlobal();
221
222 // find what avatars you can see
223 std::vector<LLUUID> avatar_ids;
224 std::vector<LLVector3d> positions;
225 LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, current_pos, gSavedSettings.getF32("NearMeRange"));
226
227 // Add avatars to the list. If they're already there, update positions
228 std::pair<std::map<LLUUID, LLVector3d>::iterator, bool> ret;
229 for (U32 i=0; i<avatar_ids.size(); i++)
230 {
231 if (avatar_ids[i] == gAgent.getID() ||
232 avatar_ids[i].isNull())
233 {
234 continue;
235 }
236
237 ret = mAvatars.insert(std::pair<LLUUID, LLVector3d>(avatar_ids[i], positions[i]));
238 if (ret.second == false)
239 {
240 mAvatars[avatar_ids[i]] = positions[i];
241 }
242 }
243
244 LLSD element;
245
246 mRadarList->deleteAllItems();
247
248 // if an avatar's not in range anymore, kill it. Otherwise, populate radar
249 std::map<LLUUID, LLVector3d>::iterator mIt;
250 std::vector<LLUUID>::iterator result;
251 for (mIt = mAvatars.begin(); mIt != mAvatars.end(); )
252 {
253 result = find(avatar_ids.begin(), avatar_ids.end(), mIt->first);
254 if (result == avatar_ids.end())
255 {
256 mAvatars.erase(mIt++);
257 }
258 else
259 {
260 // Add to list only if we get their name
261 std::string fullname = getSelectedName(mIt->first);
262 if (!fullname.empty() && fullname != " ")
263 {
264 std::string mute_text = LLMuteList::getInstance()->isMuted(mIt->first) ? getString("muted") : "";
265 element["id"] = mIt->first;
266 element["columns"][0]["column"] = "avatar_name";
267 element["columns"][0]["type"] = "text";
268 element["columns"][0]["value"] = fullname + " " + mute_text;
269 element["columns"][1]["column"] = "avatar_distance";
270 element["columns"][1]["type"] = "text";
271
272 F64 distance = dist_vec(current_pos, mIt->second);
273 std::stringstream dist_formatted;
274 dist_formatted.str("");
275 dist_formatted << (double)((int)((distance + 0.05)*10.0))/10.0 << "m";
276 element["columns"][1]["value"] = dist_formatted.str();
277
278 mRadarList->addElement(element, ADD_BOTTOM);
279 }
280 ++mIt;
281 }
282 }
283
284 mRadarList->sortItems();
285 mRadarList->setScrollPos(scroll_pos);
286
287 if (mSelectedAvatar.notNull())
288 {
289 mRadarList->selectByID(mSelectedAvatar);
290 }
291
292 // set count
293 std::stringstream avatar_count;
294 avatar_count.str("");
295 if (mAvatars.empty())
296 {
297 mRadarList->addCommentText(getString("no_one_near"), ADD_TOP);
298 avatar_count << "0";
299 }
300 else
301 {
302 avatar_count << (int)mAvatars.size();
303 }
304 childSetText("lblAvatarCount", avatar_count.str());
305
306 toggleButtons();
307}
308
309void LLFloaterMap::toggleButtons()
310{
311 BOOL enabled = mRadarList->hasFocus() ? visibleItemsSelected() : FALSE;
312 BOOL unmute_enabled = mRadarList->hasFocus() ? LLMuteList::getInstance()->isMuted(mSelectedAvatar) : FALSE;
313
314 childSetEnabled("im_btn", enabled);
315 childSetEnabled("profile_btn", enabled);
316 childSetEnabled("offer_teleport_btn", enabled);
317 childSetEnabled("track_btn", enabled);
318 childSetEnabled("invite_btn", enabled);
319 childSetEnabled("add_btn", enabled);
320 childSetEnabled("freeze_btn", enabled);
321 childSetEnabled("eject_btn", enabled);
322 childSetEnabled("mute_btn", enabled);
323 childSetEnabled("unmute_btn", unmute_enabled);
324 childSetEnabled("ar_btn", enabled);
325 childSetEnabled("estate_eject_btn", enabled);
326}
327
328// static
329void LLFloaterMap::onList(LLUICtrl* ctrl, void* user_data)
330{
331 LLFloaterMap* self = (LLFloaterMap*)user_data;
332 if (self)
333 {
334 self->toggleButtons();
335 }
336}
337
338
339BOOL LLFloaterMap::visibleItemsSelected() const
340{
341 if (mRadarList->getFirstSelectedIndex() >= 0)
342 {
343 return TRUE;
344 }
345 return FALSE;
346}
347
348// static
349void LLFloaterMap::onRangeChange(LLFocusableElement* focus, void* user_data)
350{
351 LLFloaterMap* self = (LLFloaterMap*)user_data;
352 if (self)
353 {
354 self->mUpdate = !(self->childHasFocus("near_me_range"));
355 }
356}
357
358// static
359BOOL LLFloaterMap::isSelected(LLUUID agent)
360{
361 if (sInstance->mSelectedAvatar == agent)
362 {
363 return TRUE;
364 }
365 return FALSE;
366}
367
368//
369// Avatar tab
370//
371
372// static
373void LLFloaterMap::onClickIM(void* user_data)
374{
375 LLFloaterMap* self = (LLFloaterMap*) user_data;
376 LLScrollListItem *item = self->mRadarList->getFirstSelected();
377 if (item != NULL)
378 {
379 LLUUID agent_id = item->getUUID();
380 std::string fullname;
381 if(gCacheName->getFullName(agent_id, fullname))
382 {
383 gIMMgr->setFloaterOpen(TRUE);
384 gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id);
385 }
386 }
387}
388
389// static
390void LLFloaterMap::onClickProfile(void* user_data)
391{
392 LLFloaterMap* self = (LLFloaterMap*) user_data;
393 LLScrollListItem *item = self->mRadarList->getFirstSelected();
394 if (item != NULL)
395 {
396 LLUUID agent_id = item->getUUID();
397 LLFloaterAvatarInfo::show(agent_id);
398 }
399}
400
401// static
402void LLFloaterMap::onClickOfferTeleport(void* user_data)
403{
404 LLFloaterMap* self = (LLFloaterMap*) user_data;
405 LLScrollListItem *item = self->mRadarList->getFirstSelected();
406 if (item != NULL)
407 {
408 LLUUID agent_id = item->getUUID();
409 handle_lure(agent_id);
410 }
411}
412
413// static
414void LLFloaterMap::onClickTrack(void* user_data)
415{
416 LLFloaterMap* self = (LLFloaterMap*) user_data;
417 LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
418 if (LLTracker::TRACKING_AVATAR == tracking_status)
419 {
420 LLTracker::stopTracking(NULL);
421 }
422 else
423 {
424 LLScrollListItem *item = self->mRadarList->getFirstSelected();
425 if (item != NULL)
426 {
427 LLUUID agent_id = item->getUUID();
428 std::string fullname;
429 gCacheName->getFullName(agent_id, fullname);
430 LLTracker::trackAvatar(agent_id, fullname);
431 }
432 }
433}
434
435// static
436void LLFloaterMap::onClickInvite(void* user_data)
437{
438 LLFloaterMap* self = (LLFloaterMap*) user_data;
439 LLScrollListItem *item = self->mRadarList->getFirstSelected();
440 if (item != NULL)
441 {
442 LLUUID agent_id = item->getUUID();
443 LLFloaterGroupPicker* widget;
444 widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
445 if (widget)
446 {
447 widget->center();
448 widget->setPowersMask(GP_MEMBER_INVITE);
449 widget->setSelectCallback(callback_invite_to_group, (void *)&agent_id);
450 }
451 }
452}
453
454// static
455void LLFloaterMap::callback_invite_to_group(LLUUID group_id, void *user_data)
456{
457 std::vector<LLUUID> agent_ids;
458 agent_ids.push_back(*(LLUUID *)user_data);
459
460 LLFloaterGroupInvite::showForGroup(group_id, &agent_ids);
461}
462
463// static
464void LLFloaterMap::onClickAddFriend(void* user_data)
465{
466 LLFloaterMap* self = (LLFloaterMap*) user_data;
467 LLScrollListItem *item = self->mRadarList->getFirstSelected();
468 if (item != NULL)
469 {
470 LLUUID agent_id = item->getUUID();
471 std::string fullname;
472 gCacheName->getFullName(agent_id, fullname);
473 LLPanelFriends::requestFriendshipDialog(agent_id, fullname);
474 }
475}
476
477//
478// Estate tab
479//
480
481//static
482std::string LLFloaterMap::getSelectedName(LLUUID agent_id)
483{
484 std::string agent_name;
485 if(agent_id.notNull() && gCacheName->getFullName(agent_id, agent_name))
486 {
487 return agent_name;
488 }
489 return LLStringUtil::null;
490}
491
492//static
493void LLFloaterMap::callbackFreeze(S32 option, void *user_data)
494{
495 LLFloaterMap *self = (LLFloaterMap*)user_data;
496
497 if ( option == 0 )
498 {
499 sendFreeze(self->mSelectedAvatar, true);
500 }
501 else if ( option == 1 )
502 {
503 sendFreeze(self->mSelectedAvatar, false);
504 }
505}
506
507//static
508void LLFloaterMap::callbackEject(S32 option, void *user_data)
509{
510 LLFloaterMap *self = (LLFloaterMap*)user_data;
511
512 if ( option == 0 )
513 {
514 sendEject(self->mSelectedAvatar, false);
515 }
516 else if ( option == 1 )
517 {
518 sendEject(self->mSelectedAvatar, true);
519 }
520}
521
522//static
523void LLFloaterMap::callbackEjectFromEstate(S32 option, void *user_data)
524{
525 LLFloaterMap *self = (LLFloaterMap*)user_data;
526
527 if ( option == 0 )
528 {
529 cmdEstateEject(self->mSelectedAvatar);
530 }
531 else if ( option == 1 )
532 {
533 cmdEstateBan(self->mSelectedAvatar);
534 }
535}
536
537void LLFloaterMap::onClickFreeze(void *user_data)
538{
539 LLFloaterMap *self = (LLFloaterMap*)user_data;
540 LLStringUtil::format_map_t args;
541 LLSD payload;
542 args["[AVATAR_NAME]"] = self->getSelectedName(self->mSelectedAvatar);
543 gViewerWindow->alertXml("FreezeAvatarFullname", args, callbackFreeze, user_data);
544}
545
546//static
547void LLFloaterMap::onClickEject(void *user_data)
548{
549 LLFloaterMap *self = (LLFloaterMap*)user_data;
550 LLStringUtil::format_map_t args;
551 LLSD payload;
552 args["AVATAR_NAME"] = self->getSelectedName(self->mSelectedAvatar);
553 gViewerWindow->alertXml("EjectAvatarFullName", args, callbackEject, user_data);
554}
555
556//static
557void LLFloaterMap::onClickMute(void *user_data)
558{
559 LLFloaterMap *self = (LLFloaterMap*)user_data;
560
561 LLUUID agent_id = self->mSelectedAvatar;
562 std::string agent_name = self->getSelectedName(agent_id);
563 if(!agent_name.empty())
564 {
565 if (LLMuteList::getInstance()->isMuted(agent_id))
566 {
567 //LLMute mute(agent_id, agent_name, LLMute::AGENT);
568 //LLMuteList::getInstance()->remove(mute);
569 //LLFloaterMute::getInstance()->selectMute(agent_id);
570 }
571 else
572 {
573 LLMute mute(agent_id, agent_name, LLMute::AGENT);
574 LLMuteList::getInstance()->add(mute);
575 }
576 }
577}
578
579//static
580void LLFloaterMap::onClickUnmute(void *user_data)
581{
582 LLFloaterMap *self = (LLFloaterMap*)user_data;
583
584 LLUUID agent_id = self->mSelectedAvatar;
585 std::string agent_name = self->getSelectedName(agent_id);
586 if(!agent_name.empty())
587 {
588 if (LLMuteList::getInstance()->isMuted(agent_id))
589 {
590 LLMute mute(agent_id, agent_name, LLMute::AGENT);
591 LLMuteList::getInstance()->remove(mute);
592 //LLFloaterMute::getInstance()->selectMute(agent_id);
593 }
594 else
595 {
596 //LLMute mute(agent_id, agent_name, LLMute::AGENT);
597 //LLMuteList::getInstance()->add(mute);
598 }
599 }
600}
601
602//static
603void LLFloaterMap::onClickEjectFromEstate(void *user_data)
604{
605 LLFloaterMap *self = (LLFloaterMap*)user_data;
606 LLStringUtil::format_map_t args;
607 LLSD payload;
608 args["EVIL_USER"] = self->getSelectedName(self->mSelectedAvatar);
609 gViewerWindow->alertXml("EstateKickUser", args, callbackEjectFromEstate, user_data);
610}
611
612//static
613void LLFloaterMap::onClickAR(void *user_data)
614{
615 LLFloaterMap *self = (LLFloaterMap*)user_data;
616 LLUUID agent_id = self->mSelectedAvatar;
617
618 if (agent_id.notNull())
619 {
620 LLFloaterReporter::showFromObject(agent_id);
621 }
622}
623
624// static
625void LLFloaterMap::cmdEstateEject(const LLUUID &avatar)
626{
627 sendEstateMessage("teleporthomeuser", avatar);
628}
629
630// static
631void LLFloaterMap::cmdEstateBan(const LLUUID &avatar)
632{
633 sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure
634 sendEstateBan(avatar);
635}
636
637// static
638void LLFloaterMap::sendFreeze(const LLUUID& avatar_id, bool freeze)
639{
640 U32 flags = 0x0;
641 if (!freeze)
642 {
643 // unfreeze
644 flags |= 0x1;
645 }
646
647 LLMessageSystem* msg = gMessageSystem;
648 LLViewerObject* avatar = gObjectList.findObject(avatar_id);
649
650 if (avatar)
651 {
652 msg->newMessage("FreezeUser");
653 msg->nextBlock("AgentData");
654 msg->addUUID("AgentID", gAgent.getID());
655 msg->addUUID("SessionID", gAgent.getSessionID());
656 msg->nextBlock("Data");
657 msg->addUUID("TargetID", avatar_id );
658 msg->addU32("Flags", flags );
659 msg->sendReliable( avatar->getRegion()->getHost() );
660 }
661}
662
663// static
664void LLFloaterMap::sendEject(const LLUUID& avatar_id, bool ban)
665{
666 LLMessageSystem* msg = gMessageSystem;
667 LLViewerObject* avatar = gObjectList.findObject(avatar_id);
668
669 if (avatar)
670 {
671 U32 flags = 0x0;
672 if ( ban )
673 {
674 // eject and add to ban list
675 flags |= 0x1;
676 }
677
678 msg->newMessage("EjectUser");
679 msg->nextBlock("AgentData");
680 msg->addUUID("AgentID", gAgent.getID() );
681 msg->addUUID("SessionID", gAgent.getSessionID() );
682 msg->nextBlock("Data");
683 msg->addUUID("TargetID", avatar_id );
684 msg->addU32("Flags", flags );
685 msg->sendReliable( avatar->getRegion()->getHost() );
686 }
687}
688
689// static
690void LLFloaterMap::sendEstateMessage(const char* request, const LLUUID &target)
691{
692
693 LLMessageSystem* msg = gMessageSystem;
694 LLUUID invoice;
695
696 // This seems to provide an ID so that the sim can say which request it's
697 // replying to. I think this can be ignored for now.
698 invoice.generate();
699
700 llinfos << "Sending estate request '" << request << "'" << llendl;
701 msg->newMessage("EstateOwnerMessage");
702 msg->nextBlockFast(_PREHASH_AgentData);
703 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
704 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
705 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
706 msg->nextBlock("MethodData");
707 msg->addString("Method", request);
708 msg->addUUID("Invoice", invoice);
709
710 // Agent id
711 msg->nextBlock("ParamList");
712 msg->addString("Parameter", gAgent.getID().asString().c_str());
713
714 // Target
715 msg->nextBlock("ParamList");
716 msg->addString("Parameter", target.asString().c_str());
717
718 msg->sendReliable(gAgent.getRegion()->getHost());
719}
720
721// static
722void LLFloaterMap::sendEstateBan(const LLUUID& agent)
723{
724 LLUUID invoice;
725 U32 flags = ESTATE_ACCESS_BANNED_AGENT_ADD;
726
727 invoice.generate();
728
729 LLMessageSystem* msg = gMessageSystem;
730 msg->newMessage("EstateOwnerMessage");
731 msg->nextBlockFast(_PREHASH_AgentData);
732 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
733 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
734 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
735
736 msg->nextBlock("MethodData");
737 msg->addString("Method", "estateaccessdelta");
738 msg->addUUID("Invoice", invoice);
739
740 char buf[MAX_STRING]; /* Flawfinder: ignore*/
741 gAgent.getID().toString(buf);
742 msg->nextBlock("ParamList");
743 msg->addString("Parameter", buf);
744
745 snprintf(buf, MAX_STRING, "%u", flags); /* Flawfinder: ignore */
746 msg->nextBlock("ParamList");
747 msg->addString("Parameter", buf);
748
749 agent.toString(buf);
750 msg->nextBlock("ParamList");
751 msg->addString("Parameter", buf);
752
753 gAgent.sendReliableMessage();
754}