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