diff options
-rw-r--r-- | indra/llui/lltextbase.cpp | 1 | ||||
-rw-r--r-- | indra/llui/llurlaction.cpp | 18 | ||||
-rw-r--r-- | indra/llui/llurlaction.h | 2 | ||||
-rw-r--r-- | indra/llui/llurlentry.cpp | 16 | ||||
-rw-r--r-- | indra/llui/llurlentry.h | 4 | ||||
-rwxr-xr-x | indra/newview/llfloaterworldmap.cpp | 46 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_url_parcel.xml | 2 |
7 files changed, 88 insertions, 1 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 778b253c3c..7007049e1c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2228,6 +2228,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url)); registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url)); registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); + registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url)); registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index b6b450c2a1..ce599a7552 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -30,6 +30,7 @@ #include "llview.h" #include "llwindow.h" #include "llurlregistry.h" +#include "v3dmath.h" // global state for the callback functions @@ -128,6 +129,23 @@ void LLUrlAction::showLocationOnMap(std::string url) } } +void LLUrlAction::showParcelOnMap(std::string url) +{ + LLSD path_array = LLURI(url).pathArray(); + auto path_parts = path_array.size(); + + if (path_parts < 3) // no parcel id + { + LL_WARNS() << "Global coordinates are missing in url: [" << url << "]" << LL_ENDL; + return; + } + + LLVector3d parcel_pos = LLUrlEntryParcel::getParcelPos(LLUUID(LLURI::unescape(path_array[2]))); + std::ostringstream pos; + pos << parcel_pos.mdV[VX] << '/' << parcel_pos.mdV[VY] << '/' << parcel_pos.mdV[VZ]; + executeSLURL("secondlife:///app/worldmap_global/" + pos.str()); +} + void LLUrlAction::copyURLToClipboard(std::string url) { LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url)); diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index ac9741a7ad..c960d61ca0 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -63,6 +63,8 @@ public: /// if the Url specifies an SL location, show it on a map static void showLocationOnMap(std::string url); + static void showParcelOnMap(std::string url); + /// perform the appropriate action for left-clicking on a Url static void clickAction(std::string url, bool trusted_content); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index bcd13b7f0b..59e8f47c8f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -41,6 +41,7 @@ #include "lluicolortable.h" #include "message.h" #include "llexperiencecache.h" +#include "v3dmath.h" #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" @@ -1084,6 +1085,7 @@ LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null); LLHost LLUrlEntryParcel::sRegionHost; bool LLUrlEntryParcel::sDisconnected(false); std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers; +std::map<LLUUID, LLVector3d> LLUrlEntryParcel::sParcelPos; /// /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., @@ -1176,6 +1178,20 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data) url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label); } } + if (sParcelPos.find(parcel_data.parcel_id) == sParcelPos.end()) + { + sParcelPos[parcel_data.parcel_id] = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); + } +} + +// static +LLVector3d LLUrlEntryParcel::getParcelPos(const LLUUID& parcel_id) +{ + if (sParcelPos.find(parcel_id) != sParcelPos.end()) + { + return sParcelPos[parcel_id]; + } + return LLVector3d(); } // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 6e7d2fc80f..efa79c258d 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -41,6 +41,7 @@ #include <map> class LLAvatarName; +class LLVector3d; typedef boost::signals2::signal<void (const std::string& url, const std::string& label, @@ -434,6 +435,8 @@ public: // Processes parcel label and triggers notifying observers. static void processParcelInfo(const LLParcelData& parcel_data); + static LLVector3d getParcelPos(const LLUUID& parcel_id); + // Next setters are used to update agent and viewer connection information // upon events like user login, viewer disconnect and user changing region host. // These setters are made public to be accessible from newview and should not be @@ -447,6 +450,7 @@ private: static LLHost sRegionHost; static bool sDisconnected; static std::set<LLUrlEntryParcel*> sParcelInfoObservers; + static std::map<LLUUID, LLVector3d> sParcelPos; }; /// diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 565642e683..da808bd8f2 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -169,6 +169,52 @@ public: }; LLWorldMapHandler gWorldMapHandler; +// handle secondlife:///app/worldmap_global/{GLOBAL_COORDS} URLs +class LLWorldMapGlobalHandler : public LLCommandHandler +{ +public: + LLWorldMapGlobalHandler() : LLCommandHandler("worldmap_global", UNTRUSTED_THROTTLE) + {} + + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (nav_type == NAV_TYPE_CLICKED + || nav_type == NAV_TYPE_EXTERNAL) + { + // NAV_TYPE_EXTERNAL will be throttled + return true; + } + + return false; + } + + bool handle(const LLSD& params, + const LLSD& query_map, + const std::string& grid, + LLMediaCtrl* web) + { + if (params.size() < 3) + { + LL_WARNS() << "Correct global coordinates are not provided." << LL_ENDL; + return true; + } + + LLVector3d parcel_global_pos = LLVector3d(params[0].asInteger(), params[1].asInteger(), params[2].asInteger()); + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!parcel_global_pos.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(parcel_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + return true; + } +}; +LLWorldMapGlobalHandler gWorldMapGlobalHandler; + // SocialMap handler secondlife:///app/maptrackavatar/id class LLMapTrackAvatarHandler : public LLCommandHandler { diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml index e0f1fcf9c3..95752dab66 100644 --- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml +++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml @@ -16,7 +16,7 @@ layout="topleft" name="show_on_map"> <menu_item_call.on_click - function="Url.ShowOnMap" /> + function="Url.ShowParcelOnMap" /> </menu_item_call> <menu_item_separator layout="topleft" /> |