diff options
Diffstat (limited to 'linden/indra/newview/llfloaterhtmlhelp.cpp')
-rw-r--r-- | linden/indra/newview/llfloaterhtmlhelp.cpp | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp new file mode 100644 index 0000000..9a5ba0e --- /dev/null +++ b/linden/indra/newview/llfloaterhtmlhelp.cpp | |||
@@ -0,0 +1,528 @@ | |||
1 | /** | ||
2 | * @file llfloaterhtmlhelp.cpp | ||
3 | * @brief HTML Help floater - uses embedded web browser control | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2006-2008, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 | |||
32 | #include "llviewerprecompiledheaders.h" | ||
33 | |||
34 | #include "llfloaterhtmlhelp.h" | ||
35 | |||
36 | #include "llparcel.h" | ||
37 | #include "llvieweruictrlfactory.h" | ||
38 | #include "llwebbrowserctrl.h" | ||
39 | #include "llviewerwindow.h" | ||
40 | #include "llviewercontrol.h" | ||
41 | #include "llviewerparcelmgr.h" | ||
42 | #include "llweb.h" | ||
43 | #include "llui.h" | ||
44 | #include "roles_constants.h" | ||
45 | |||
46 | #include "llurlhistory.h" | ||
47 | #include "llwebbrowserctrl.h" | ||
48 | #include "llviewermedia.h" | ||
49 | #include "llviewerparcelmedia.h" | ||
50 | #include "llcombobox.h" | ||
51 | |||
52 | |||
53 | LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) | ||
54 | { | ||
55 | gUICtrlFactory->buildFloater(this, "floater_media_browser.xml"); | ||
56 | } | ||
57 | |||
58 | void LLFloaterMediaBrowser::draw() | ||
59 | { | ||
60 | childSetEnabled("go", !mAddressCombo->getValue().asString().empty()); | ||
61 | if ( gParcelMgr ) // this code can be called at login screen where gParcelMgr is NULL | ||
62 | { | ||
63 | LLParcel* parcel = gParcelMgr->getAgentParcel(); | ||
64 | if(parcel) | ||
65 | { | ||
66 | childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA)); | ||
67 | childSetEnabled("assign", !mAddressCombo->getValue().asString().empty()); | ||
68 | } | ||
69 | }; | ||
70 | LLFloater::draw(); | ||
71 | } | ||
72 | |||
73 | BOOL LLFloaterMediaBrowser::postBuild() | ||
74 | { | ||
75 | mBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "browser"); | ||
76 | mBrowser->addObserver(this); | ||
77 | |||
78 | mAddressCombo = LLUICtrlFactory::getComboBoxByName(this, "address"); | ||
79 | mAddressCombo->setCommitCallback(onEnterAddress); | ||
80 | mAddressCombo->setCallbackUserData(this); | ||
81 | |||
82 | childSetAction("back", onClickBack, this); | ||
83 | childSetAction("forward", onClickForward, this); | ||
84 | childSetAction("reload", onClickRefresh, this); | ||
85 | childSetAction("go", onClickGo, this); | ||
86 | childSetAction("close", onClickClose, this); | ||
87 | childSetAction("open_browser", onClickOpenWebBrowser, this); | ||
88 | childSetAction("assign", onClickAssign, this); | ||
89 | |||
90 | buildURLHistory(); | ||
91 | return TRUE; | ||
92 | } | ||
93 | |||
94 | void LLFloaterMediaBrowser::buildURLHistory() | ||
95 | { | ||
96 | LLCtrlListInterface* url_list = childGetListInterface("address"); | ||
97 | if (url_list) | ||
98 | { | ||
99 | url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); | ||
100 | } | ||
101 | |||
102 | // Get all of the entries in the "parcel" collection | ||
103 | LLSD parcel_history = LLURLHistory::getURLHistory("browser"); | ||
104 | |||
105 | LLSD::array_iterator iter_history = | ||
106 | parcel_history.beginArray(); | ||
107 | LLSD::array_iterator end_history = | ||
108 | parcel_history.endArray(); | ||
109 | for(; iter_history != end_history; ++iter_history) | ||
110 | { | ||
111 | std::string url = (*iter_history).asString(); | ||
112 | if(! url.empty()) | ||
113 | url_list->addSimpleElement(url); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | void LLFloaterMediaBrowser::onClose(bool app_quitting) | ||
118 | { | ||
119 | //setVisible(FALSE); | ||
120 | destroy(); | ||
121 | } | ||
122 | |||
123 | void LLFloaterMediaBrowser::onLocationChange( const EventType& eventIn ) | ||
124 | { | ||
125 | // hitting the refresh button will navigate to same URL, so don't add to address history | ||
126 | mCurrentURL = eventIn.getStringValue(); | ||
127 | std::string::size_type string_start = mCurrentURL.find("://"); | ||
128 | LLString truncated_url; | ||
129 | if ((string_start == std::string::npos) || (1)) // NOTE: this conditional is forced true to disable truncation DEV-9834 | ||
130 | { | ||
131 | truncated_url = mCurrentURL; | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | truncated_url = mCurrentURL.substr(string_start + 3); | ||
136 | } | ||
137 | // redirects will navigate momentarily to about:blank, don't add to history | ||
138 | if (truncated_url != "about:blank") | ||
139 | { | ||
140 | mAddressCombo->remove(truncated_url); | ||
141 | mAddressCombo->add(truncated_url, ADD_SORTED); | ||
142 | mAddressCombo->selectByValue(truncated_url); | ||
143 | |||
144 | // Serialize url history | ||
145 | LLURLHistory::removeURL("browser", truncated_url); | ||
146 | LLURLHistory::addURL("browser", truncated_url); | ||
147 | } | ||
148 | childSetEnabled("back", mBrowser->canNavigateBack()); | ||
149 | childSetEnabled("forward", mBrowser->canNavigateForward()); | ||
150 | childSetEnabled("reload", TRUE); | ||
151 | } | ||
152 | |||
153 | LLFloaterMediaBrowser* LLFloaterMediaBrowser::showInstance(const LLSD& media_url) | ||
154 | { | ||
155 | LLFloaterMediaBrowser* floaterp = LLUISingleton<LLFloaterMediaBrowser, VisibilityPolicy<LLFloater> >::showInstance(media_url); | ||
156 | |||
157 | floaterp->openMedia(media_url.asString()); | ||
158 | return floaterp; | ||
159 | } | ||
160 | |||
161 | //static | ||
162 | void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data) | ||
163 | { | ||
164 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
165 | self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); | ||
166 | } | ||
167 | |||
168 | //static | ||
169 | void LLFloaterMediaBrowser::onClickRefresh(void* user_data) | ||
170 | { | ||
171 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
172 | |||
173 | self->mAddressCombo->remove(0); | ||
174 | self->mBrowser->navigateTo(self->mCurrentURL); | ||
175 | } | ||
176 | |||
177 | //static | ||
178 | void LLFloaterMediaBrowser::onClickForward(void* user_data) | ||
179 | { | ||
180 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
181 | |||
182 | self->mBrowser->navigateForward(); | ||
183 | } | ||
184 | |||
185 | //static | ||
186 | void LLFloaterMediaBrowser::onClickBack(void* user_data) | ||
187 | { | ||
188 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
189 | |||
190 | self->mBrowser->navigateBack(); | ||
191 | } | ||
192 | |||
193 | //static | ||
194 | void LLFloaterMediaBrowser::onClickGo(void* user_data) | ||
195 | { | ||
196 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
197 | |||
198 | self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); | ||
199 | } | ||
200 | |||
201 | //static | ||
202 | void LLFloaterMediaBrowser::onClickClose(void* user_data) | ||
203 | { | ||
204 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
205 | |||
206 | self->close(); | ||
207 | } | ||
208 | |||
209 | //static | ||
210 | void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data) | ||
211 | { | ||
212 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
213 | |||
214 | LLWeb::loadURLExternal(self->mCurrentURL); | ||
215 | } | ||
216 | |||
217 | void LLFloaterMediaBrowser::onClickAssign(void* user_data) | ||
218 | { | ||
219 | LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; | ||
220 | |||
221 | LLParcel* parcel = gParcelMgr->getAgentParcel(); | ||
222 | if (!parcel) | ||
223 | { | ||
224 | return; | ||
225 | } | ||
226 | std::string media_url = self->mAddressCombo->getValue().asString(); | ||
227 | LLString::trim(media_url); | ||
228 | |||
229 | parcel->setMediaURL(media_url.c_str()); | ||
230 | parcel->setMediaType("text/html"); | ||
231 | |||
232 | // Send current parcel data upstream to server | ||
233 | gParcelMgr->sendParcelPropertiesUpdate( parcel, true ); | ||
234 | // now check for video | ||
235 | LLViewerParcelMedia::update( parcel ); | ||
236 | |||
237 | |||
238 | } | ||
239 | |||
240 | void LLFloaterMediaBrowser::openMedia(const std::string& media_url) | ||
241 | { | ||
242 | mBrowser->setHomePageUrl(media_url); | ||
243 | mBrowser->navigateTo(media_url); | ||
244 | } | ||
245 | |||
246 | LLViewerHtmlHelp gViewerHtmlHelp; | ||
247 | |||
248 | class LLFloaterHtmlHelp : | ||
249 | public LLFloater, | ||
250 | public LLWebBrowserCtrlObserver | ||
251 | { | ||
252 | public: | ||
253 | LLFloaterHtmlHelp(std::string start_url, std::string title); | ||
254 | virtual ~LLFloaterHtmlHelp(); | ||
255 | |||
256 | virtual void onClose( bool app_quitting ); | ||
257 | virtual void draw(); | ||
258 | |||
259 | static void show(std::string url, std::string title); | ||
260 | static void onClickBack( void* data ); | ||
261 | static void onClickHome( void* data ); | ||
262 | static void onClickForward( void* data ); | ||
263 | static void onClickClose( void* data ); | ||
264 | |||
265 | // browser observer impls | ||
266 | virtual void onStatusTextChange( const EventType& eventIn ); | ||
267 | virtual void onLocationChange( const EventType& eventIn ); | ||
268 | |||
269 | // used for some stats logging - will be removed at some point | ||
270 | static BOOL sFloaterOpened; | ||
271 | |||
272 | static void onClickF1HelpLoadURL(S32 option, void* userdata); | ||
273 | |||
274 | protected: | ||
275 | LLWebBrowserCtrl* mWebBrowser; | ||
276 | static LLFloaterHtmlHelp* sInstance; | ||
277 | LLButton* mBackButton; | ||
278 | LLButton* mForwardButton; | ||
279 | LLButton* mCloseButton; | ||
280 | LLTextBox* mStatusText; | ||
281 | LLString mStatusTextContents; | ||
282 | LLString mCurrentUrl; | ||
283 | }; | ||
284 | |||
285 | LLFloaterHtmlHelp* LLFloaterHtmlHelp::sInstance = 0; | ||
286 | |||
287 | BOOL LLFloaterHtmlHelp::sFloaterOpened = FALSE; | ||
288 | |||
289 | //////////////////////////////////////////////////////////////////////////////// | ||
290 | // | ||
291 | LLFloaterHtmlHelp::LLFloaterHtmlHelp(std::string start_url, std::string title) | ||
292 | : LLFloater( "HTML Help" ), | ||
293 | mWebBrowser( 0 ), | ||
294 | mStatusTextContents( "" ), | ||
295 | mCurrentUrl( "" ) | ||
296 | { | ||
297 | sInstance = this; | ||
298 | |||
299 | // create floater from its XML definition | ||
300 | gUICtrlFactory->buildFloater( this, "floater_html_help.xml" ); | ||
301 | |||
302 | childSetAction("back_btn", onClickBack, this); | ||
303 | childSetAction("home_btn", onClickHome, this); | ||
304 | childSetAction("forward_btn", onClickForward, this); | ||
305 | |||
306 | if (!title.empty()) | ||
307 | { | ||
308 | setTitle(title); | ||
309 | } | ||
310 | |||
311 | mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "html_help_browser" ); | ||
312 | if ( mWebBrowser ) | ||
313 | { | ||
314 | // observe browser control events | ||
315 | mWebBrowser->addObserver( this ); | ||
316 | |||
317 | if (start_url != "") | ||
318 | { | ||
319 | mWebBrowser->navigateTo( start_url ); | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | // if the last page we were at before the client was closed is valid, go there and | ||
324 | // override what is in the XML file | ||
325 | // (not when the window was closed - it's only ever hidden - not closed) | ||
326 | LLString lastPageUrl = gSavedSettings.getString( "HtmlHelpLastPage" ); | ||
327 | if ( lastPageUrl != "" ) | ||
328 | { | ||
329 | mWebBrowser->navigateTo( lastPageUrl ); | ||
330 | }; | ||
331 | } | ||
332 | }; | ||
333 | } | ||
334 | |||
335 | //////////////////////////////////////////////////////////////////////////////// | ||
336 | // | ||
337 | LLFloaterHtmlHelp::~LLFloaterHtmlHelp() | ||
338 | { | ||
339 | // stop observing browser events | ||
340 | if ( mWebBrowser ) | ||
341 | { | ||
342 | mWebBrowser->remObserver( this ); | ||
343 | }; | ||
344 | |||
345 | // save position of floater | ||
346 | gSavedSettings.setRect( "HtmlHelpRect", getRect() ); | ||
347 | |||
348 | // save the location we were at when SL closed | ||
349 | gSavedSettings.setString( "HtmlHelpLastPage", mCurrentUrl ); | ||
350 | |||
351 | sInstance = 0; | ||
352 | } | ||
353 | |||
354 | //////////////////////////////////////////////////////////////////////////////// | ||
355 | // virtual | ||
356 | void LLFloaterHtmlHelp::draw() | ||
357 | { | ||
358 | // enable/disable buttons depending on state | ||
359 | if ( mWebBrowser ) | ||
360 | { | ||
361 | bool enable_back = mWebBrowser->canNavigateBack(); | ||
362 | childSetEnabled( "back_btn", enable_back ); | ||
363 | |||
364 | bool enable_forward = mWebBrowser->canNavigateForward(); | ||
365 | childSetEnabled( "forward_btn", enable_forward ); | ||
366 | }; | ||
367 | |||
368 | LLFloater::draw(); | ||
369 | } | ||
370 | |||
371 | //////////////////////////////////////////////////////////////////////////////// | ||
372 | // | ||
373 | void LLFloaterHtmlHelp::show(std::string url, std::string title) | ||
374 | { | ||
375 | gViewerWindow->alertXml("ClickOpenF1Help", onClickF1HelpLoadURL, (void*) NULL); | ||
376 | |||
377 | // switching this out for the moment - will come back later | ||
378 | // want it still to be compiled so not using comments of #if 0 | ||
379 | if ( false ) | ||
380 | { | ||
381 | sFloaterOpened = true; | ||
382 | |||
383 | if ( sInstance ) | ||
384 | { | ||
385 | if (sInstance->mWebBrowser) | ||
386 | { | ||
387 | sInstance->mWebBrowser->navigateTo(url); | ||
388 | } | ||
389 | sInstance->setVisibleAndFrontmost(); | ||
390 | return; | ||
391 | } | ||
392 | |||
393 | LLFloaterHtmlHelp* self = new LLFloaterHtmlHelp(url, title); | ||
394 | |||
395 | // reposition floater from saved settings | ||
396 | LLRect rect = gSavedSettings.getRect( "HtmlHelpRect" ); | ||
397 | self->reshape( rect.getWidth(), rect.getHeight(), FALSE ); | ||
398 | self->setRect( rect ); | ||
399 | }; | ||
400 | } | ||
401 | |||
402 | // static | ||
403 | void LLFloaterHtmlHelp::onClickF1HelpLoadURL(S32 option, void* userdata) | ||
404 | { | ||
405 | if (option == 0) | ||
406 | { | ||
407 | // choose HELP url based on selected language - default to english language support page | ||
408 | LLString lang = LLUI::sConfigGroup->getString("Language"); | ||
409 | |||
410 | // this sucks but there isn't a way to grab an arbitrary string from an XML file | ||
411 | // (using llcontroldef strings causes problems if string don't exist) | ||
412 | LLString help_url( "http://secondlife.com/support" ); | ||
413 | if ( lang == "ja" ) | ||
414 | help_url = "http://help.secondlife.com/jp"; | ||
415 | else | ||
416 | if ( lang == "ko" ) | ||
417 | help_url = "http://help.secondlife.com/kr"; | ||
418 | else | ||
419 | if ( lang == "pt" ) | ||
420 | help_url = "http://help.secondlife.com/pt"; | ||
421 | else | ||
422 | if ( lang == "de" ) | ||
423 | help_url = "http://de.secondlife.com/support"; | ||
424 | |||
425 | LLWeb::loadURL( help_url ); | ||
426 | }; | ||
427 | } | ||
428 | |||
429 | //////////////////////////////////////////////////////////////////////////////// | ||
430 | // | ||
431 | void LLFloaterHtmlHelp::onClose( bool app_quitting ) | ||
432 | { | ||
433 | setVisible( false ); | ||
434 | } | ||
435 | |||
436 | //////////////////////////////////////////////////////////////////////////////// | ||
437 | // | ||
438 | void LLFloaterHtmlHelp::onClickClose( void* data ) | ||
439 | { | ||
440 | LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; | ||
441 | |||
442 | self->setVisible( false ); | ||
443 | } | ||
444 | |||
445 | //////////////////////////////////////////////////////////////////////////////// | ||
446 | // | ||
447 | void LLFloaterHtmlHelp::onClickBack( void* data ) | ||
448 | { | ||
449 | LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; | ||
450 | if ( self ) | ||
451 | { | ||
452 | if ( self->mWebBrowser ) | ||
453 | { | ||
454 | self->mWebBrowser->navigateBack(); | ||
455 | }; | ||
456 | }; | ||
457 | } | ||
458 | |||
459 | //////////////////////////////////////////////////////////////////////////////// | ||
460 | // | ||
461 | void LLFloaterHtmlHelp::onClickHome( void* data ) | ||
462 | { | ||
463 | LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; | ||
464 | if ( self ) | ||
465 | { | ||
466 | // get the home page URL (which can differ from the start URL) from XML and go there | ||
467 | LLWebBrowserCtrl* web_browser = LLViewerUICtrlFactory::getWebBrowserByName( self, "html_help_browser" ); | ||
468 | if ( web_browser ) | ||
469 | { | ||
470 | web_browser->navigateHome(); | ||
471 | }; | ||
472 | }; | ||
473 | } | ||
474 | |||
475 | //////////////////////////////////////////////////////////////////////////////// | ||
476 | // | ||
477 | void LLFloaterHtmlHelp::onClickForward( void* data ) | ||
478 | { | ||
479 | LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; | ||
480 | if ( self ) | ||
481 | { | ||
482 | if ( self->mWebBrowser ) | ||
483 | { | ||
484 | self->mWebBrowser->navigateForward(); | ||
485 | }; | ||
486 | }; | ||
487 | } | ||
488 | |||
489 | //////////////////////////////////////////////////////////////////////////////// | ||
490 | // | ||
491 | void LLFloaterHtmlHelp::onStatusTextChange( const EventType& eventIn ) | ||
492 | { | ||
493 | mStatusTextContents = LLString( eventIn.getStringValue() ); | ||
494 | |||
495 | childSetText("status_text", mStatusTextContents); | ||
496 | } | ||
497 | |||
498 | //////////////////////////////////////////////////////////////////////////////// | ||
499 | // | ||
500 | void LLFloaterHtmlHelp::onLocationChange( const EventType& eventIn ) | ||
501 | { | ||
502 | llinfos << "MOZ> Location changed to " << eventIn.getStringValue() << llendl; | ||
503 | mCurrentUrl = LLString( eventIn.getStringValue() ); | ||
504 | } | ||
505 | |||
506 | //////////////////////////////////////////////////////////////////////////////// | ||
507 | // | ||
508 | LLViewerHtmlHelp::LLViewerHtmlHelp() | ||
509 | { | ||
510 | LLUI::setHtmlHelp(this); | ||
511 | } | ||
512 | |||
513 | LLViewerHtmlHelp::~LLViewerHtmlHelp() | ||
514 | { | ||
515 | LLUI::setHtmlHelp(NULL); | ||
516 | } | ||
517 | |||
518 | void LLViewerHtmlHelp::show(std::string url, std::string title) | ||
519 | { | ||
520 | LLFloaterHtmlHelp::show(url, title); | ||
521 | } | ||
522 | |||
523 | BOOL LLViewerHtmlHelp::getFloaterOpened() | ||
524 | { | ||
525 | return LLFloaterHtmlHelp::sFloaterOpened; | ||
526 | } | ||
527 | |||
528 | |||