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" />  | 
