diff options
-rw-r--r-- | ChangeLog.txt | 13 | ||||
-rw-r--r-- | linden/indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermap.cpp | 903 | ||||
-rw-r--r-- | linden/indra/newview/llfloatermap.h | 78 | ||||
-rw-r--r-- | linden/indra/newview/llnetmap.cpp | 7 | ||||
-rw-r--r-- | linden/indra/newview/llviewermessage.cpp | 6 | ||||
-rw-r--r-- | linden/indra/newview/panelradar.cpp | 968 | ||||
-rw-r--r-- | linden/indra/newview/panelradar.h | 114 |
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 @@ | |||
1 | 2009-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 | |||
1 | 2009-10-26 Jacek Antonelli <jacek.antonelli@gmail.com> | 14 | 2009-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 | ||
70 | LLFloaterMap::LLFloaterMap(const LLSD& key) | 48 | LLFloaterMap::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 | ||
70 | void* LLFloaterMap::createPanelRadar(void* data) | ||
71 | { | ||
72 | LLFloaterMap* self = (LLFloaterMap*)data; | ||
73 | self->mPanelRadar = new PanelRadar(); | ||
74 | return self->mPanelRadar; | ||
75 | } | ||
76 | |||
77 | |||
95 | BOOL LLFloaterMap::postBuild() | 78 | BOOL 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 | ||
203 | bool 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 | ||
218 | void LLFloaterMap::updateRadar() | ||
219 | { | ||
220 | LLFloaterMap::getInstance()->populateRadar(); | ||
221 | } | ||
222 | |||
223 | void 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 | |||
395 | void 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 | |||
413 | bool LLFloaterMap::isInChatList(LLUUID agent_id) | ||
414 | { | ||
415 | if (mChatAvatars.count(agent_id) > 0) | ||
416 | { | ||
417 | return true; | ||
418 | } | ||
419 | return false; | ||
420 | } | ||
421 | |||
422 | void 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 | |||
436 | void LLFloaterMap::removeFromChatList(LLUUID agent_id) | ||
437 | { | ||
438 | // Do we want to add a notice? | ||
439 | mChatAvatars.erase(agent_id); | ||
440 | } | ||
441 | |||
442 | bool LLFloaterMap::isTyping(LLUUID agent_id) | ||
443 | { | ||
444 | if (mTypingAvatars.count(agent_id) > 0) | ||
445 | { | ||
446 | return true; | ||
447 | } | ||
448 | return false; | ||
449 | } | ||
450 | |||
451 | void 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 | |||
466 | void 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 | |||
484 | void 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 | |||
498 | bool LLFloaterMap::getInSimAvList(LLUUID agent_id) | ||
499 | { | ||
500 | if (mSimAvatars.count(agent_id) > 0) | ||
501 | { | ||
502 | return true; | ||
503 | } | ||
504 | return false; | ||
505 | } | ||
506 | |||
507 | void 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 | |||
579 | BOOL 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 | ||
616 | void LLFloaterMap::onList(LLUICtrl* ctrl, void* user_data) | ||
617 | { | ||
618 | LLFloaterMap* self = (LLFloaterMap*)user_data; | ||
619 | if (self) | ||
620 | { | ||
621 | self->toggleButtons(); | ||
622 | } | ||
623 | } | ||
624 | |||
625 | BOOL LLFloaterMap::visibleItemsSelected() const | ||
626 | { | ||
627 | if (mRadarList->getFirstSelectedIndex() >= 0) | ||
628 | { | ||
629 | return TRUE; | ||
630 | } | ||
631 | return FALSE; | ||
632 | } | ||
633 | |||
634 | // static | ||
635 | void 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 | ||
645 | LLUUID LLFloaterMap::getSelected() | ||
646 | { | ||
647 | return LLFloaterMap::getInstance()->mSelectedAvatar; | ||
648 | } | ||
649 | |||
650 | // | ||
651 | // Avatar tab | ||
652 | // | ||
653 | |||
654 | // static | ||
655 | void 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 | ||
668 | void 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 | ||
680 | void 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 | ||
692 | void 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 | ||
713 | void 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 | ||
732 | void 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 | ||
741 | void 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 | ||
757 | std::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 | ||
768 | void 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 | ||
783 | void 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 | ||
798 | void 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 | |||
812 | void 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 | ||
822 | void 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 | ||
832 | void 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 | ||
855 | void 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 | 153 | PanelRadar* LLFloaterMap::getRadar() |
878 | void 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 | ||
888 | void 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 | ||
900 | void LLFloaterMap::cmdEstateEject(const LLUUID &avatar) | ||
901 | { | ||
902 | sendEstateMessage("teleporthomeuser", avatar); | ||
903 | } | ||
904 | |||
905 | // static | ||
906 | void LLFloaterMap::cmdEstateBan(const LLUUID &avatar) | ||
907 | { | ||
908 | sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure | ||
909 | sendEstateBan(avatar); | ||
910 | } | ||
911 | |||
912 | // static | ||
913 | void 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 | ||
939 | void 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 | ||
965 | void 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 | ||
997 | void 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 | ||
38 | class LLNetMap; | 38 | class 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 | ||
69 | private: | 63 | private: |
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 | ||
520 | void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) | 521 | void 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 | |||
58 | PanelRadar::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 | |||
70 | BOOL 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 | |||
99 | PanelRadar::~PanelRadar() | ||
100 | { | ||
101 | } | ||
102 | |||
103 | |||
104 | //static | ||
105 | bool 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 | |||
120 | void 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 | |||
293 | void 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 | |||
312 | bool PanelRadar::isInChatList(LLUUID agent_id) | ||
313 | { | ||
314 | if (mChatAvatars.count(agent_id) > 0) | ||
315 | { | ||
316 | return true; | ||
317 | } | ||
318 | return false; | ||
319 | } | ||
320 | |||
321 | |||
322 | void 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 | |||
337 | void PanelRadar::removeFromChatList(LLUUID agent_id) | ||
338 | { | ||
339 | // Do we want to add a notice? | ||
340 | mChatAvatars.erase(agent_id); | ||
341 | } | ||
342 | |||
343 | |||
344 | bool PanelRadar::isTyping(LLUUID agent_id) | ||
345 | { | ||
346 | if (mTypingAvatars.count(agent_id) > 0) | ||
347 | { | ||
348 | return true; | ||
349 | } | ||
350 | return false; | ||
351 | } | ||
352 | |||
353 | |||
354 | void 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 | |||
370 | void 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 | |||
389 | void 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 | |||
404 | bool PanelRadar::getInSimAvList(LLUUID agent_id) | ||
405 | { | ||
406 | if (mSimAvatars.count(agent_id) > 0) | ||
407 | { | ||
408 | return true; | ||
409 | } | ||
410 | return false; | ||
411 | } | ||
412 | |||
413 | |||
414 | void 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 | |||
490 | BOOL 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 | ||
528 | void 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 | |||
538 | BOOL PanelRadar::visibleItemsSelected() const | ||
539 | { | ||
540 | if (mRadarList->getFirstSelectedIndex() >= 0) | ||
541 | { | ||
542 | return TRUE; | ||
543 | } | ||
544 | return FALSE; | ||
545 | } | ||
546 | |||
547 | |||
548 | // static | ||
549 | void 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 | |||
559 | LLUUID PanelRadar::getSelected() | ||
560 | { | ||
561 | return mSelectedAvatar; | ||
562 | } | ||
563 | |||
564 | |||
565 | |||
566 | // | ||
567 | // Avatar tab | ||
568 | // | ||
569 | |||
570 | // static | ||
571 | void 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 | ||
585 | void 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 | ||
598 | void 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 | ||
611 | void 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 | ||
633 | void 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 | ||
653 | void 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 | ||
663 | void 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 | ||
681 | std::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 | ||
693 | void 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 | ||
709 | void 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 | ||
725 | void 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 | |||
740 | void 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 | ||
751 | void 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 | ||
762 | void 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 | ||
786 | void 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 | ||
810 | void 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 | ||
821 | void 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 | ||
834 | void PanelRadar::cmdEstateEject(const LLUUID &avatar) | ||
835 | { | ||
836 | sendEstateMessage("teleporthomeuser", avatar); | ||
837 | } | ||
838 | |||
839 | |||
840 | // static | ||
841 | void PanelRadar::cmdEstateBan(const LLUUID &avatar) | ||
842 | { | ||
843 | sendEstateMessage("teleporthomeuser", avatar); // Kick first, just to be sure | ||
844 | sendEstateBan(avatar); | ||
845 | } | ||
846 | |||
847 | |||
848 | // static | ||
849 | void 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 | ||
876 | void 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 | ||
903 | void 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 | ||
936 | void 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 | |||
37 | class PanelRadar : public LLPanel | ||
38 | { | ||
39 | public: | ||
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 | |||
79 | private: | ||
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 | |||