aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llurldispatcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llurldispatcher.cpp')
-rw-r--r--linden/indra/newview/llurldispatcher.cpp326
1 files changed, 326 insertions, 0 deletions
diff --git a/linden/indra/newview/llurldispatcher.cpp b/linden/indra/newview/llurldispatcher.cpp
new file mode 100644
index 0000000..7344206
--- /dev/null
+++ b/linden/indra/newview/llurldispatcher.cpp
@@ -0,0 +1,326 @@
1/**
2 * @file llurldispatcher.cpp
3 * @brief Central registry for all URL handlers
4 *
5 * $LicenseInfo:firstyear=2007&license=viewergpl$
6 *
7 * Copyright (c) 2007, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlife.com/developers/opensource/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31#include "llviewerprecompiledheaders.h"
32
33#include "llurldispatcher.h"
34
35// viewer includes
36#include "llagent.h" // teleportViaLocation()
37#include "llcommandhandler.h"
38// *FIX: code in merge sl-search-8
39//#include "llfloaterurldisplay.h"
40#include "llfloaterdirectory.h"
41#include "llfloaterhtmlhelp.h"
42#include "llfloaterworldmap.h"
43#include "llpanellogin.h"
44#include "llstartup.h" // gStartupState
45#include "llurlsimstring.h"
46#include "llviewerwindow.h" // alertXml()
47#include "llworldmap.h"
48
49// library includes
50#include "llsd.h"
51
52// system includes
53#include <boost/tokenizer.hpp>
54
55const std::string SLURL_SL_HELP_PREFIX = "secondlife://app.";
56const std::string SLURL_SL_PREFIX = "sl://";
57const std::string SLURL_SECONDLIFE_PREFIX = "secondlife://";
58const std::string SLURL_SLURL_PREFIX = "http://slurl.com/secondlife/";
59
60const std::string SLURL_APP_TOKEN = "app/";
61
62class LLURLDispatcherImpl
63{
64public:
65 static bool isSLURL(const std::string& url);
66
67 static bool isSLURLCommand(const std::string& url);
68
69 static bool dispatch(const std::string& url);
70 // returns true if handled
71
72 static bool dispatchRightClick(const std::string& url);
73
74private:
75 static bool dispatchCore(const std::string& url, bool right_mouse);
76 // handles both left and right click
77
78 static bool dispatchHelp(const std::string& url, BOOL right_mouse);
79 // Handles sl://app.floater.html.help by showing Help floater.
80 // Returns true if handled.
81
82 static bool dispatchApp(const std::string& url, BOOL right_mouse);
83 // Handles secondlife://app/agent/<agent_id>/about and similar
84 // by showing panel in Search floater.
85 // Returns true if handled.
86
87 static bool dispatchRegion(const std::string& url, BOOL right_mouse);
88 // handles secondlife://Ahern/123/45/67/
89 // Returns true if handled.
90
91// *FIX: code in merge sl-search-8
92// static void regionHandleCallback(U64 handle, const std::string& url,
93// const LLUUID& snapshot_id, bool teleport);
94// // Called by LLWorldMap when a region name has been resolved to a
95// // location in-world, used by places-panel display.
96
97 static bool matchPrefix(const std::string& url, const std::string& prefix);
98
99 static std::string stripProtocol(const std::string& url);
100
101 friend class LLTeleportHandler;
102};
103
104// static
105bool LLURLDispatcherImpl::isSLURL(const std::string& url)
106{
107 if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) return true;
108 if (matchPrefix(url, SLURL_SL_PREFIX)) return true;
109 if (matchPrefix(url, SLURL_SECONDLIFE_PREFIX)) return true;
110 if (matchPrefix(url, SLURL_SLURL_PREFIX)) return true;
111 return false;
112}
113
114// static
115bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url)
116{
117 if (matchPrefix(url, SLURL_SL_PREFIX + SLURL_APP_TOKEN)
118 || matchPrefix(url, SLURL_SECONDLIFE_PREFIX + SLURL_APP_TOKEN)
119 || matchPrefix(url, SLURL_SLURL_PREFIX + SLURL_APP_TOKEN) )
120 {
121 return true;
122 }
123 return false;
124}
125
126// static
127bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool right_mouse)
128{
129 if (url.empty()) return false;
130 if (dispatchHelp(url, right_mouse)) return true;
131 if (dispatchApp(url, right_mouse)) return true;
132 if (dispatchRegion(url, right_mouse)) return true;
133 return false;
134}
135
136// static
137bool LLURLDispatcherImpl::dispatch(const std::string& url)
138{
139 llinfos << "url: " << url << llendl;
140 return dispatchCore(url, false); // not right click
141}
142
143// static
144bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
145{
146 llinfos << "url: " << url << llendl;
147 return dispatchCore(url, true); // yes right click
148}
149// static
150bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse)
151{
152 if (matchPrefix(url, SLURL_SL_HELP_PREFIX))
153 {
154 gViewerHtmlHelp.show();
155 return true;
156 }
157 return false;
158}
159
160// static
161bool LLURLDispatcherImpl::dispatchApp(const std::string& url, BOOL right_mouse)
162{
163 if (!isSLURL(url))
164 {
165 return false;
166 }
167 std::string s = stripProtocol(url);
168
169 // At this point, "secondlife://app/foo/bar/baz/" should be left
170 // as: "app/foo/bar/baz/"
171 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
172 boost::char_separator<char> sep("/", "", boost::drop_empty_tokens);
173 tokenizer tokens(s, sep);
174 tokenizer::iterator it = tokens.begin();
175 tokenizer::iterator end = tokens.end();
176
177 // Build parameter list suitable for LLDispatcher dispatch
178 if (it == end) return false;
179 if (*it != "app") return false;
180 ++it;
181
182 if (it == end) return false;
183 std::string cmd = *it;
184 ++it;
185
186 std::vector<std::string> params;
187 for ( ; it != end; ++it)
188 {
189 params.push_back(*it);
190 }
191
192 bool handled = LLCommandDispatcher::dispatch(cmd, params);
193 if (handled) return true;
194
195 // Inform the user we can't handle this
196 std::map<std::string, std::string> args;
197 args["[SLURL]"] = url;
198 gViewerWindow->alertXml("BadURL", args);
199 return false;
200}
201
202// static
203bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, BOOL right_mouse)
204{
205 if (!isSLURL(url))
206 {
207 return false;
208 }
209
210 // Before we're logged in, need to update the startup screen
211 // to tell the user where they are going.
212 if (LLStartUp::getStartupState() < STATE_CLEANUP)
213 {
214 // Parse it and stash in globals, it will be dispatched in
215 // STATE_CLEANUP.
216 LLURLSimString::setString(url);
217 // We're at the login screen, so make sure user can see
218 // the login location box to know where they are going.
219 LLPanelLogin::refreshLocation( true );
220 return true;
221 }
222
223 std::string sim_string = stripProtocol(url);
224 std::string region_name;
225 S32 x = 128;
226 S32 y = 128;
227 S32 z = 0;
228 LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);
229 if (gFloaterWorldMap)
230 {
231 llinfos << "Opening map to " << region_name << llendl;
232 gFloaterWorldMap->trackURL( region_name.c_str(), x, y, z );
233 LLFloaterWorldMap::show(NULL, TRUE);
234 }
235 return true;
236}
237
238// static
239bool LLURLDispatcherImpl::matchPrefix(const std::string& url, const std::string& prefix)
240{
241 std::string test_prefix = url.substr(0, prefix.length());
242 LLString::toLower(test_prefix);
243 return test_prefix == prefix;
244}
245
246// static
247std::string LLURLDispatcherImpl::stripProtocol(const std::string& url)
248{
249 std::string stripped = url;
250 if (matchPrefix(stripped, SLURL_SL_HELP_PREFIX))
251 {
252 stripped.erase(0, SLURL_SL_HELP_PREFIX.length());
253 }
254 else if (matchPrefix(stripped, SLURL_SL_PREFIX))
255 {
256 stripped.erase(0, SLURL_SL_PREFIX.length());
257 }
258 else if (matchPrefix(stripped, SLURL_SECONDLIFE_PREFIX))
259 {
260 stripped.erase(0, SLURL_SECONDLIFE_PREFIX.length());
261 }
262 else if (matchPrefix(stripped, SLURL_SLURL_PREFIX))
263 {
264 stripped.erase(0, SLURL_SLURL_PREFIX.length());
265 }
266 return stripped;
267}
268
269// *FIX: code in merge sl-search-8
270//
271////---------------------------------------------------------------------------
272//// Teleportation links are handled here because they are tightly coupled
273//// to URL parsing and sim-fragment parsing
274//class LLTeleportHandler : public LLCommandHandler
275//{
276//public:
277// LLTeleportHandler() : LLCommandHandler("teleport") { }
278// bool handle(const std::vector<std::string>& tokens)
279// {
280// // construct a "normal" SLURL, resolve the region to
281// // a global position, and teleport to it
282// if (tokens.size() < 1) return false;
283//
284// // Region names may be %20 escaped.
285// std::string region_name = LLURLSimString::unescapeRegionName(tokens[0]);
286//
287// // build secondlife://De%20Haro/123/45/67 for use in callback
288// std::string url = SLURL_SECONDLIFE_PREFIX;
289// for (size_t i = 0; i < tokens.size(); ++i)
290// {
291// url += tokens[i] + "/";
292// }
293// gWorldMap->sendNamedRegionRequest(region_name,
294// LLURLDispatcherImpl::regionHandleCallback,
295// url,
296// true); // teleport
297// return true;
298// }
299//};
300//LLTeleportHandler gTeleportHandler;
301
302//---------------------------------------------------------------------------
303
304// static
305bool LLURLDispatcher::isSLURL(const std::string& url)
306{
307 return LLURLDispatcherImpl::isSLURL(url);
308}
309
310// static
311bool LLURLDispatcher::isSLURLCommand(const std::string& url)
312{
313 return LLURLDispatcherImpl::isSLURLCommand(url);
314}
315
316// static
317bool LLURLDispatcher::dispatch(const std::string& url)
318{
319 return LLURLDispatcherImpl::dispatch(url);
320}
321// static
322bool LLURLDispatcher::dispatchRightClick(const std::string& url)
323{
324 return LLURLDispatcherImpl::dispatchRightClick(url);
325}
326