diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llpanellogin.cpp | 769 |
1 files changed, 769 insertions, 0 deletions
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp new file mode 100644 index 0000000..3d3aee9 --- /dev/null +++ b/linden/indra/newview/llpanellogin.cpp | |||
@@ -0,0 +1,769 @@ | |||
1 | /** | ||
2 | * @file llpanellogin.cpp | ||
3 | * @brief Login dialog and logo display | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llpanellogin.h" | ||
31 | #include "llpanelgeneral.h" | ||
32 | |||
33 | #include "indra_constants.h" // for key and mask constants | ||
34 | #include "llfontgl.h" | ||
35 | #include "llmd5.h" | ||
36 | #include "llsecondlifeurls.h" | ||
37 | #include "llwindow.h" // shell_open() | ||
38 | #include "llversion.h" | ||
39 | #include "v4color.h" | ||
40 | |||
41 | #include "llbutton.h" | ||
42 | #include "llcheckboxctrl.h" | ||
43 | #include "llcombobox.h" | ||
44 | #include "llviewercontrol.h" | ||
45 | #include "llfloaterabout.h" | ||
46 | #include "llfloaterpreference.h" | ||
47 | #include "llfocusmgr.h" | ||
48 | #include "lllineeditor.h" | ||
49 | #include "lltextbox.h" | ||
50 | #include "llui.h" | ||
51 | #include "lluiconstants.h" | ||
52 | #include "llviewerbuild.h" | ||
53 | #include "llviewerimagelist.h" | ||
54 | #include "llviewermenu.h" // for handle_preferences() | ||
55 | #include "llviewernetwork.h" | ||
56 | #include "llviewerwindow.h" // to link into child list | ||
57 | #include "llnotify.h" | ||
58 | #include "viewer.h" // for gHideLinks | ||
59 | #include "llvieweruictrlfactory.h" | ||
60 | #include "llhttpclient.h" | ||
61 | #include "llweb.h" | ||
62 | #include "llwebbrowserctrl.h" | ||
63 | |||
64 | #include "llfloaterhtmlhelp.h" | ||
65 | #include "llfloatertos.h" | ||
66 | |||
67 | #include "llglheaders.h" | ||
68 | |||
69 | const S32 BLACK_BORDER_HEIGHT = 160; | ||
70 | const S32 MAX_PASSWORD = 16; | ||
71 | |||
72 | LLPanelLogin *LLPanelLogin::sInstance = NULL; | ||
73 | BOOL LLPanelLogin::sCapslockDidNotification = FALSE; | ||
74 | |||
75 | // helper class that trys to download a URL from a web site and calls a method | ||
76 | // on parent class indicating if the web server is working or not | ||
77 | class LLIamHereLogin : public LLHTTPClient::Responder | ||
78 | { | ||
79 | private: | ||
80 | LLIamHereLogin( LLPanelLogin* parent ) : | ||
81 | mParent( parent ) | ||
82 | {} | ||
83 | |||
84 | LLPanelLogin* mParent; | ||
85 | |||
86 | public: | ||
87 | static boost::intrusive_ptr< LLIamHereLogin > build( LLPanelLogin* parent ) | ||
88 | { | ||
89 | return boost::intrusive_ptr< LLIamHereLogin >( new LLIamHereLogin( parent ) ); | ||
90 | }; | ||
91 | |||
92 | virtual void setParent( LLPanelLogin* parentIn ) | ||
93 | { | ||
94 | mParent = parentIn; | ||
95 | }; | ||
96 | |||
97 | virtual void result( const LLSD& content ) | ||
98 | { | ||
99 | if ( mParent ) | ||
100 | mParent->setSiteIsAlive( true ); | ||
101 | }; | ||
102 | |||
103 | virtual void error( U32 status, const std::string& reason ) | ||
104 | { | ||
105 | if ( mParent ) | ||
106 | mParent->setSiteIsAlive( false ); | ||
107 | }; | ||
108 | }; | ||
109 | |||
110 | // this is global and not a class member to keep crud out of the header file | ||
111 | namespace { | ||
112 | boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0; | ||
113 | }; | ||
114 | |||
115 | //--------------------------------------------------------------------------- | ||
116 | // Public methods | ||
117 | //--------------------------------------------------------------------------- | ||
118 | LLPanelLogin::LLPanelLogin(const LLRect &rect, | ||
119 | BOOL show_server, | ||
120 | void (*callback)(S32 option, void* user_data), | ||
121 | void *cb_data) | ||
122 | : LLPanel("panel_login", LLRect(0,600,800,0), FALSE), // not bordered | ||
123 | mLogoImage(), | ||
124 | mCallback(callback), | ||
125 | mCallbackData(cb_data), | ||
126 | mHtmlAvailable( TRUE ) | ||
127 | { | ||
128 | mIsFocusRoot = TRUE; | ||
129 | mMungedPassword[0] = '\0'; | ||
130 | mIncomingPassword[0] = '\0'; | ||
131 | |||
132 | setBackgroundVisible(FALSE); | ||
133 | setBackgroundOpaque(TRUE); | ||
134 | |||
135 | // instance management | ||
136 | if (LLPanelLogin::sInstance) | ||
137 | { | ||
138 | llwarns << "Duplicate instance of login view deleted" << llendl; | ||
139 | delete LLPanelLogin::sInstance; | ||
140 | } | ||
141 | |||
142 | LLPanelLogin::sInstance = this; | ||
143 | |||
144 | // add to front so we are the bottom-most child | ||
145 | gViewerWindow->getRootView()->addChildAtEnd(this); | ||
146 | |||
147 | // Logo | ||
148 | mLogoImage = gImageList.getImage("startup_logo.tga", LLUUID::null, MIPMAP_FALSE, TRUE); | ||
149 | |||
150 | gUICtrlFactory->buildPanel(this, "panel_login.xml"); | ||
151 | setRect(rect); | ||
152 | reshape(rect.getWidth(), rect.getHeight()); | ||
153 | |||
154 | childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace); | ||
155 | childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace); | ||
156 | |||
157 | childSetCommitCallback("password_edit", mungePassword); | ||
158 | childSetKeystrokeCallback("password_edit", onPassKey, this); | ||
159 | childSetUserData("password_edit", this); | ||
160 | |||
161 | LLLineEditor* edit = LLUICtrlFactory::getLineEditorByName(this, "password_edit"); | ||
162 | if (edit) edit->setDrawAsterixes(TRUE); | ||
163 | |||
164 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(this, "start_location_combo"); | ||
165 | if (combo) | ||
166 | { | ||
167 | combo->setAllowTextEntry(TRUE, 128, FALSE); | ||
168 | |||
169 | // The XML file loads the combo with the following labels: | ||
170 | // 0 - "My Home" | ||
171 | // 1 - "My Last Location" | ||
172 | // 2 - "<Type region name>" | ||
173 | |||
174 | BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); | ||
175 | LLString sim_string = LLURLSimString::sInstance.mSimString; | ||
176 | if (!sim_string.empty()) | ||
177 | { | ||
178 | // Replace "<Type region name>" with this region name | ||
179 | combo->remove(2); | ||
180 | combo->add( sim_string ); | ||
181 | combo->setTextEntry(sim_string); | ||
182 | combo->setCurrentByIndex( 2 ); | ||
183 | } | ||
184 | else if (login_last) | ||
185 | { | ||
186 | combo->setCurrentByIndex( 1 ); | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | combo->setCurrentByIndex( 0 ); | ||
191 | } | ||
192 | |||
193 | combo->setCommitCallback( &LLPanelGeneral::set_start_location ); | ||
194 | } | ||
195 | |||
196 | // Specific servers added later. | ||
197 | childSetVisible("server_combo", show_server); | ||
198 | |||
199 | childSetAction("new_account_btn", onClickNewAccount, this); | ||
200 | childSetVisible("new_account_btn", !gHideLinks); | ||
201 | |||
202 | childSetAction("connect_btn", onClickConnect, this); | ||
203 | |||
204 | setDefaultBtn("connect_btn"); | ||
205 | |||
206 | childSetAction("preferences_btn", LLFloaterPreference::show, this); | ||
207 | |||
208 | childSetAction("quit_btn", onClickQuit, this); | ||
209 | |||
210 | LLTextBox* text = LLUICtrlFactory::getTextBoxByName(this, "version_text"); | ||
211 | if (text) | ||
212 | { | ||
213 | LLString version = llformat("%d.%d.%d (%d)", | ||
214 | LL_VERSION_MAJOR, | ||
215 | LL_VERSION_MINOR, | ||
216 | LL_VERSION_PATCH, | ||
217 | LL_VIEWER_BUILD ); | ||
218 | text->setText(version); | ||
219 | text->setClickedCallback(onClickVersion); | ||
220 | text->setCallbackUserData(this); | ||
221 | |||
222 | // HACK | ||
223 | S32 right = getRect().mRight; | ||
224 | LLRect r = text->getRect(); | ||
225 | const S32 PAD = 2; | ||
226 | r.setOriginAndSize( right - r.getWidth() - PAD, PAD, | ||
227 | r.getWidth(), r.getHeight() ); | ||
228 | text->setRect(r); | ||
229 | } | ||
230 | |||
231 | // get the web browser control | ||
232 | #if LL_LIBXUL_ENABLED | ||
233 | LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); | ||
234 | if ( web_browser ) | ||
235 | { | ||
236 | // don't make it a tab stop until SL-27594 is fixed | ||
237 | web_browser->setTabStop(FALSE); | ||
238 | |||
239 | // painfully build the path to the loading screen | ||
240 | std::string loading_path( gDirUtilp->getExpandedFilename( LL_PATH_SKINS, "" ) ); | ||
241 | loading_path.append( gDirUtilp->getDirDelimiter() ); | ||
242 | loading_path.append( "html" ); | ||
243 | loading_path.append( gDirUtilp->getDirDelimiter() ); | ||
244 | loading_path.append( "loading" ); | ||
245 | loading_path.append( gDirUtilp->getDirDelimiter() ); | ||
246 | loading_path.append( "loading.html" ); | ||
247 | web_browser->navigateTo( loading_path.c_str() ); | ||
248 | |||
249 | // make links open in external browser | ||
250 | web_browser->setOpenInExternalBrowser( true ); | ||
251 | |||
252 | // force the size to be correct (XML doesn't seem to be sufficient to do this) (with some padding so the other login screen doesn't show through) | ||
253 | LLRect htmlRect = mRect; | ||
254 | htmlRect.setCenterAndSize( mRect.getCenterX() - 2, mRect.getCenterY() + 40, mRect.getWidth() + 6, mRect.getHeight() - 78 ); | ||
255 | web_browser->setRect( htmlRect ); | ||
256 | web_browser->reshape( htmlRect.getWidth(), htmlRect.getHeight(), TRUE ); | ||
257 | reshape( mRect.getWidth(), mRect.getHeight(), 1 ); | ||
258 | |||
259 | // kick off a request to grab the url manually | ||
260 | gResponsePtr = LLIamHereLogin::build( this ); | ||
261 | LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr ); | ||
262 | }; | ||
263 | #else | ||
264 | mHtmlAvailable = FALSE; | ||
265 | #endif | ||
266 | |||
267 | // Initialize visibility (and don't force visibility - use prefs) | ||
268 | refreshLocation( false ); | ||
269 | } | ||
270 | |||
271 | void LLPanelLogin::setSiteIsAlive( bool alive ) | ||
272 | { | ||
273 | #if LL_LIBXUL_ENABLED | ||
274 | LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); | ||
275 | // if the contents of the site was retrieved | ||
276 | if ( alive ) | ||
277 | { | ||
278 | if ( web_browser ) | ||
279 | { | ||
280 | // navigate to the "real" page | ||
281 | web_browser->navigateTo( childGetValue( "real_url" ).asString() ); | ||
282 | |||
283 | // mark as available | ||
284 | mHtmlAvailable = TRUE; | ||
285 | }; | ||
286 | } | ||
287 | else | ||
288 | // the site is not available (missing page, server down, other badness) | ||
289 | { | ||
290 | if ( web_browser ) | ||
291 | { | ||
292 | // hide browser control (revealing default one) | ||
293 | web_browser->setVisible( FALSE ); | ||
294 | |||
295 | // mark as unavailable | ||
296 | mHtmlAvailable = FALSE; | ||
297 | }; | ||
298 | }; | ||
299 | #else | ||
300 | mHtmlAvailable = FALSE; | ||
301 | #endif | ||
302 | } | ||
303 | |||
304 | void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data) | ||
305 | { | ||
306 | LLPanelLogin* self = (LLPanelLogin*)user_data; | ||
307 | LLLineEditor* editor = (LLLineEditor*)caller; | ||
308 | std::string password = editor->getText(); | ||
309 | |||
310 | // Re-md5 if we've changed at all | ||
311 | if (password != self->mIncomingPassword) | ||
312 | { | ||
313 | LLMD5 pass((unsigned char *)password.c_str()); | ||
314 | pass.hex_digest(self->mMungedPassword); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | LLPanelLogin::~LLPanelLogin() | ||
319 | { | ||
320 | LLPanelLogin::sInstance = NULL; | ||
321 | |||
322 | // tell the responder we're not here anymore | ||
323 | if ( gResponsePtr ) | ||
324 | gResponsePtr->setParent( 0 ); | ||
325 | |||
326 | // We know we're done with the image, so be rid of it. | ||
327 | gImageList.deleteImage( mLogoImage ); | ||
328 | } | ||
329 | |||
330 | // virtual | ||
331 | void LLPanelLogin::draw() | ||
332 | { | ||
333 | if (!getVisible()) return; | ||
334 | |||
335 | BOOL target_fullscreen; | ||
336 | S32 target_width; | ||
337 | S32 target_height; | ||
338 | gViewerWindow->getTargetWindow(target_fullscreen, target_width, target_height); | ||
339 | |||
340 | childSetVisible("full_screen_text", target_fullscreen); | ||
341 | |||
342 | glPushMatrix(); | ||
343 | { | ||
344 | F32 image_aspect = 1.333333f; | ||
345 | F32 view_aspect = (F32)mRect.getWidth() / (F32)mRect.getHeight(); | ||
346 | // stretch image to maintain aspect ratio | ||
347 | if (image_aspect > view_aspect) | ||
348 | { | ||
349 | glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * mRect.getWidth(), 0.f, 0.f); | ||
350 | glScalef(image_aspect / view_aspect, 1.f, 1.f); | ||
351 | } | ||
352 | // Don't maintain aspect ratio if screen wider than image. This results in the | ||
353 | // hand being partially cut off. JC | ||
354 | //else | ||
355 | //{ | ||
356 | // glTranslatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * (F32)BLACK_BORDER_HEIGHT, 0.f); | ||
357 | // glScalef(1.f, view_aspect / image_aspect, 1.f); | ||
358 | //} | ||
359 | |||
360 | S32 width = mRect.getWidth(); | ||
361 | S32 height = mRect.getHeight(); | ||
362 | |||
363 | if ( mHtmlAvailable ) | ||
364 | { | ||
365 | // draw a background box in black | ||
366 | gl_rect_2d( 0, height - 264, width, 264, LLColor4( 0.0f, 0.0f, 0.0f, 1.f ) ); | ||
367 | |||
368 | // draw the bottom part of the background image - just the blue background to the native client UI | ||
369 | gl_draw_scaled_image(0, -264, width + 8, mLogoImage->getHeight(), mLogoImage); | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | // the HTML login page is not available so default to the original screen | ||
374 | S32 offscreen_part = height / 3; | ||
375 | gl_draw_scaled_image(0, -offscreen_part, width, height+offscreen_part, mLogoImage); | ||
376 | }; | ||
377 | } | ||
378 | glPopMatrix(); | ||
379 | |||
380 | LLPanel::draw(); | ||
381 | } | ||
382 | |||
383 | // virtual | ||
384 | BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | ||
385 | { | ||
386 | if (getVisible() && getEnabled()) | ||
387 | { | ||
388 | if (( KEY_RETURN == key ) && (MASK_ALT == mask)) | ||
389 | { | ||
390 | gViewerWindow->toggleFullscreen(FALSE); | ||
391 | return TRUE; | ||
392 | } | ||
393 | |||
394 | if (('P' == key) && (MASK_CONTROL == mask)) | ||
395 | { | ||
396 | LLFloaterPreference::show(NULL); | ||
397 | return TRUE; | ||
398 | } | ||
399 | |||
400 | #if LL_LIBXUL_ENABLED | ||
401 | if ( KEY_F1 == key ) | ||
402 | { | ||
403 | llinfos << "Spawning HTML help window" << llendl; | ||
404 | LLHtmlHelp::show( ); | ||
405 | return TRUE; | ||
406 | }; | ||
407 | #if ! LL_RELEASE_FOR_DOWNLOAD | ||
408 | if ( KEY_F2 == key ) | ||
409 | { | ||
410 | llinfos << "Spawning floater TOS window" << llendl; | ||
411 | LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,""); | ||
412 | tos_dialog->startModal(); | ||
413 | return TRUE; | ||
414 | }; | ||
415 | #endif | ||
416 | #endif | ||
417 | |||
418 | if (!called_from_parent) | ||
419 | { | ||
420 | if (KEY_RETURN == key && MASK_NONE == mask) | ||
421 | { | ||
422 | // let the panel handle UICtrl processing: calls onClickConnect() | ||
423 | return LLPanel::handleKeyHere(key, mask, called_from_parent); | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | return LLPanel::handleKeyHere(key, mask, called_from_parent); | ||
429 | } | ||
430 | |||
431 | // virtual | ||
432 | void LLPanelLogin::setFocus(BOOL b) | ||
433 | { | ||
434 | if(b != hasFocus()) | ||
435 | { | ||
436 | if(b) | ||
437 | { | ||
438 | LLPanelLogin::giveFocus(); | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | LLPanel::setFocus(b); | ||
443 | } | ||
444 | } | ||
445 | } | ||
446 | |||
447 | // static | ||
448 | void LLPanelLogin::giveFocus() | ||
449 | { | ||
450 | if( sInstance ) | ||
451 | { | ||
452 | // Grab focus and move cursor to first blank input field | ||
453 | std::string first = sInstance->childGetText("first_name_edit"); | ||
454 | std::string pass = sInstance->childGetText("password_edit"); | ||
455 | |||
456 | BOOL have_first = !first.empty(); | ||
457 | BOOL have_pass = !pass.empty(); | ||
458 | |||
459 | LLLineEditor* edit = NULL; | ||
460 | if (have_first && !have_pass) | ||
461 | { | ||
462 | // User saved his name but not his password. Move | ||
463 | // focus to password field. | ||
464 | edit = LLUICtrlFactory::getLineEditorByName(sInstance, "password_edit"); | ||
465 | } | ||
466 | else | ||
467 | { | ||
468 | // User doesn't have a name, so start there. | ||
469 | edit = LLUICtrlFactory::getLineEditorByName(sInstance, "first_name_edit"); | ||
470 | } | ||
471 | |||
472 | if (edit) | ||
473 | { | ||
474 | edit->setFocus(TRUE); | ||
475 | edit->selectAll(); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | |||
480 | |||
481 | // static | ||
482 | void LLPanelLogin::show(const LLRect &rect, | ||
483 | BOOL show_server, | ||
484 | void (*callback)(S32 option, void* user_data), | ||
485 | void* callback_data) | ||
486 | { | ||
487 | new LLPanelLogin(rect, show_server, callback, callback_data); | ||
488 | |||
489 | if( !gFocusMgr.getKeyboardFocus() ) | ||
490 | { | ||
491 | // Grab focus and move cursor to first enabled control | ||
492 | sInstance->setFocus(TRUE); | ||
493 | // make sure that focus always goes here | ||
494 | gFocusMgr.setDefaultKeyboardFocus(sInstance); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | // static | ||
499 | void LLPanelLogin::setFields(const std::string& firstname, const std::string& lastname, const std::string& password, | ||
500 | BOOL remember) | ||
501 | { | ||
502 | if (!sInstance) | ||
503 | { | ||
504 | llwarns << "Attempted fillFields with no login view shown" << llendl; | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | sInstance->childSetText("first_name_edit", firstname); | ||
509 | sInstance->childSetText("last_name_edit", lastname); | ||
510 | |||
511 | // Max "actual" password length is 16 characters. | ||
512 | // Hex digests are always 32 characters. | ||
513 | if (password.length() == 32) | ||
514 | { | ||
515 | // This is a MD5 hex digest of a password. | ||
516 | // We don't actually use the password input field, | ||
517 | // fill it with MAX_PASSWORD characters so we get a | ||
518 | // nice row of asterixes. | ||
519 | const char* filler = "123456789!123456"; | ||
520 | sInstance->childSetText("password_edit", filler); | ||
521 | strcpy(sInstance->mIncomingPassword, filler); | ||
522 | strcpy(sInstance->mMungedPassword, password.c_str()); | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | // this is a normal text password | ||
527 | sInstance->childSetText("password_edit", password); | ||
528 | strcpy(sInstance->mIncomingPassword, password.c_str()); | ||
529 | LLMD5 pass((unsigned char *)password.c_str()); | ||
530 | pass.hex_digest(sInstance->mMungedPassword); | ||
531 | } | ||
532 | |||
533 | sInstance->childSetValue("remember_check", remember); | ||
534 | } | ||
535 | |||
536 | |||
537 | // static | ||
538 | void LLPanelLogin::addServer(const char *server, S32 domain_name) | ||
539 | { | ||
540 | if (!sInstance) | ||
541 | { | ||
542 | llwarns << "Attempted addServer with no login view shown" << llendl; | ||
543 | return; | ||
544 | } | ||
545 | |||
546 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); | ||
547 | if (combo) | ||
548 | { | ||
549 | combo->add(server, LLSD(domain_name) ); | ||
550 | combo->setCurrentByIndex(0); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | // static | ||
555 | void LLPanelLogin::getFields(LLString &firstname, LLString &lastname, LLString &password, | ||
556 | BOOL &remember) | ||
557 | { | ||
558 | if (!sInstance) | ||
559 | { | ||
560 | llwarns << "Attempted getFields with no login view shown" << llendl; | ||
561 | return; | ||
562 | } | ||
563 | |||
564 | firstname = sInstance->childGetText("first_name_edit"); | ||
565 | LLString::trim(firstname); | ||
566 | |||
567 | lastname = sInstance->childGetText("last_name_edit"); | ||
568 | LLString::trim(lastname); | ||
569 | |||
570 | password.assign( sInstance->mMungedPassword ); | ||
571 | remember = sInstance->childGetValue("remember_check"); | ||
572 | } | ||
573 | |||
574 | |||
575 | // static | ||
576 | void LLPanelLogin::getServer(LLString &server, S32 &domain_name) | ||
577 | { | ||
578 | if (!sInstance) | ||
579 | { | ||
580 | llwarns << "Attempted getServer with no login view shown" << llendl; | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); | ||
585 | if (combo) | ||
586 | { | ||
587 | LLSD combo_val = combo->getValue(); | ||
588 | if (LLSD::TypeInteger == combo_val.type()) | ||
589 | { | ||
590 | domain_name = combo->getValue().asInteger(); | ||
591 | |||
592 | if ((S32)USERSERVER_OTHER == domain_name) | ||
593 | { | ||
594 | server = gUserServerName; | ||
595 | } | ||
596 | } | ||
597 | else | ||
598 | { | ||
599 | // no valid selection, return other | ||
600 | domain_name = (S32)USERSERVER_OTHER; | ||
601 | server = combo_val.asString(); | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | |||
606 | // static | ||
607 | void LLPanelLogin::getLocation(LLString &location) | ||
608 | { | ||
609 | if (!sInstance) | ||
610 | { | ||
611 | llwarns << "Attempted getLocation with no login view shown" << llendl; | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "start_location_combo"); | ||
616 | if (combo) | ||
617 | { | ||
618 | location = combo->getValue().asString(); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | // static | ||
623 | void LLPanelLogin::refreshLocation( bool force_visible ) | ||
624 | { | ||
625 | if (!sInstance) return; | ||
626 | |||
627 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "start_location_combo"); | ||
628 | if (!combo) return; | ||
629 | |||
630 | LLString sim_string = LLURLSimString::sInstance.mSimString; | ||
631 | if (!sim_string.empty()) | ||
632 | { | ||
633 | combo->setCurrentByIndex( 3 ); // BUG? Maybe 2? | ||
634 | combo->setTextEntry(sim_string); | ||
635 | } | ||
636 | else | ||
637 | { | ||
638 | BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation"); | ||
639 | combo->setCurrentByIndex( login_last ? 1 : 0 ); | ||
640 | } | ||
641 | |||
642 | BOOL show_start = TRUE; | ||
643 | |||
644 | if ( ! force_visible ) | ||
645 | show_start = gSavedSettings.getBOOL("ShowStartLocation"); | ||
646 | |||
647 | sInstance->childSetVisible("start_location_combo", show_start); | ||
648 | sInstance->childSetVisible("start_location_text", show_start); | ||
649 | } | ||
650 | |||
651 | // static | ||
652 | void LLPanelLogin::close() | ||
653 | { | ||
654 | if (sInstance) | ||
655 | { | ||
656 | gViewerWindow->getRootView()->removeChild( LLPanelLogin::sInstance ); | ||
657 | |||
658 | gFocusMgr.setDefaultKeyboardFocus(NULL); | ||
659 | |||
660 | delete sInstance; | ||
661 | sInstance = NULL; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | |||
666 | //--------------------------------------------------------------------------- | ||
667 | // Protected methods | ||
668 | //--------------------------------------------------------------------------- | ||
669 | |||
670 | // static | ||
671 | void LLPanelLogin::onClickConnect(void *) | ||
672 | { | ||
673 | if (sInstance && sInstance->mCallback) | ||
674 | { | ||
675 | // tell the responder we're not here anymore | ||
676 | if ( gResponsePtr ) | ||
677 | gResponsePtr->setParent( 0 ); | ||
678 | |||
679 | // JC - Make sure the fields all get committed. | ||
680 | sInstance->setFocus(FALSE); | ||
681 | |||
682 | LLString first = sInstance->childGetText("first_name_edit"); | ||
683 | LLString last = sInstance->childGetText("last_name_edit"); | ||
684 | if (!first.empty() && !last.empty()) | ||
685 | { | ||
686 | // has both first and last name typed | ||
687 | |||
688 | // store off custom server entry, if currently selected | ||
689 | LLComboBox* combo = LLUICtrlFactory::getComboBoxByName(sInstance, "server_combo"); | ||
690 | if (combo) | ||
691 | { | ||
692 | S32 selected_server = combo->getValue(); | ||
693 | if (selected_server == USERSERVER_NONE) | ||
694 | { | ||
695 | LLString custom_server = combo->getValue().asString(); | ||
696 | gSavedSettings.setString("CustomServer", custom_server); | ||
697 | } | ||
698 | } | ||
699 | sInstance->mCallback(0, sInstance->mCallbackData); | ||
700 | } | ||
701 | else | ||
702 | { | ||
703 | // empty first or last name | ||
704 | // same as clicking new account | ||
705 | onClickNewAccount(NULL); | ||
706 | } | ||
707 | } | ||
708 | } | ||
709 | |||
710 | |||
711 | // static | ||
712 | void LLPanelLogin::newAccountAlertCallback(S32 option, void*) | ||
713 | { | ||
714 | if (0 == option) | ||
715 | { | ||
716 | llinfos << "Going to account creation URL" << llendl; | ||
717 | LLWeb::loadURL( CREATE_ACCOUNT_URL ); | ||
718 | } | ||
719 | else | ||
720 | { | ||
721 | sInstance->setFocus(TRUE); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | |||
726 | // static | ||
727 | void LLPanelLogin::onClickNewAccount(void*) | ||
728 | { | ||
729 | if (gHideLinks) | ||
730 | { | ||
731 | gViewerWindow->alertXml("MustHaveAccountToLogInNoLinks"); | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | gViewerWindow->alertXml("MustHaveAccountToLogIn", | ||
736 | LLPanelLogin::newAccountAlertCallback); | ||
737 | } | ||
738 | } | ||
739 | |||
740 | |||
741 | // static | ||
742 | void LLPanelLogin::onClickQuit(void*) | ||
743 | { | ||
744 | if (sInstance && sInstance->mCallback) | ||
745 | { | ||
746 | // tell the responder we're not here anymore | ||
747 | if ( gResponsePtr ) | ||
748 | gResponsePtr->setParent( 0 ); | ||
749 | |||
750 | sInstance->mCallback(1, sInstance->mCallbackData); | ||
751 | } | ||
752 | } | ||
753 | |||
754 | |||
755 | // static | ||
756 | void LLPanelLogin::onClickVersion(void*) | ||
757 | { | ||
758 | LLFloaterAbout::show(NULL); | ||
759 | } | ||
760 | |||
761 | // static | ||
762 | void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) | ||
763 | { | ||
764 | if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE) | ||
765 | { | ||
766 | LLNotifyBox::showXml("CapsKeyOn"); | ||
767 | sCapslockDidNotification = TRUE; | ||
768 | } | ||
769 | } | ||