00001 
00033 
00034 
00035 
00036 
00037 
00038 #include "llviewerprecompiledheaders.h"
00039 
00040 #include "llfloaterworldmap.h"
00041 
00042 
00043 #include "llfontgl.h"
00044 #include "llinventory.h"
00045 #include "lllineeditor.h"
00046 #include "message.h"
00047 
00048 
00049 #include "llagent.h"
00050 #include "llviewerwindow.h"
00051 #include "llbutton.h"
00052 #include "llcallingcard.h"
00053 #include "llcolorscheme.h"
00054 #include "llcombobox.h"
00055 #include "llviewercontrol.h"
00056 #include "lldraghandle.h"
00057 #include "lleconomy.h"
00058 #include "llfirstuse.h"
00059 #include "llfocusmgr.h"
00060 #include "lliconctrl.h"
00061 #include "llinventorymodel.h"
00062 #include "llinventoryview.h"
00063 #include "lllandmarklist.h"
00064 #include "llnetmap.h"
00065 #include "llpreviewlandmark.h"
00066 #include "llradiogroup.h"
00067 #include "llregionhandle.h"
00068 #include "llresizehandle.h"
00069 #include "llresmgr.h"
00070 #include "llscrolllistctrl.h"
00071 #include "llsliderctrl.h"
00072 #include "llspinctrl.h"
00073 #include "llstatusbar.h"
00074 #include "lltabcontainer.h"
00075 #include "lltextbox.h"
00076 #include "lltracker.h"
00077 #include "llui.h"
00078 #include "lluiconstants.h"
00079 #include "llviewercamera.h"
00080 #include "llviewermenu.h"
00081 #include "llviewerregion.h"
00082 #include "llviewerstats.h"
00083 #include "llworldmap.h"
00084 #include "llworldmapview.h"
00085 #include "llurl.h"
00086 #include "llvieweruictrlfactory.h"
00087 #include "viewer.h"
00088 #include "llmapimagetype.h"
00089 #include "llweb.h"
00090 
00091 #include "llglheaders.h"
00092 
00093 
00094 
00095 
00096 static const F32 MAP_ZOOM_TIME = 0.2f;
00097 
00098 enum EPanDirection
00099 {
00100         PAN_UP,
00101         PAN_DOWN,
00102         PAN_LEFT,
00103         PAN_RIGHT
00104 };
00105 
00106 
00107 static const F32 ZOOM_MIN = -8.f;       
00108 static const F32 ZOOM_MAX = 0.f;
00109 static const F32 ZOOM_INC = 0.2f;
00110 
00111 static const F32 SIM_COORD_MIN   = 0.f;
00112 static const F32 SIM_COORD_MAX   = 255.f;
00113 static const F32 SIM_COORD_DEFAULT = 128.f;
00114 
00115 static const F64 MAX_FLY_DISTANCE = 363.f;  
00116 static const F64 MAX_FLY_DISTANCE_SQUARED = MAX_FLY_DISTANCE * MAX_FLY_DISTANCE;
00117 
00118 
00119 
00120 
00121 
00122 LLFloaterWorldMap* gFloaterWorldMap = NULL;
00123 
00124 class LLMapInventoryObserver : public LLInventoryObserver
00125 {
00126 public:
00127         LLMapInventoryObserver() {}
00128         virtual ~LLMapInventoryObserver() {}
00129         virtual void changed(U32 mask);
00130 };
00131   
00132 void LLMapInventoryObserver::changed(U32 mask)
00133 {
00134         
00135         if((mask & (LLInventoryObserver::CALLING_CARD | LLInventoryObserver::ADD |
00136                                 LLInventoryObserver::REMOVE)) != 0)
00137         {
00138                 gFloaterWorldMap->inventoryChanged();
00139         }
00140 }
00141 
00142 class LLMapFriendObserver : public LLFriendObserver
00143 {
00144 public:
00145         LLMapFriendObserver() {}
00146         virtual ~LLMapFriendObserver() {}
00147         virtual void changed(U32 mask);
00148 };
00149 
00150 void LLMapFriendObserver::changed(U32 mask)
00151 {
00152         
00153         if((mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE | LLFriendObserver::POWERS)) != 0)
00154         {
00155                 gFloaterWorldMap->friendsChanged();
00156         }
00157 }
00158 
00159 
00160 
00161 
00162 
00163 
00164 const LLUUID LLFloaterWorldMap::sHomeID( "10000000-0000-0000-0000-000000000001" );
00165 
00166 
00167 
00168 
00169 
00170 
00171 LLFloaterWorldMap::LLFloaterWorldMap()
00172 :       LLFloater("worldmap", "FloaterWorldMapRect", "World Map",
00173                           TRUE,         
00174                           410,          
00175                           520,          
00176                           FALSE,        
00177                           TRUE,         
00178                           TRUE),        
00179         mInventory(NULL),
00180         mInventoryObserver(NULL),
00181         mFriendObserver(NULL),
00182         mCompletingRegionName(""),
00183         mWaitingForTracker(FALSE),
00184         mExactMatch(FALSE),
00185         mIsClosing(FALSE),
00186         mSetToUserPosition(TRUE),
00187         mTrackedLocation(0,0,0),
00188         mTrackedStatus(LLTracker::TRACKING_NOTHING)
00189 {
00190         LLCallbackMap::map_t factory_map;
00191         factory_map["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
00192         factory_map["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL);
00193         gUICtrlFactory->buildFloater(this, "floater_world_map.xml", &factory_map);
00194 }
00195 
00196 
00197 void* LLFloaterWorldMap::createWorldMapView(void* data)
00198 {
00199         return new LLWorldMapView("mapview", LLRect(0,300,400,0));
00200 }
00201 
00202 BOOL LLFloaterWorldMap::postBuild()
00203 {
00204         mTabs = LLUICtrlFactory::getTabContainerByName(this, "maptab");
00205         if (!mTabs) return FALSE;
00206 
00207         LLPanel *panel;
00208 
00209         panel = LLUICtrlFactory::getPanelByName(mTabs, "objects_mapview");
00210         if (panel)
00211         {
00212                 mTabs->setTabChangeCallback(panel, onCommitBackground);
00213                 mTabs->setTabUserData(panel, this);
00214         }
00215         panel = LLUICtrlFactory::getPanelByName(mTabs, "terrain_mapview");
00216         if (panel)
00217         {
00218                 mTabs->setTabChangeCallback(panel, onCommitBackground);
00219                 mTabs->setTabUserData(panel, this);
00220         }
00221 
00222         onCommitBackground((void*)this, false);
00223 
00224         childSetCommitCallback("friend combo", onAvatarComboCommit, this);
00225 
00226         LLComboBox *avatar_combo = LLUICtrlFactory::getComboBoxByName(this, "friend combo");
00227         if (avatar_combo)
00228         {
00229                 avatar_combo->selectFirstItem();
00230                 avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange );
00231         }
00232 
00233         childSetAction("DoSearch", onLocationCommit, this);
00234 
00235         childSetFocusChangedCallback("location", updateSearchEnabled);
00236         childSetKeystrokeCallback("location", (void (*)(LLLineEditor*,void*))updateSearchEnabled, NULL);
00237         
00238         childSetCommitCallback("search_results", onCommitSearchResult, this);
00239         childSetDoubleClickCallback("search_results", onClickTeleportBtn);
00240         childSetCommitCallback("spin x", onCommitLocation, this);
00241         childSetCommitCallback("spin y", onCommitLocation, this);
00242         childSetCommitCallback("spin z", onCommitLocation, this);
00243 
00244         childSetCommitCallback("landmark combo", onLandmarkComboCommit, this);
00245 
00246         LLComboBox *landmark_combo = LLUICtrlFactory::getComboBoxByName(this, "landmark combo");
00247         if (landmark_combo)
00248         {
00249                 landmark_combo->selectFirstItem();
00250                 landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange );
00251         }
00252 
00253         childSetAction("Go Home", onGoHome, this);
00254 
00255         childSetAction("Teleport", onClickTeleportBtn, this);
00256 
00257         childSetAction("Show Destination", onShowTargetBtn, this);
00258         childSetAction("Show My Location", onShowAgentBtn, this);
00259         childSetAction("Clear", onClearBtn, this);
00260         childSetAction("copy_slurl", onCopySLURL, this);
00261 
00262         mCurZoomVal = log(gMapScale)/log(2.f);
00263         childSetValue("zoom slider", gMapScale);
00264 
00265         setDefaultBtn(NULL);
00266 
00267         if ( gAgent.isTeen() )
00268         {
00269                 
00270                 childHide("events_mature_icon");
00271                 childHide("events_mature_label");
00272                 childHide("event_mature_chk");
00273         }
00274 
00275         mZoomTimer.stop();
00276 
00277         return TRUE;
00278 }
00279 
00280 
00281 LLFloaterWorldMap::~LLFloaterWorldMap()
00282 {
00283         
00284         mTabs = NULL;
00285 
00286         
00287         mInventory = NULL;
00288         mInventoryObserver = NULL;
00289 
00290         
00291         mFriendObserver = NULL;
00292 }
00293 
00294 
00295 
00296 void LLFloaterWorldMap::onClose(bool app_quitting)
00297 {
00298         setVisible(FALSE);
00299 }
00300 
00301 
00302 void LLFloaterWorldMap::show(void*, BOOL center_on_target)
00303 {
00304         BOOL was_visible = gFloaterWorldMap->getVisible();
00305 
00306         gFloaterWorldMap->mIsClosing = FALSE;
00307         gFloaterWorldMap->open();               
00308 
00309         LLWorldMapView* map_panel;
00310         map_panel = (LLWorldMapView*)gFloaterWorldMap->mTabs->getCurrentPanel();
00311         map_panel->clearLastClick();
00312 
00313         if (!was_visible)
00314         {
00315                 
00316                 if (!center_on_target)
00317                 {
00318                         LLWorldMapView::setPan(0, 0, TRUE);
00319                 }
00320                 map_panel->updateVisibleBlocks();
00321 
00322                 
00323                 gWorldMap->eraseItems();
00324 
00325                 
00326                 gWorldMap->clearSimFlags();
00327 
00328                 const S32 panel_num = gFloaterWorldMap->mTabs->getCurrentPanelIndex();
00329                 const bool request_from_sim = true;
00330                 gWorldMap->setCurrentLayer(panel_num, request_from_sim);
00331 
00332                 
00333                 
00334                 gFloaterWorldMap->adjustZoomSliderBounds();
00335 
00336                 
00337                 LLFirstUse::useMap();
00338 
00339                 
00340                 LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
00341                 gInventory.startBackgroundFetch(landmark_folder_id);
00342 
00343                 gFloaterWorldMap->childSetFocus("location", TRUE);
00344                 gFocusMgr.triggerFocusFlash();
00345 
00346                 gFloaterWorldMap->buildAvatarIDList();
00347                 gFloaterWorldMap->buildLandmarkIDLists();
00348 
00349                 
00350                 gFloaterWorldMap->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
00351         }
00352         
00353         if (center_on_target)
00354         {
00355                 gFloaterWorldMap->centerOnTarget(FALSE);
00356         }
00357 }
00358 
00359 
00360 
00361 
00362 void LLFloaterWorldMap::reloadIcons(void*)
00363 {
00364         gWorldMap->eraseItems();
00365 
00366         gWorldMap->sendMapLayerRequest();
00367 }
00368 
00369 
00370 
00371 void LLFloaterWorldMap::toggle(void*)
00372 {
00373         BOOL visible = gFloaterWorldMap->getVisible();
00374 
00375         if (!visible)
00376         {
00377                 show(NULL, FALSE);
00378         }
00379         else
00380         {
00381                 gFloaterWorldMap->mIsClosing = TRUE;
00382                 gFloaterWorldMap->close();
00383         }
00384 }
00385 
00386 
00387 
00388 void LLFloaterWorldMap::hide(void*)
00389 {
00390         gFloaterWorldMap->mIsClosing = TRUE;
00391         gFloaterWorldMap->close();
00392 }
00393 
00394 
00395 
00396 void LLFloaterWorldMap::setVisible( BOOL visible )
00397 {
00398         LLFloater::setVisible( visible );
00399 
00400         gSavedSettings.setBOOL( "ShowWorldMap", visible );
00401 
00402         if( !visible )
00403         {
00404                 
00405                 if (gWorldMap)
00406                 {
00407                         gWorldMap->clearImageRefs();
00408                 }
00409         }
00410 }
00411 
00412 
00413 
00414 BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
00415 {
00416         BOOL handled;
00417         handled = LLFloater::handleHover(x, y, mask);
00418         return handled;
00419 }
00420 
00421 BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
00422 {
00423         if (getVisible() && !isMinimized() && isFrontmost())
00424         {
00425                 F32 slider_value = (F32)childGetValue("zoom slider").asReal();
00426                 slider_value += ((F32)clicks * -0.3333f);
00427                 childSetValue("zoom slider", LLSD(slider_value));
00428                 return TRUE;
00429         }
00430         return FALSE;
00431 }
00432 
00433 
00434 
00435 void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent )
00436 {
00437         LLFloater::reshape( width, height, called_from_parent );
00438 
00439         
00440         
00441         
00442         
00443         
00444 }
00445 
00446 
00447 
00448 void LLFloaterWorldMap::draw()
00449 {
00450         if( !getVisible() )
00451         {
00452                 return;
00453         }
00454 
00455         
00456         
00457         
00458         LLViewerRegion* regionp = gAgent.getRegion();
00459         bool agent_on_prelude = (regionp && regionp->isPrelude());
00460         bool enable_go_home = gAgent.isGodlike() || !agent_on_prelude;
00461         childSetEnabled("Go Home", enable_go_home);
00462 
00463         updateLocation();
00464         
00465         LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); 
00466         if (LLTracker::TRACKING_AVATAR == tracking_status)
00467         {
00468                 childSetColor("avatar_icon", gTrackColor);
00469         }
00470         else
00471         {
00472                 childSetColor("avatar_icon", gDisabledTrackColor);
00473         }
00474 
00475         if (LLTracker::TRACKING_LANDMARK == tracking_status)
00476         {
00477                 childSetColor("landmark_icon", gTrackColor);
00478         }
00479         else
00480         {
00481                 childSetColor("landmark_icon", gDisabledTrackColor);
00482         }
00483 
00484         if (LLTracker::TRACKING_LOCATION == tracking_status)
00485         {
00486                 childSetColor("location_icon", gTrackColor);
00487         }
00488         else
00489         {
00490                 if (mCompletingRegionName != "")
00491                 {
00492                         F64 seconds = LLTimer::getElapsedSeconds();
00493                         double value = fmod(seconds, 2);
00494                         value = 0.5 + 0.5*cos(value * 3.14159f);
00495                         LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
00496                         childSetColor("location_icon", loading_color);
00497                 }
00498                 else
00499                 {
00500                         childSetColor("location_icon", gDisabledTrackColor);
00501                 }
00502         }
00503 
00504         
00505         if (mWaitingForTracker)
00506         {
00507                 centerOnTarget(TRUE);
00508         }
00509 
00510         childSetEnabled("Teleport", (BOOL)tracking_status);
00511 
00512         childSetEnabled("Show Destination", (BOOL)tracking_status || gWorldMap->mIsTrackingUnknownLocation);
00513         childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
00514 
00515         setMouseOpaque(TRUE);
00516         mDragHandle->setMouseOpaque(TRUE);
00517 
00518         
00519         if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)childGetValue("zoom slider").asReal())
00520         {
00521                 mZoomTimer.start();
00522         }
00523         F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
00524         if (interp > 1.f)
00525         {
00526                 interp = 1.f;
00527                 mZoomTimer.stop();
00528         }
00529         mCurZoomVal = lerp(mCurZoomVal, (F32)childGetValue("zoom slider").asReal(), interp);
00530         F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
00531         LLWorldMapView::setScale( map_scale );
00532         
00533         LLFloater::draw();
00534 }
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const LLString& name )
00543 {
00544         LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
00545         if (!iface) return;
00546 
00547         buildAvatarIDList();
00548         if(iface->setCurrentByID(avatar_id) || gAgent.isGodlike())
00549         {
00550                 
00551                 
00552                 
00553                 if(gAgent.isGodlike())
00554                 {
00555                         childSetValue("spin z", LLSD(200.f));
00556                 }
00557                 
00558                 if (mTrackedStatus != LLTracker::TRACKING_AVATAR || name != mTrackedAvatarName)
00559                 {
00560                         mTrackedStatus = LLTracker::TRACKING_AVATAR;
00561                         mTrackedAvatarName = name;
00562                         LLTracker::trackAvatar(avatar_id, name);
00563                 }
00564         }
00565         else
00566         {
00567                 LLTracker::stopTracking(NULL);
00568         }
00569         setDefaultBtn("Teleport");
00570 }
00571 
00572 void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
00573 {
00574         LLCtrlSelectionInterface *iface = childGetSelectionInterface("landmark combo");
00575         if (!iface) return;
00576 
00577         buildLandmarkIDLists();
00578         BOOL found = FALSE;
00579         S32 idx;
00580         for (idx = 0; idx < mLandmarkItemIDList.count(); idx++)
00581         {
00582                 if ( mLandmarkItemIDList.get(idx) == landmark_item_id)
00583                 {
00584                         found = TRUE;
00585                         break;
00586                 }
00587         }
00588 
00589         if (found && iface->setCurrentByID( landmark_item_id ) ) 
00590         {
00591                 LLUUID asset_id = mLandmarkAssetIDList.get( idx );
00592                 LLString name;
00593                 LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(this, "landmark combo");
00594                 if (combo) name = combo->getSimple();
00595                 mTrackedStatus = LLTracker::TRACKING_LANDMARK;
00596                 LLTracker::trackLandmark(mLandmarkAssetIDList.get( idx ),       
00597                                                                 mLandmarkItemIDList.get( idx ), 
00598                                                                 name);                  
00599 
00600                 if( asset_id != sHomeID )
00601                 {
00602                         
00603                         gLandmarkList.getAsset( asset_id);
00604                 }
00605 
00606                 
00607 
00608         }
00609         else
00610         {
00611                 LLTracker::stopTracking(NULL);
00612         }
00613         setDefaultBtn("Teleport");
00614 }
00615 
00616 
00617 void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info)
00618 {
00619         mTrackedStatus = LLTracker::TRACKING_LOCATION;
00620         LLTracker::trackLocation(event_info.mPosGlobal, event_info.mName, event_info.mToolTip, LLTracker::LOCATION_EVENT);
00621         setDefaultBtn("Teleport");
00622 }
00623 
00624 void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
00625 {
00626         mTrackedStatus = LLTracker::TRACKING_LOCATION;
00627         LLTracker::trackLocation(item.mPosGlobal, item.mName, item.mToolTip, LLTracker::LOCATION_ITEM);
00628         setDefaultBtn("Teleport");
00629 }
00630 
00631 void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
00632 {
00633         LLSimInfo* sim_info = gWorldMap->simInfoFromPosGlobal(pos_global);
00634         if (!sim_info)
00635         {
00636                 gWorldMap->mIsTrackingUnknownLocation = TRUE;
00637                 gWorldMap->mInvalidLocation = FALSE;
00638                 gWorldMap->mUnknownLocation = pos_global;
00639                 LLTracker::stopTracking(NULL);
00640                 S32 world_x = S32(pos_global.mdV[0] / 256);
00641                 S32 world_y = S32(pos_global.mdV[1] / 256);
00642                 gWorldMap->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
00643                 setDefaultBtn("");
00644                 return;
00645         }
00646         if (sim_info->mAccess == SIM_ACCESS_DOWN)
00647         {
00648                 
00649                 gWorldMap->mIsTrackingUnknownLocation = TRUE;
00650                 gWorldMap->mUnknownLocation = pos_global;
00651                 gWorldMap->mInvalidLocation = TRUE;
00652                 LLTracker::stopTracking(NULL);
00653                 setDefaultBtn("");
00654                 return;
00655         }
00656 
00657         LLString sim_name;
00658         gWorldMap->simNameFromPosGlobal( pos_global, sim_name );
00659         F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
00660         F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
00661         LLString full_name = llformat("%s (%d, %d, %d)", 
00662                                                                   sim_name.c_str(), 
00663                                                                   llround(region_x), 
00664                                                                   llround(region_y),
00665                                                                   llround((F32)pos_global.mdV[VZ]));
00666 
00667         LLString tooltip("");
00668         mTrackedStatus = LLTracker::TRACKING_LOCATION;
00669         LLTracker::trackLocation(pos_global, full_name, tooltip);
00670         gWorldMap->mIsTrackingUnknownLocation = FALSE;
00671         gWorldMap->mIsTrackingDoubleClick = FALSE;
00672         gWorldMap->mIsTrackingCommit = FALSE;
00673 
00674         setDefaultBtn("Teleport");
00675 }
00676 
00677 void LLFloaterWorldMap::updateLocation()
00678 {
00679         bool gotSimName;
00680 
00681         LLTracker::ETrackingStatus status = LLTracker::getTrackingStatus();
00682 
00683         
00684         
00685         LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
00686         if (pos_global.isExactlyZero())
00687         {
00688                 LLVector3d agentPos = gAgent.getPositionGlobal();
00689 
00690                 
00691                 if ( status == LLTracker::TRACKING_NOTHING && mSetToUserPosition )
00692                 {
00693                         
00694                         LLString agent_sim_name;
00695                         gotSimName = gWorldMap->simNameFromPosGlobal( agentPos, agent_sim_name );
00696                         if ( gotSimName )
00697                         {
00698                                 mSetToUserPosition = FALSE;
00699 
00700                                 
00701                                 childSetValue("location", agent_sim_name);
00702 
00703                                 
00704                                 LLVector3d agentPos = gAgent.getPositionGlobal();
00705 
00706                                 S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
00707                                 S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
00708                                 S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
00709 
00710                                 childSetValue("spin x", LLSD(agent_x) );
00711                                 childSetValue("spin y", LLSD(agent_y) );
00712                                 childSetValue("spin z", LLSD(agent_z) );
00713 
00714                                 
00715                                 mSLURL = LLWeb::escapeURL( llformat("http://slurl.com/secondlife/%s/%d/%d/%d", 
00716                                                                 agent_sim_name.c_str(), agent_x, agent_y, agent_z) );
00717                         }
00718                 }
00719 
00720                 return; 
00721         }
00722         LLString sim_name;
00723         gotSimName = gWorldMap->simNameFromPosGlobal( pos_global, sim_name );
00724         if ((status != LLTracker::TRACKING_NOTHING) &&
00725                 (status != mTrackedStatus || pos_global != mTrackedLocation || sim_name != mTrackedSimName))
00726         {
00727                 mTrackedStatus = status;
00728                 mTrackedLocation = pos_global;
00729                 mTrackedSimName = sim_name;
00730                 
00731                 if (status == LLTracker::TRACKING_AVATAR)
00732                 {
00733                         
00734                         
00735                         
00736                         if(gAgent.isGodlike())
00737                         {
00738                                 pos_global[2] = 200;
00739                         }
00740                 }
00741 
00742                 childSetValue("location", sim_name);
00743                 
00744                 F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
00745                 F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
00746                 childSetValue("spin x", LLSD(region_x) );
00747                 childSetValue("spin y", LLSD(region_y) );
00748                 childSetValue("spin z", LLSD((F32)pos_global.mdV[VZ]) );
00749 
00750                 
00751                 if ( gotSimName )
00752                 {
00753                         mSLURL = LLWeb::escapeURL(llformat("http://slurl.com/secondlife/%s/%d/%d/%d", 
00754                                                                                 sim_name.c_str(), llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ])));
00755                 }
00756                 else
00757                 {       
00758                         mSLURL = "";
00759                 }
00760         }
00761 }
00762 
00763 void LLFloaterWorldMap::trackURL(const LLString& region_name, S32 x_coord, S32 y_coord, S32 z_coord)
00764 {
00765         LLSimInfo* sim_info = gWorldMap->simInfoFromName(region_name);
00766         z_coord = llclamp(z_coord, 0, 1000);
00767         if (sim_info)
00768         {
00769                 LLVector3 local_pos;
00770                 local_pos.mV[VX] = (F32)x_coord;
00771                 local_pos.mV[VY] = (F32)y_coord;
00772                 local_pos.mV[VZ] = (F32)z_coord;
00773                 LLVector3d global_pos = sim_info->getGlobalPos(local_pos);
00774                 trackLocation(global_pos);
00775                 setDefaultBtn("Teleport");
00776         }
00777         else
00778         {
00779                 
00780                 gFloaterWorldMap->childSetValue("location", region_name);
00781                 childSetValue("spin x", LLSD((F32)x_coord));
00782                 childSetValue("spin y", LLSD((F32)y_coord));
00783                 childSetValue("spin z", LLSD((F32)z_coord));
00784 
00785                 
00786                 gFloaterWorldMap->mCompletingRegionName = region_name;
00787                 gWorldMap->sendNamedRegionRequest(region_name);
00788                 LLString::toLower(gFloaterWorldMap->mCompletingRegionName);
00789                 gWorldMap->mIsTrackingCommit = TRUE;
00790         }
00791 }
00792 
00793 void LLFloaterWorldMap::observeInventory(LLInventoryModel* model)
00794 {
00795         if(mInventory)
00796         {
00797                 mInventory->removeObserver(mInventoryObserver);
00798                 delete mInventoryObserver;
00799                 mInventory = NULL;
00800                 mInventoryObserver = NULL;
00801         }
00802         if(model)
00803         {
00804                 mInventory = model;
00805                 mInventoryObserver = new LLMapInventoryObserver;
00806                 
00807                 mInventory->addObserver(mInventoryObserver);
00808                 inventoryChanged();
00809         }
00810 }
00811 
00812 void LLFloaterWorldMap::inventoryChanged()
00813 {
00814         if(!LLTracker::getTrackedLandmarkItemID().isNull())
00815         {
00816                 LLUUID item_id = LLTracker::getTrackedLandmarkItemID();
00817                 buildLandmarkIDLists();
00818                 trackLandmark(item_id);
00819         }
00820 }
00821 
00822 void LLFloaterWorldMap::observeFriends()
00823 {
00824         if(!mFriendObserver)
00825         {
00826                 mFriendObserver = new LLMapFriendObserver;
00827                 LLAvatarTracker::instance().addObserver(mFriendObserver);
00828                 friendsChanged();
00829         }
00830 }
00831 
00832 void LLFloaterWorldMap::friendsChanged()
00833 {
00834         LLAvatarTracker& t = LLAvatarTracker::instance();
00835         const LLUUID& avatar_id = t.getAvatarID();
00836         buildAvatarIDList();
00837         if(avatar_id.notNull())
00838         {
00839                 LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
00840                 if(!iface || !iface->setCurrentByID(avatar_id) || 
00841                         !t.getBuddyInfo(avatar_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) || gAgent.isGodlike())
00842                 {
00843                         LLTracker::stopTracking(NULL);
00844                 }
00845         }
00846 }
00847 
00848 
00849 void LLFloaterWorldMap::buildAvatarIDList()
00850 {
00851         LLCtrlListInterface *list = childGetListInterface("friend combo");
00852         if (!list) return;
00853 
00854     
00855         S32 list_size = list->getItemCount();
00856         while (list_size > 1)
00857         {
00858                 list->selectNthItem(1);
00859                 list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
00860                 --list_size;
00861         }
00862 
00863         LLSD default_column;
00864         default_column["name"] = "friend name";
00865         default_column["label"] = "Friend Name";
00866         default_column["width"] = 500;
00867         list->addColumn(default_column);
00868 
00869         
00870         LLCollectMappableBuddies collector;
00871         LLAvatarTracker::instance().applyFunctor(collector);
00872         LLCollectMappableBuddies::buddy_map_t::iterator it;
00873         LLCollectMappableBuddies::buddy_map_t::iterator end;
00874         it = collector.mMappable.begin();
00875         end = collector.mMappable.end();
00876         for( ; it != end; ++it)
00877         {
00878                 list->addSimpleElement((*it).first, ADD_BOTTOM, (*it).second);
00879         }
00880 
00881         list->setCurrentByID( LLAvatarTracker::instance().getAvatarID() );
00882         list->selectFirstItem();
00883 }
00884 
00885 
00886 void LLFloaterWorldMap::buildLandmarkIDLists()
00887 {
00888         LLCtrlListInterface *list = childGetListInterface("landmark combo");
00889         if (!list) return;
00890 
00891     
00892         S32 list_size = list->getItemCount();
00893         while (list_size > 1)
00894         {
00895                 list->selectNthItem(1);
00896                 list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
00897                 --list_size;
00898         }
00899 
00900         mLandmarkItemIDList.reset();
00901         mLandmarkAssetIDList.reset();
00902 
00903         
00904         mLandmarkAssetIDList.put( LLUUID::null );
00905         mLandmarkItemIDList.put( LLUUID::null );
00906 
00907         mLandmarkAssetIDList.put( sHomeID );
00908         mLandmarkItemIDList.put( sHomeID );
00909 
00910         LLInventoryModel::cat_array_t cats;
00911         LLInventoryModel::item_array_t items;
00912         LLIsType is_landmark(LLAssetType::AT_LANDMARK);
00913         gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
00914                                                                         cats,
00915                                                                         items,
00916                                                                         LLInventoryModel::EXCLUDE_TRASH,
00917                                                                         is_landmark);
00918         std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
00919         
00920         S32 count = items.count();
00921         for(S32 i = 0; i < count; ++i)
00922         {
00923                 LLInventoryItem* item = items.get(i);
00924 
00925                 list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());
00926 
00927                 mLandmarkAssetIDList.put( item->getAssetUUID() );
00928                 mLandmarkItemIDList.put( item->getUUID() );
00929         }
00930         list->sortByColumn("landmark name", TRUE);
00931         list->selectFirstItem();
00932 }
00933 
00934 
00935 F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination, 
00936                                                                                                 F32 z_attenuation) const
00937 {
00938         LLVector3d delta = destination - gAgent.getPositionGlobal();
00939         
00940         
00941         delta.mdV[VZ] *= z_attenuation;
00942         F32 distance = (F32)delta.magVec();
00943         return distance;
00944 }
00945 
00946 
00947 void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
00948 {
00949         LLCtrlListInterface *list = childGetListInterface("search_results");
00950         if (list)
00951         {
00952                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00953         }
00954         if (!childHasKeyboardFocus("spin x"))
00955         {
00956                 childSetValue("spin x", SIM_COORD_DEFAULT);
00957         }
00958         if (!childHasKeyboardFocus("spin y"))
00959         {
00960                 childSetValue("spin y", SIM_COORD_DEFAULT);
00961         }
00962         if (!childHasKeyboardFocus("spin z"))
00963         {
00964                 childSetValue("spin z", 0);
00965         }
00966         gWorldMap->mIsTrackingCommit = FALSE;
00967         mCompletingRegionName = "";
00968         mExactMatch = FALSE;
00969 }
00970 
00971 
00972 void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui)
00973 {
00974         if (clear_ui || !childHasKeyboardFocus("landmark combo"))
00975         {
00976                 LLCtrlListInterface *list = childGetListInterface("landmark combo");
00977                 if (list)
00978                 {
00979                         list->selectByValue( "None" );
00980                 }
00981         }
00982 }
00983 
00984 
00985 void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
00986 {
00987         if (clear_ui || !childHasKeyboardFocus("friend combo"))
00988         {
00989                 mTrackedStatus = LLTracker::TRACKING_NOTHING;
00990                 LLCtrlListInterface *list = childGetListInterface("friend combo");
00991                 if (list)
00992                 {
00993                         list->selectByValue( "None" );
00994                 }
00995         }
00996 }
00997 
00998 
00999 
01000 
01001 void LLFloaterWorldMap::adjustZoomSliderBounds()
01002 {
01003         
01004         S32 world_width_regions  = gWorldMap->getWorldWidth() / REGION_WIDTH_UNITS;
01005         S32 world_height_regions = gWorldMap->getWorldHeight() / REGION_WIDTH_UNITS;
01006 
01007         
01008         
01009         world_width_regions++;
01010         world_height_regions++;
01011 
01012         
01013         LLWorldMapView* map_panel;
01014         map_panel = (LLWorldMapView*)mTabs->getCurrentPanel();
01015         LLRect view_rect = map_panel->getRect();
01016 
01017         
01018         S32 view_width = view_rect.getWidth();
01019         S32 view_height = view_rect.getHeight();
01020 
01021         
01022         F32 width_pixels_per_region = (F32) view_width / (F32) world_width_regions;
01023         F32 height_pixels_per_region = (F32) view_height / (F32) world_height_regions;
01024 
01025         F32 pixels_per_region = llmin(width_pixels_per_region,
01026                                                                   height_pixels_per_region);
01027 
01028         
01029         S32 slider_units = llfloor(pixels_per_region / 0.2f);
01030         pixels_per_region = slider_units * 0.2f;
01031 
01032         
01033         
01034         pixels_per_region = llclamp(pixels_per_region, 1.f, (F32)(pow(2.f, ZOOM_MAX) * 128.f));
01035 
01036         F32 min_power = log(pixels_per_region/256.f)/log(2.f);
01037         childSetMinValue("zoom slider", min_power);
01038 }
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 void LLFloaterWorldMap::onPanBtn( void* userdata )
01047 {
01048         if( !gFloaterWorldMap ) return;
01049 
01050         EPanDirection direction = (EPanDirection)(intptr_t)userdata;
01051 
01052         S32 pan_x = 0;
01053         S32 pan_y = 0;
01054         switch( direction )
01055         {
01056         case PAN_UP:    pan_y = -1;     break;
01057         case PAN_DOWN:  pan_y = 1;      break;
01058         case PAN_LEFT:  pan_x = 1;      break;
01059         case PAN_RIGHT: pan_x = -1;     break;
01060         default:                llassert(0);    return;
01061         }
01062 
01063         LLWorldMapView* map_panel;
01064         map_panel = (LLWorldMapView*)gFloaterWorldMap->mTabs->getCurrentPanel();
01065         map_panel->translatePan( pan_x, pan_y );
01066 }
01067 
01068 
01069 void LLFloaterWorldMap::onGoHome(void*)
01070 {
01071         gAgent.teleportHome();
01072         gFloaterWorldMap->close();
01073 }
01074 
01075 
01076 
01077 void LLFloaterWorldMap::onLandmarkComboPrearrange( LLUICtrl* ctrl, void* userdata )
01078 {
01079         LLFloaterWorldMap* self = gFloaterWorldMap;
01080         if( !self || self->mIsClosing )
01081         {
01082                 return;
01083         }
01084 
01085         LLCtrlListInterface *list = self->childGetListInterface("landmark combo");
01086         if (!list) return;
01087 
01088         LLUUID current_choice = list->getCurrentID();
01089 
01090         gFloaterWorldMap->buildLandmarkIDLists();
01091 
01092         if( current_choice.isNull() || !list->setCurrentByID( current_choice ) )
01093         {
01094                 LLTracker::stopTracking(NULL);
01095         }
01096 
01097 }
01098 
01099 
01100 void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata )
01101 {
01102         LLFloaterWorldMap* self = gFloaterWorldMap;
01103 
01104         if( !self || self->mIsClosing )
01105         {
01106                 return;
01107         }
01108 
01109         LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("landmark combo");
01110         if (!list) return;
01111 
01112         LLUUID asset_id;
01113         LLUUID item_id = list->getCurrentID();
01114 
01115         LLTracker::stopTracking(NULL);
01116 
01117         
01118         list->setCurrentByID(item_id);
01119 
01120         if( item_id.isNull() )
01121         {
01122         }
01123         else if( item_id == sHomeID )
01124         {
01125                 asset_id = sHomeID;
01126         }
01127         else
01128         {
01129                 LLInventoryItem* item = gInventory.getItem( item_id );
01130                 if( item )
01131                 {
01132                         asset_id = item->getAssetUUID();
01133                 }
01134                 else
01135                 {
01136                         
01137                         item_id.setNull();
01138                 }
01139         }
01140         
01141         self->trackLandmark( item_id);
01142         onShowTargetBtn(self);
01143 
01144         
01145         self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
01146 }
01147 
01148 
01149 void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata )
01150 {
01151         LLFloaterWorldMap* self = gFloaterWorldMap;
01152         if( !self || self->mIsClosing )
01153         {
01154                 return;
01155         }
01156 
01157         LLCtrlListInterface *list = self->childGetListInterface("friend combo");
01158         if (!list) return;
01159 
01160         LLUUID current_choice;
01161 
01162         if( LLAvatarTracker::instance().haveTrackingInfo() )
01163         {
01164                 current_choice = LLAvatarTracker::instance().getAvatarID();
01165         }
01166 
01167         self->buildAvatarIDList();
01168 
01169         if( !list->setCurrentByID( current_choice ) || current_choice.isNull() )
01170         {
01171                 LLTracker::stopTracking(NULL);
01172         }
01173 }
01174 
01175 
01176 
01177 void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata )
01178 {
01179         LLFloaterWorldMap* self = gFloaterWorldMap;
01180         if( !self || self->mIsClosing )
01181         {
01182                 return;
01183         }
01184 
01185         LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("friend combo");
01186         if (!list) return;
01187 
01188         const LLUUID& new_avatar_id = list->getCurrentID();
01189         if (new_avatar_id.notNull())
01190         {
01191                 LLString name;
01192                 LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(gFloaterWorldMap, "friend combo");
01193                 if (combo) name = combo->getSimple();
01194                 self->trackAvatar(new_avatar_id, name);
01195                 onShowTargetBtn(self);
01196         }
01197         else
01198         {       
01199                 self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
01200         }
01201 }
01202 
01203 
01204 void LLFloaterWorldMap::updateSearchEnabled( LLUICtrl* ctrl, void* userdata )
01205 {
01206         LLFloaterWorldMap *self = gFloaterWorldMap;
01207         if (self->childHasKeyboardFocus("location") && 
01208                 self->childGetValue("location").asString().length() > 0)
01209         {
01210                 self->setDefaultBtn("DoSearch");
01211         }
01212         else
01213         {
01214                 self->setDefaultBtn(NULL);
01215         }
01216 }
01217 
01218 
01219 void LLFloaterWorldMap::onLocationCommit( void* userdata )
01220 {
01221         LLFloaterWorldMap *self = gFloaterWorldMap;
01222         if( !self || self->mIsClosing )
01223         {
01224                 return;
01225         }
01226 
01227         self->clearLocationSelection(FALSE);
01228         self->mCompletingRegionName = "";
01229         self->mLastRegionName = "";
01230 
01231         LLString str = self->childGetValue("location").asString();
01232 
01233         
01234         LLString saved_str = str;
01235         LLString::trim( str );
01236         if ( str != saved_str )
01237         {       
01238                 self->childSetValue("location", str);
01239         }
01240 
01241         LLString::toLower(str);
01242         gFloaterWorldMap->mCompletingRegionName = str;
01243         gWorldMap->mIsTrackingCommit = TRUE;
01244         self->mExactMatch = FALSE;
01245         if (str.length() >= 3)
01246         {
01247                 gWorldMap->sendNamedRegionRequest(str);
01248         }
01249         else
01250         {
01251                 str += "#";
01252                 gWorldMap->sendNamedRegionRequest(str);
01253         }
01254 }
01255 
01256 
01257 
01258 void LLFloaterWorldMap::onClearBtn(void* data)
01259 {
01260         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01261         self->mTrackedStatus = LLTracker::TRACKING_NOTHING;
01262         LLTracker::stopTracking((void *)(intptr_t)TRUE);
01263         gWorldMap->mIsTrackingUnknownLocation = FALSE;
01264         self->mSLURL = "";                              
01265         self->mSetToUserPosition = TRUE;        
01266 }
01267 
01268 
01269 void LLFloaterWorldMap::onFlyBtn(void* data)
01270 {
01271         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01272         self->fly();
01273 }
01274 
01275 void LLFloaterWorldMap::onShowTargetBtn(void* data)
01276 {
01277         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01278         self->centerOnTarget(TRUE);
01279 }
01280 
01281 void LLFloaterWorldMap::onShowAgentBtn(void* data)
01282 {
01283         LLWorldMapView::setPan( 0, 0, FALSE); 
01284 
01285         
01286         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01287         self->mSetToUserPosition = TRUE;        
01288 }
01289 
01290 
01291 void LLFloaterWorldMap::onClickTeleportBtn(void* data)
01292 {
01293         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01294         self->teleport();
01295 }
01296 
01297 
01298 void LLFloaterWorldMap::onCopySLURL(void* data)
01299 {
01300         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01301         gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL));
01302         
01303         LLString::format_map_t args;
01304         args["[SLURL]"] = self->mSLURL;
01305 
01306         LLAlertDialog::showXml("CopySLURL", args);
01307 }
01308 
01309 void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data)
01310 {
01311         LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
01312         if(!self) return;
01313         self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk"));
01314 }
01315 
01316 
01317 void LLFloaterWorldMap::centerOnTarget(BOOL animate)
01318 {
01319         LLVector3d pos_global;
01320         if(LLTracker::getTrackingStatus() != LLTracker::TRACKING_NOTHING)
01321         {
01322                 LLVector3d tracked_position = LLTracker::getTrackedPositionGlobal();
01323                 
01324                 
01325                 if (tracked_position.isExactlyZero())
01326                 {
01327                         mWaitingForTracker = TRUE;
01328                         return;
01329                 }
01330                 else
01331                 {
01332                         
01333 
01334                         pos_global = LLTracker::getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();
01335                 }
01336         }
01337         else if(gWorldMap->mIsTrackingUnknownLocation)
01338         {
01339                 pos_global = gWorldMap->mUnknownLocation - gAgent.getCameraPositionGlobal();;
01340         }
01341         else
01342         {
01343                 
01344                 pos_global.clearVec();
01345         }
01346 
01347         LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sPixelsPerMeter)), 
01348                                                         -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sPixelsPerMeter)),
01349                                                         !animate);
01350         mWaitingForTracker = FALSE;
01351 }
01352 
01353 
01354 void LLFloaterWorldMap::fly()
01355 {
01356         LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
01357 
01358         
01359         
01360         if (!pos_global.isExactlyZero())
01361         {
01362                 gAgent.startAutoPilotGlobal( pos_global );
01363                 close();
01364         }
01365         else
01366         {
01367                 make_ui_sound("UISndInvalidOp");
01368         }
01369 }
01370 
01371 
01372 
01373 void LLFloaterWorldMap::teleport()
01374 {
01375         BOOL teleport_home = FALSE;
01376         LLVector3d pos_global;
01377         LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
01378 
01379         LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
01380         if (LLTracker::TRACKING_AVATAR == tracking_status
01381                 && av_tracker.haveTrackingInfo() )
01382         {
01383                 pos_global = av_tracker.getGlobalPos();
01384                 pos_global.mdV[VZ] = childGetValue("spin z");
01385         }
01386         else if ( LLTracker::TRACKING_LANDMARK == tracking_status)
01387         {
01388                 if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
01389                 {
01390                         teleport_home = TRUE;
01391                 }
01392                 else
01393                 {
01394                         LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
01395                         LLUUID region_id;
01396                         if(landmark
01397                            && !landmark->getGlobalPos(pos_global)
01398                            && landmark->getRegionID(region_id))
01399                         {
01400                                 LLLandmark::requestRegionHandle(
01401                                         gMessageSystem,
01402                                         gAgent.getRegionHost(),
01403                                         region_id,
01404                                         NULL);
01405                         }
01406                 }
01407         }
01408         else if ( LLTracker::TRACKING_LOCATION == tracking_status)
01409         {
01410                 pos_global = LLTracker::getTrackedPositionGlobal();
01411         }
01412         else
01413         {
01414                 make_ui_sound("UISndInvalidOp");
01415         }
01416 
01417         
01418         if (teleport_home)
01419         {
01420                 gAgent.teleportHome();
01421         }
01422         else if (!pos_global.isExactlyZero())
01423         {
01424                 if(LLTracker::TRACKING_LANDMARK == tracking_status)
01425                 {
01426                         gAgent.teleportViaLandmark(LLTracker::getTrackedLandmarkAssetID());
01427                 }
01428                 else
01429                 {
01430                         gAgent.teleportViaLocation( pos_global );
01431                 }
01432         }
01433 }
01434 
01435 
01436 void LLFloaterWorldMap::onGoToLandmarkDialog( S32 option, void* userdata )
01437 {
01438         LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
01439         switch( option )
01440         {
01441         case 0:
01442                 self->teleportToLandmark();
01443                 break;
01444         case 1:
01445                 self->flyToLandmark();
01446                 break;
01447         default:
01448                 
01449                 break;
01450         }
01451 }
01452 
01453 void LLFloaterWorldMap::flyToLandmark()
01454 {
01455         LLVector3d destination_pos_global;
01456         if( !LLTracker::getTrackedLandmarkAssetID().isNull() )
01457         {
01458                 if (LLTracker::hasLandmarkPosition())
01459                 {
01460                         gAgent.startAutoPilotGlobal( LLTracker::getTrackedPositionGlobal() );
01461                 }
01462         }
01463 }
01464 
01465 void LLFloaterWorldMap::teleportToLandmark()
01466 {
01467         BOOL has_destination = FALSE;
01468         LLUUID destination_id; 
01469 
01470         if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
01471         {
01472                 has_destination = TRUE;
01473         }
01474         else
01475         {
01476                 LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
01477                 LLVector3d global_pos;
01478                 if(landmark && landmark->getGlobalPos(global_pos))
01479                 {
01480                         destination_id = LLTracker::getTrackedLandmarkAssetID();
01481                         has_destination = TRUE;
01482                 }
01483                 else if(landmark)
01484                 {
01485                         
01486                         LLUUID region_id;
01487                         if(landmark->getRegionID(region_id))
01488                         {
01489                                 LLLandmark::requestRegionHandle(
01490                                         gMessageSystem,
01491                                         gAgent.getRegionHost(),
01492                                         region_id,
01493                                         NULL);
01494                         }
01495                 }
01496         }
01497 
01498         if( has_destination )
01499         {
01500                 gAgent.teleportViaLandmark( destination_id );
01501         }
01502 }
01503 
01504 
01505 void LLFloaterWorldMap::teleportToAvatar()
01506 {
01507         LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
01508         if(av_tracker.haveTrackingInfo())
01509         {
01510                 LLVector3d pos_global = av_tracker.getGlobalPos();
01511                 gAgent.teleportViaLocation( pos_global );
01512         }
01513 }
01514 
01515 
01516 void LLFloaterWorldMap::flyToAvatar()
01517 {
01518         if( LLAvatarTracker::instance().haveTrackingInfo() )
01519         {
01520                 gAgent.startAutoPilotGlobal( LLAvatarTracker::instance().getGlobalPos() );
01521         }
01522 }
01523 
01524 
01525 void LLFloaterWorldMap::onCommitBackground(void* userdata, bool from_click)
01526 {
01527         LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
01528 
01529         
01530         S32 index = self->mTabs->getCurrentPanelIndex();
01531 
01532         if (gWorldMap)
01533         {
01534                 gWorldMap->setCurrentLayer(index);
01535         }
01536 }
01537 
01538 void LLFloaterWorldMap::updateSims(bool found_null_sim)
01539 {
01540         if (mCompletingRegionName == "")
01541         {
01542                 return;
01543         }
01544 
01545         LLCtrlListInterface *list = childGetListInterface("search_results");
01546         if (!list) return;
01547         list->operateOnAll(LLCtrlListInterface::OP_DELETE);
01548 
01549         LLSD selected_value = list->getSimpleSelectedValue();
01550 
01551         S32 name_length = mCompletingRegionName.length();
01552 
01553         BOOL match_found = FALSE;
01554         S32 num_results = 0;
01555         std::map<U64, LLSimInfo*>::const_iterator it;
01556         for (it = gWorldMap->mSimInfoMap.begin(); it != gWorldMap->mSimInfoMap.end(); ++it)
01557         {
01558                 LLSimInfo* info = (*it).second;
01559                 LLString sim_name = info->mName;
01560                 LLString sim_name_lower = sim_name;
01561                 LLString::toLower(sim_name_lower);
01562 
01563                 if (sim_name_lower.substr(0, name_length) == mCompletingRegionName)
01564                 {
01565                         if (gWorldMap->mIsTrackingCommit)
01566                         {
01567                                 if (sim_name_lower == mCompletingRegionName)
01568                                 {
01569                                         selected_value = sim_name;
01570                                         match_found = TRUE;
01571                                 }
01572                         }
01573 
01574                         LLSD value;
01575                         value["id"] = sim_name;
01576                         value["columns"][0]["column"] = "sim_name";
01577                         value["columns"][0]["value"] = sim_name;
01578                         list->addElement(value);
01579                         num_results++;
01580                 }
01581         }
01582         
01583         list->selectByValue(selected_value);
01584 
01585         if (found_null_sim)
01586         {
01587                 mCompletingRegionName = "";
01588         }
01589 
01590         if (match_found)
01591         {
01592                 mExactMatch = TRUE;
01593                 childSetFocus("search_results");
01594                 onCommitSearchResult(NULL, this);
01595         }
01596         else if (!mExactMatch && num_results > 0)
01597         {
01598                 list->selectFirstItem(); 
01599                 childSetFocus("search_results");
01600                 onCommitSearchResult(NULL, this);
01601         }
01602         else
01603         {
01604                 list->addSimpleElement("None found.");
01605                 list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
01606         }
01607 }
01608 
01609 
01610 void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata)
01611 {
01612         LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
01613         LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
01614         if ( LLTracker::TRACKING_LOCATION == tracking_status)
01615         {
01616                 LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
01617                 F64 local_x = self->childGetValue("spin x");
01618                 F64 local_y = self->childGetValue("spin y");
01619                 F64 local_z = self->childGetValue("spin z");
01620                 pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x;
01621                 pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y;
01622                 pos_global.mdV[VZ] = local_z;
01623                 self->trackLocation(pos_global);
01624         }
01625 }
01626 
01627 
01628 void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata)
01629 {
01630         LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
01631 
01632         LLCtrlListInterface *list = self->childGetListInterface("search_results");
01633         if (!list) return;
01634 
01635         LLSD selected_value = list->getSimpleSelectedValue();
01636         LLString sim_name = selected_value.asString();
01637         if (sim_name.empty())
01638         {
01639                 return;
01640         }
01641         LLString::toLower(sim_name);
01642 
01643         std::map<U64, LLSimInfo*>::const_iterator it;
01644         for (it = gWorldMap->mSimInfoMap.begin(); it != gWorldMap->mSimInfoMap.end(); ++it)
01645         {
01646                 LLSimInfo* info = (*it).second;
01647                 LLString info_sim_name = info->mName;
01648                 LLString::toLower(info_sim_name);
01649 
01650                 if (sim_name == info_sim_name)
01651                 {
01652                         LLVector3d pos_global = from_region_handle( info->mHandle );
01653                         F64 local_x = self->childGetValue("spin x");
01654                         F64 local_y = self->childGetValue("spin y");
01655                         F64 local_z = self->childGetValue("spin z");
01656                         pos_global.mdV[VX] += local_x;
01657                         pos_global.mdV[VY] += local_y;
01658                         pos_global.mdV[VZ] = local_z;
01659 
01660                         self->childSetValue("location", sim_name);
01661                         self->trackLocation(pos_global);
01662                         self->setDefaultBtn("Teleport");
01663                         break;
01664                 }
01665         }
01666 
01667         onShowTargetBtn(self);
01668 }