aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMcCabe Maxsted2011-03-22 01:59:52 -0700
committerMcCabe Maxsted2011-03-22 01:59:52 -0700
commit9e11339ee6be8161c676fe16c34edb5bc089a9bf (patch)
treeb6a2a1bd49a1ba4cc02a5898c1746e1df8327580
parentFixed tab order on login screen (diff)
downloadmeta-impy-9e11339ee6be8161c676fe16c34edb5bc089a9bf.zip
meta-impy-9e11339ee6be8161c676fe16c34edb5bc089a9bf.tar.gz
meta-impy-9e11339ee6be8161c676fe16c34edb5bc089a9bf.tar.bz2
meta-impy-9e11339ee6be8161c676fe16c34edb5bc089a9bf.tar.xz
Support username logins on Linden grids. Seems to cover most edge cases with our current grid manager, but really exposes the weaknesses of not saving login info with the grid, usability-wise. (Note: autologin and the command line need to be tested)
-rw-r--r--linden/indra/llui/lllineeditor.cpp20
-rw-r--r--linden/indra/llui/lllineeditor.h1
-rw-r--r--linden/indra/newview/hippogridmanager.cpp7
-rw-r--r--linden/indra/newview/hippogridmanager.h1
-rw-r--r--linden/indra/newview/llloginhandler.cpp20
-rw-r--r--linden/indra/newview/llpanellogin.cpp206
-rw-r--r--linden/indra/newview/llpanellogin.h20
-rw-r--r--linden/indra/newview/llstartup.cpp19
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/notifications.xml19
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_login.xml22
10 files changed, 315 insertions, 20 deletions
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp
index 76b8927..a21ad5d 100644
--- a/linden/indra/llui/lllineeditor.cpp
+++ b/linden/indra/llui/lllineeditor.cpp
@@ -2696,7 +2696,6 @@ BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
2696 return rv; 2696 return rv;
2697} 2697}
2698 2698
2699
2700// static 2699// static
2701BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str) 2700BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
2702{ 2701{
@@ -2721,6 +2720,25 @@ BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
2721} 2720}
2722 2721
2723// static 2722// static
2723BOOL LLLineEditor::prevalidatePrintableSpace(const LLWString &str)
2724{
2725 BOOL rv = TRUE;
2726 S32 len = str.length();
2727 if(len == 0) return rv;
2728 while(len--)
2729 {
2730 if( !(LLStringOps::isAlnum((char)str[len]) ||
2731 LLStringOps::isPunct((char)str[len]) ||
2732 ' ' == str[len]) )
2733 {
2734 rv = FALSE;
2735 break;
2736 }
2737 }
2738 return rv;
2739}
2740
2741// static
2724BOOL LLLineEditor::prevalidateASCII(const LLWString &str) 2742BOOL LLLineEditor::prevalidateASCII(const LLWString &str)
2725{ 2743{
2726 BOOL rv = TRUE; 2744 BOOL rv = TRUE;
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h
index d217859..43ce869 100644
--- a/linden/indra/llui/lllineeditor.h
+++ b/linden/indra/llui/lllineeditor.h
@@ -253,6 +253,7 @@ public:
253 static BOOL prevalidateAlphaNumSpace(const LLWString &str ); 253 static BOOL prevalidateAlphaNumSpace(const LLWString &str );
254 static BOOL prevalidatePrintableNotPipe(const LLWString &str); 254 static BOOL prevalidatePrintableNotPipe(const LLWString &str);
255 static BOOL prevalidatePrintableNoSpace(const LLWString &str); 255 static BOOL prevalidatePrintableNoSpace(const LLWString &str);
256 static BOOL prevalidatePrintableSpace(const LLWString &str);
256 static BOOL prevalidateASCII(const LLWString &str); 257 static BOOL prevalidateASCII(const LLWString &str);
257 258
258 static BOOL postvalidateFloat(const std::string &str); 259 static BOOL postvalidateFloat(const std::string &str);
diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp
index d56214c..a15f676 100644
--- a/linden/indra/newview/hippogridmanager.cpp
+++ b/linden/indra/newview/hippogridmanager.cpp
@@ -165,6 +165,13 @@ const std::string& HippoGridInfo::getRealCurrencySymbol() const
165 return mRealCurrencySymbol; 165 return mRealCurrencySymbol;
166} 166}
167 167
168bool HippoGridInfo::isUsernameCompat() const
169{
170 // currently only SecondLife grids support username-style logins
171 // but Aurora is working on implementing it -- MC
172 return (mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE);
173}
174
168 175
169 176
170// ******************************************************************** 177// ********************************************************************
diff --git a/linden/indra/newview/hippogridmanager.h b/linden/indra/newview/hippogridmanager.h
index 8429dba..1b6fbc5 100644
--- a/linden/indra/newview/hippogridmanager.h
+++ b/linden/indra/newview/hippogridmanager.h
@@ -55,6 +55,7 @@ public:
55 const std::string& getVoiceConnector() const { return mVoiceConnector; } 55 const std::string& getVoiceConnector() const { return mVoiceConnector; }
56 std::string getSearchUrl(SearchType ty, bool is_web) const; 56 std::string getSearchUrl(SearchType ty, bool is_web) const;
57 bool isRenderCompat() const; 57 bool isRenderCompat() const;
58 bool isUsernameCompat() const;
58 int getMaxAgentGroups() const { return mMaxAgentGroups; } 59 int getMaxAgentGroups() const { return mMaxAgentGroups; }
59 60
60 const std::string& getCurrencySymbol() const; 61 const std::string& getCurrencySymbol() const;
diff --git a/linden/indra/newview/llloginhandler.cpp b/linden/indra/newview/llloginhandler.cpp
index 30b05ef..c35ba04 100644
--- a/linden/indra/newview/llloginhandler.cpp
+++ b/linden/indra/newview/llloginhandler.cpp
@@ -35,6 +35,7 @@
35#include "llloginhandler.h" 35#include "llloginhandler.h"
36 36
37// viewer includes 37// viewer includes
38#include "hippogridmanager.h"
38#include "llpanellogin.h" // save_password_to_disk() 39#include "llpanellogin.h" // save_password_to_disk()
39#include "llstartup.h" // getStartupState() 40#include "llstartup.h" // getStartupState()
40#include "llurlsimstring.h" 41#include "llurlsimstring.h"
@@ -141,10 +142,27 @@ bool LLLoginHandler::handle(const LLSD& tokens,
141 142
142 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page 143 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
143 { 144 {
145 // if we ever support saving names based on grid, we'll have to support saving usernames too -- MC
146 LLPanelLogin::loadLoginForm();
147
144 if (!mFirstName.empty() || !mLastName.empty()) 148 if (!mFirstName.empty() || !mLastName.empty())
145 { 149 {
146 // Fill in the name, and maybe the password 150 // Fill in the name, and maybe the password
147 LLPanelLogin::setFields(mFirstName, mLastName, password); 151 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat())
152 {
153 if (mLastName == "resident" || mLastName == "Resident")
154 {
155 LLPanelLogin::setFields(mFirstName, password);
156 }
157 else
158 {
159 LLPanelLogin::setFields(mFirstName+"."+ mLastName, password);
160 }
161 }
162 else
163 {
164 LLPanelLogin::setFields(mFirstName, mLastName, password);
165 }
148 } 166 }
149 167
150 if (mWebLoginKey.isNull()) 168 if (mWebLoginKey.isNull())
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp
index 0b91091..ba5b963 100644
--- a/linden/indra/newview/llpanellogin.cpp
+++ b/linden/indra/newview/llpanellogin.cpp
@@ -81,6 +81,8 @@
81 81
82#include "llglheaders.h" 82#include "llglheaders.h"
83 83
84#include <boost/algorithm/string.hpp>
85
84// [RLVa:KB] 86// [RLVa:KB]
85#include "rlvhandler.h" 87#include "rlvhandler.h"
86// [/RLVa:KB] 88// [/RLVa:KB]
@@ -208,6 +210,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
208#if !USE_VIEWER_AUTH 210#if !USE_VIEWER_AUTH
209 childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace); 211 childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
210 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace); 212 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
213 childSetPrevalidate("username_edit", LLLineEditor::prevalidatePrintableSpace);
211 214
212 childSetCommitCallback("password_edit", mungePassword); 215 childSetCommitCallback("password_edit", mungePassword);
213 childSetKeystrokeCallback("password_edit", onPassKey, this); 216 childSetKeystrokeCallback("password_edit", onPassKey, this);
@@ -316,6 +319,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
316 refreshLocation( false ); 319 refreshLocation( false );
317#endif 320#endif
318 321
322 loadLoginForm();
323
319 loadNewsBar(); 324 loadNewsBar();
320 325
321 LLFirstUse::useLoginScreen(); 326 LLFirstUse::useLoginScreen();
@@ -551,6 +556,26 @@ void LLPanelLogin::show(const LLRect &rect,
551 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); 556 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel());
552} 557}
553 558
559
560// static
561void LLPanelLogin::setFields(const std::string& username, const std::string& password)
562{
563 if (!sInstance)
564 {
565 llwarns << "Attempted fillFields with no login view shown" << llendl;
566 return;
567 }
568
569 if (!gHippoGridManager->getCurrentGrid()->isUsernameCompat())
570 {
571 llwarns << "Trying to set a username for an incompatible grid!" << llendl;
572 return;
573 }
574
575 sInstance->childSetText("username_edit", username);
576 setPassword(password);
577}
578
554// static 579// static
555void LLPanelLogin::setFields(const std::string& firstname, 580void LLPanelLogin::setFields(const std::string& firstname,
556 const std::string& lastname, 581 const std::string& lastname,
@@ -564,7 +589,13 @@ void LLPanelLogin::setFields(const std::string& firstname,
564 589
565 sInstance->childSetText("first_name_edit", firstname); 590 sInstance->childSetText("first_name_edit", firstname);
566 sInstance->childSetText("last_name_edit", lastname); 591 sInstance->childSetText("last_name_edit", lastname);
592 setPassword(password);
593}
567 594
595
596// static
597void LLPanelLogin::setPassword(const std::string& password)
598{
568 // Max "actual" password length is 16 characters. 599 // Max "actual" password length is 16 characters.
569 // Hex digests are always 32 characters. 600 // Hex digests are always 32 characters.
570 if (password.length() == 32) 601 if (password.length() == 32)
@@ -663,11 +694,25 @@ void LLPanelLogin::getFields(std::string *firstname,
663 return; 694 return;
664 } 695 }
665 696
666 *firstname = sInstance->childGetText("first_name_edit"); 697 // SL grids use a generic one-line text entry field for logins
667 LLStringUtil::trim(*firstname); 698 std::string username = sInstance->childGetText("username_edit");
699 if (!username.empty() && gHippoGridManager->getConnectedGrid()->isUsernameCompat())
700 {
701 // no need to trim here, spaces are removed
702 if (!convertUsernameToLegacy(username, *firstname, *lastname))
703 {
704 llerrs << "Invalid username accepted! Cannot proceed!" << llendl;
705 return;
706 }
707 }
708 else
709 {
710 *firstname = sInstance->childGetText("first_name_edit");
711 LLStringUtil::trim(*firstname);
668 712
669 *lastname = sInstance->childGetText("last_name_edit"); 713 *lastname = sInstance->childGetText("last_name_edit");
670 LLStringUtil::trim(*lastname); 714 LLStringUtil::trim(*lastname);
715 }
671 716
672 *password = sInstance->mMungedPassword; 717 *password = sInstance->mMungedPassword;
673} 718}
@@ -802,6 +847,54 @@ void LLPanelLogin::refreshLoginPage()
802} 847}
803 848
804 849
850// static
851void LLPanelLogin::loadLoginForm()
852{
853 if (!sInstance) return;
854
855 // toggle between username/first+last login based on grid -- MC
856 LLTextBox* firstnamet = sInstance->getChild<LLTextBox>("first_name_text");
857 LLTextBox* lastnamet = sInstance->getChild<LLTextBox>("last_name_text");
858 LLTextBox* usernamet = sInstance->getChild<LLTextBox>("username_text");
859
860 LLLineEditor* firstnamel = sInstance->getChild<LLLineEditor>("first_name_edit");
861 LLLineEditor* lastnamel = sInstance->getChild<LLLineEditor>("last_name_edit");
862 LLLineEditor* usernamel = sInstance->getChild<LLLineEditor>("username_edit");
863
864 firstnamet->setVisible(!gHippoGridManager->getCurrentGrid()->isUsernameCompat());
865 lastnamet->setVisible(!gHippoGridManager->getCurrentGrid()->isUsernameCompat());
866 usernamet->setVisible(gHippoGridManager->getCurrentGrid()->isUsernameCompat());
867
868 firstnamel->setVisible(!gHippoGridManager->getCurrentGrid()->isUsernameCompat());
869 lastnamel->setVisible(!gHippoGridManager->getCurrentGrid()->isUsernameCompat());
870 usernamel->setVisible(gHippoGridManager->getCurrentGrid()->isUsernameCompat());
871
872 // these should really REALLY be stored in the grid info -- MC
873 std::string firstnames = gSavedSettings.getString("FirstName");
874 std::string lastnames = gSavedSettings.getString("LastName");
875 if (!firstnames.empty() && !lastnames.empty())
876 {
877 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat())
878 {
879 if (lastnames == "resident" || lastnames == "Resident")
880 {
881 usernamel->setText(firstnames);
882 }
883 else
884 {
885 usernamel->setText(firstnames+"."+lastnames);
886 }
887 }
888 else
889 {
890 firstnamel->setText(firstnames);
891 lastnamel->setText(lastnames);
892 }
893 }
894}
895
896
897// static
805void LLPanelLogin::loadLoginPage() 898void LLPanelLogin::loadLoginPage()
806{ 899{
807 if (!sInstance) return; 900 if (!sInstance) return;
@@ -972,6 +1065,63 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
972//--------------------------------------------------------------------------- 1065//---------------------------------------------------------------------------
973 1066
974// static 1067// static
1068bool LLPanelLogin::convertUsernameToLegacy(std::string& username, std::string& firstname, std::string& lastname)
1069{
1070 if (!username.empty())
1071 {
1072 // trim beginning and end
1073 LLStringUtil::trim(username);
1074
1075 // minimum length for an SL grid
1076 if (username.length() < 5)
1077 {
1078 return false;
1079 }
1080 }
1081 else
1082 {
1083 return false;
1084 }
1085
1086 std::vector<std::string> names;
1087 boost::algorithm::split(names, username, boost::is_any_of(" ."));
1088
1089 // maybe they typed in a few too many spaces?
1090 if (names.size() > 2)
1091 {
1092 std::vector<std::string>::iterator vIt = names.begin();
1093 while (vIt != names.end())
1094 {
1095 if ((*vIt).empty())
1096 {
1097 vIt = names.erase(vIt);
1098 }
1099 else
1100 {
1101 ++vIt;
1102 }
1103 }
1104 }
1105
1106 if (names.size() == 1) // username
1107 {
1108 firstname = names[0];
1109 lastname = "Resident";
1110 return true;
1111 }
1112 else if (names.size() == 2) // first.last or first+" "+last
1113 {
1114 firstname = names[0];
1115 lastname = names[1];
1116 return true;
1117 }
1118 else
1119 {
1120 return false;
1121 }
1122}
1123
1124// static
975void LLPanelLogin::onClickConnect(void *) 1125void LLPanelLogin::onClickConnect(void *)
976{ 1126{
977 if (sInstance && sInstance->mCallback) 1127 if (sInstance && sInstance->mCallback)
@@ -983,17 +1133,48 @@ void LLPanelLogin::onClickConnect(void *)
983 // JC - Make sure the fields all get committed. 1133 // JC - Make sure the fields all get committed.
984 sInstance->setFocus(FALSE); 1134 sInstance->setFocus(FALSE);
985 1135
986 std::string first = sInstance->childGetText("first_name_edit"); 1136 // Note: valid logins are username or Username or First.Last or First Last -- MC
987 std::string last = sInstance->childGetText("last_name_edit"); 1137 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat())
988 if (!first.empty() && !last.empty())
989 { 1138 {
990 // has both first and last name typed 1139 std::string username = sInstance->childGetText("username_edit");
991 sInstance->mCallback(0, sInstance->mCallbackData); 1140 if (!username.empty())
1141 {
1142 // todo: make this two functions, one for validating the other for converting
1143 std::string temp1;
1144 std::string temp2;
1145 if (convertUsernameToLegacy(username, temp1, temp2))
1146 {
1147 // has username typed, make sure we're just using that
1148 sInstance->childSetText("first_name_edit", LLStringUtil::null);
1149 sInstance->childSetText("last_name_edit", LLStringUtil::null);
1150 sInstance->mCallback(0, sInstance->mCallbackData);
1151 }
1152 else
1153 {
1154 LLNotifications::instance().add("InvalidLogInSecondLife", LLSD(), LLSD(),
1155 LLPanelLogin::newAccountAlertCallback);
1156 }
1157 }
1158 else
1159 {
1160 LLNotifications::instance().add("MustHaveAccountToLogIn", LLSD(), LLSD(),
1161 LLPanelLogin::newAccountAlertCallback);
1162 }
992 } 1163 }
993 else 1164 else
994 { 1165 {
995 LLNotifications::instance().add("MustHaveAccountToLogIn", LLSD(), LLSD(), 1166 std::string first = sInstance->childGetText("first_name_edit");
996 LLPanelLogin::newAccountAlertCallback); 1167 std::string last = sInstance->childGetText("last_name_edit");
1168 if (!first.empty() && !last.empty())
1169 {
1170 // has both first and last name typed
1171 sInstance->mCallback(0, sInstance->mCallbackData);
1172 }
1173 else
1174 {
1175 LLNotifications::instance().add("MustHaveAccountToLogIn", LLSD(), LLSD(),
1176 LLPanelLogin::newAccountAlertCallback);
1177 }
997 } 1178 }
998 } 1179 }
999} 1180}
@@ -1123,6 +1304,9 @@ void LLPanelLogin::updateGridCombo(std::string grid_nick)
1123 1304
1124 llinfos << "current grid set to " << grid_nick << llendl; 1305 llinfos << "current grid set to " << grid_nick << llendl;
1125 1306
1307 // switch between username/first+last name based on grid
1308 loadLoginForm();
1309
1126 // grid changed so show new splash screen (possibly) 1310 // grid changed so show new splash screen (possibly)
1127 loadLoginPage(); 1311 loadLoginPage();
1128 1312
diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h
index 5830b52..947aea6 100644
--- a/linden/indra/newview/llpanellogin.h
+++ b/linden/indra/newview/llpanellogin.h
@@ -59,9 +59,9 @@ public:
59 void (*callback)(S32 option, void* user_data), 59 void (*callback)(S32 option, void* user_data),
60 void* callback_data); 60 void* callback_data);
61 61
62 // Remember password checkbox is set via gSavedSettings "RememberPassword" 62 // Sets the login screen's name and password editors. Remember password checkbox is set via gSavedSettings "RememberPassword"
63 static void setFields(const std::string& firstname, const std::string& lastname, 63 static void setFields(const std::string& firstname, const std::string& lastname, const std::string& password);
64 const std::string& password); 64 static void setFields(const std::string& username, const std::string& password);
65 65
66 static void addServer(const std::string& server); 66 static void addServer(const std::string& server);
67 static void refreshLocation( bool force_visible ); 67 static void refreshLocation( bool force_visible );
@@ -78,6 +78,7 @@ public:
78 78
79 void setSiteIsAlive( bool alive ); 79 void setSiteIsAlive( bool alive );
80 80
81 static void loadLoginForm();
81 static void loadLoginPage(); 82 static void loadLoginPage();
82 static void refreshLoginPage(); 83 static void refreshLoginPage();
83 static void giveFocus(); 84 static void giveFocus();
@@ -101,8 +102,19 @@ private:
101 static void onPassKey(LLLineEditor* caller, void* user_data); 102 static void onPassKey(LLLineEditor* caller, void* user_data);
102 static void onSelectServer(LLUICtrl*, void*); 103 static void onSelectServer(LLUICtrl*, void*);
103 static void onServerComboLostFocus(LLFocusableElement*, void*); 104 static void onServerComboLostFocus(LLFocusableElement*, void*);
105
106 // converts the following login name formats into valid firstname lastname combos:
107 // username
108 // username.Resident
109 // first.last
110 // first+" "+last
111 // " "+first+" "+last+" "
112 // returns true if name conversion successful
113 static bool convertUsernameToLegacy(std::string& username, std::string& firstname, std::string& lastname);
114
115 // set the password for the login screen
116 static void setPassword(const std::string& password);
104 117
105private:
106 LLPointer<LLUIImage> mLogoImage; 118 LLPointer<LLUIImage> mLogoImage;
107 119
108 void (*mCallback)(S32 option, void *userdata); 120 void (*mCallback)(S32 option, void *userdata);
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index c9cdc8f..e21efa3 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -813,8 +813,23 @@ bool idle_startup()
813 // Show the login dialog 813 // Show the login dialog
814 login_show(); 814 login_show();
815 // connect dialog is already shown, so fill in the names 815 // connect dialog is already shown, so fill in the names
816 LLPanelLogin::setFields( firstname, lastname, password); 816 // icky how usernames get bolted on here as a kind of hack -- MC
817 817 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat())
818 {
819 if (lastname == "resident" || lastname == "Resident")
820 {
821 LLPanelLogin::setFields(firstname, password);
822 }
823 else
824 {
825 LLPanelLogin::setFields(firstname+"."+lastname, password);
826 }
827 }
828 else
829 {
830 LLPanelLogin::setFields(firstname, lastname, password);
831 }
832
818 LLPanelLogin::giveFocus(); 833 LLPanelLogin::giveFocus();
819 834
820 gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); 835 gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml
index 27f5529..eb8860d 100644
--- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml
@@ -7197,6 +7197,25 @@ IM history could not be found for [NAME].
7197</notification> 7197</notification>
7198 7198
7199<notification 7199<notification
7200 icon="alertmodal.tga"
7201 name="InvalidLogInSecondLife"
7202 type="alertmodal">
7203Oops! The login name you entered wasn't formatted correctly!
7204
7205[SECOND_LIFE] accepts the following login formats:
7206
7207 - username
7208 - username.Resident
7209 - firstname.lastname
7210
7211If you don't have an account, would you like to create one now?
7212 <usetemplate
7213 name="okcancelbuttons"
7214 notext="Try again"
7215 yestext="Create an account"/>
7216</notification>
7217
7218<notification
7200 icon="alert.tga" 7219 icon="alert.tga"
7201 name="ShowLookAtInfo" 7220 name="ShowLookAtInfo"
7202 type="alert"> 7221 type="alert">
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml
index 9499239..68991b6 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_login.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_login.xml
@@ -70,10 +70,30 @@
70 allow_translate="false" /> 70 allow_translate="false" />
71 71
72 72
73 <!-- SL USERNAME -->
74
75 <text name="username_text"
76 bottom="80" left="24" height="16" width="250"
77 follows="left|bottom" h_pad="0" halign="left" v_pad="0"
78 bg_visible="false" drop_shadow_visible="true"
79 border_visible="false" border_drop_shadow_visible="false"
80 font="SansSerif" mouse_opaque="true">
81 Login name:
82 </text>
83 <line_editor name="username_edit"
84 bottom_delta="-20" left_delta="0" height="20" width="250"
85 follows="left|bottom" font="SansSerif"
86 bevel_style="in" border_style="line" border_thickness="1"
87 max_length="31" mouse_opaque="true"
88 handle_edit_keys_directly="true"
89 select_all_on_focus_received="true"
90 allow_translate="false" />
91
92
73 <!-- PASSWORD --> 93 <!-- PASSWORD -->
74 94
75 <text name="password_text" 95 <text name="password_text"
76 bottom_delta="20" left_delta="130" height="16" width="120" 96 bottom_delta="20" left="285" height="16" width="120"
77 follows="left|bottom" h_pad="0" halign="left" v_pad="0" 97 follows="left|bottom" h_pad="0" halign="left" v_pad="0"
78 bg_visible="false" drop_shadow_visible="true" 98 bg_visible="false" drop_shadow_visible="true"
79 border_visible="false" border_drop_shadow_visible="false" 99 border_visible="false" border_drop_shadow_visible="false"