- added ok, halt and reboot buttons
- added "hide password" checkbox
- shake the window on error (good idea axel :p)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25064 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2008-04-20 02:42:25 +00:00
parent 8917d3d855
commit d5cec75295
6 changed files with 200 additions and 34 deletions

View File

@ -2,6 +2,7 @@ SubDir HAIKU_TOP src apps login ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders app ;
#UsePrivateHeaders shared ; #UsePrivateHeaders shared ;
#UsePrivateHeaders tracker ; #UsePrivateHeaders tracker ;
#SubDirHdrs $(HAIKU_TOP) src kits tracker ; #SubDirHdrs $(HAIKU_TOP) src kits tracker ;

View File

@ -1,6 +1,9 @@
#include <Alert.h>
#include <Screen.h> #include <Screen.h>
#include <String.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <pwd.h> #include <pwd.h>
@ -8,6 +11,7 @@
#include "LoginWindow.h" #include "LoginWindow.h"
#ifdef __HAIKU__ #ifdef __HAIKU__
#include <RosterPrivate.h>
#include <shadow.h> #include <shadow.h>
#include "multiuser_utils.h" #include "multiuser_utils.h"
#endif #endif
@ -31,7 +35,7 @@ void
LoginApp::ReadyToRun() LoginApp::ReadyToRun()
{ {
BScreen s; BScreen s;
BRect frame(0, 0, 300, 100); BRect frame(0, 0, 400, 150);
frame.OffsetBySelf(s.Frame().Width()/2 - frame.Width()/2, frame.OffsetBySelf(s.Frame().Width()/2 - frame.Width()/2,
s.Frame().Height()/2 - frame.Height()/2); s.Frame().Height()/2 - frame.Height()/2);
LoginWindow *w = new LoginWindow(frame); LoginWindow *w = new LoginWindow(frame);
@ -42,16 +46,39 @@ LoginApp::ReadyToRun()
void void
LoginApp::MessageReceived(BMessage *message) LoginApp::MessageReceived(BMessage *message)
{ {
bool reboot = false;
switch (message->what) { switch (message->what) {
case kAttemptLogin: case kAttemptLogin:
break; message->PrintToStream();
TryLogin(message);
// TODO
break;
#ifdef __HAIKU__
case kHaltAction:
reboot = false;
// FALLTHROUGH
case kRebootAction:
{
BRoster roster;
BRoster::Private rosterPrivate(roster);
status_t error = rosterPrivate.ShutDown(reboot, false, false);
if (error < B_OK) {
BString msg("Error: ");
msg << strerror(error);
(new BAlert("Error", msg.String(), "Ok"))->Go();
}
break;
}
case kSuspendAction:
(new BAlert("Error", "Unimplemented", "Ok"))->Go();
break;
#endif
default: default:
BApplication::MessageReceived(message); BApplication::MessageReceived(message);
} }
} }
void TryLogin(BMessage *message);
status_t ValidateLogin(const char *login, const char *password/*, bool force = false*/);
void void
LoginApp::TryLogin(BMessage *message) LoginApp::TryLogin(BMessage *message)
@ -59,13 +86,14 @@ LoginApp::TryLogin(BMessage *message)
status_t err; status_t err;
const char *login; const char *login;
const char *password; const char *password;
BMessage reply(B_REPLY); BMessage reply(kLoginBad);
if (message->FindString("login", &login) == B_OK) { if (message->FindString("login", &login) == B_OK) {
if (message->FindString("password", &password) < B_OK) if (message->FindString("password", &password) < B_OK)
password = NULL; password = NULL;
err = ValidateLogin(login, password); err = ValidateLogin(login, password);
printf("ValidateLogin: %s\n", strerror(err));
if (err == B_OK) { if (err == B_OK) {
reply.AddInt32("error", B_OK); reply.what = kLoginOk;
message->SendReply(&reply); message->SendReply(&reply);
if (password == NULL) if (password == NULL)
@ -109,11 +137,11 @@ LoginApp::ValidateLogin(const char *login, const char *password/*, bool force =
return B_OK; return B_OK;
#else #else
// for testing // for testing
if (strcmp(crypt(password, pwd->pw_passwd), pwd->pw_passwd)) if (strcmp(crypt(password, pwd->pw_passwd), pwd->pw_passwd) == 0)
return B_NOT_ALLOWED; return B_OK;
#endif #endif
return B_NOT_ALLOWED; return B_PERMISSION_DENIED;
} }

View File

@ -1,7 +1,15 @@
#ifndef _LOGINAPP_H_
#define _LOGINAPP_H_
#include <Application.h> #include <Application.h>
/* try loging in a user */ /* try loging in a user */
const uint32 kAttemptLogin = 'logi'; const uint32 kAttemptLogin = 'logi';
const uint32 kHaltAction = 'halt';
const uint32 kRebootAction = 'rebo';
const uint32 kSuspendAction = 'susp';
const uint32 kLoginBad = 'lgba';
const uint32 kLoginOk = 'lgok';
class LoginApp : public BApplication { class LoginApp : public BApplication {
public: public:
@ -17,3 +25,5 @@ private:
int getpty(char *pty, char *tty); int getpty(char *pty, char *tty);
}; };
#endif // _LOGINAPP_H_

View File

@ -1,30 +1,70 @@
#include <ScrollView.h> #include <ScrollView.h>
#include <Window.h>
#include <pwd.h> #include <pwd.h>
#include "LoginApp.h"
#include "LoginView.h" #include "LoginView.h"
#define CSEP 15 #define CSEP 15
#define BH 20
#define BW 60
LoginView::LoginView(BRect frame) LoginView::LoginView(BRect frame)
: BView(frame, "LoginView", B_FOLLOW_ALL, 0) : BView(frame, "LoginView", B_FOLLOW_ALL, 0)
{ {
// TODO: when I don't need to test in BeOS anymore,
// rewrite to use layout engine.
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
SetLowColor(ViewColor()); SetLowColor(ViewColor());
BRect r; BRect r;
r.Set(CSEP, CSEP, 80, Bounds().Height() - 2 * CSEP); r.Set(CSEP, CSEP, 80, Bounds().Height() - 3 * CSEP - BH);
fUserList = new BListView(r, "users"); fUserList = new BListView(r, "users");
BScrollView *sv = new BScrollView("userssv", fUserList); BScrollView *sv = new BScrollView("userssv", fUserList,
B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true);
AddChild(sv); AddChild(sv);
fUserList->SetSelectionMessage(new BMessage(kUserSelected));
fUserList->SetInvocationMessage(new BMessage(kUserInvoked));
r.Set(100, Bounds().top + CSEP, Bounds().right - CSEP, Bounds().top + CSEP + CSEP); r.Set(140, Bounds().top + CSEP,
fLoginControl = new BTextControl(r, "login", "login:", "", new BMessage(kLoginEdited)); Bounds().right - CSEP, Bounds().top + CSEP + CSEP);
fLoginControl = new BTextControl(r, "login", "login:", "",
new BMessage(kLoginEdited));
AddChild(fLoginControl); AddChild(fLoginControl);
r.OffsetBySelf(0, CSEP + CSEP); r.OffsetBySelf(0, CSEP + CSEP);
fPasswordControl = new BTextControl(r, "password", "password:", "", new BMessage(kPasswordEdited)); fPasswordControl = new BTextControl(r, "password", "password:", "",
new BMessage(kPasswordEdited));
fPasswordControl->TextView()->HideTyping(true); fPasswordControl->TextView()->HideTyping(true);
AddChild(fPasswordControl); AddChild(fPasswordControl);
r.OffsetBySelf(0, CSEP + CSEP);
fHidePasswordCheckBox = new BCheckBox(r, "hidepw", "Hide Password",
new BMessage(kHidePassword));
fHidePasswordCheckBox->SetValue(1);
AddChild(fHidePasswordCheckBox);
// buttons
float buttonWidth = BW; //(Bounds().Width() - 4 * CSEP) / 3;
BRect buttonRect(0, Bounds().bottom - BH,
buttonWidth, Bounds().bottom);
buttonRect.OffsetBySelf(CSEP, -CSEP);
fHaltButton = new BButton(buttonRect, "halt", "Halt",
new BMessage(kHaltAction));
AddChild(fHaltButton);
buttonRect.OffsetBySelf(CSEP + buttonWidth, 0);
fRebootButton = new BButton(buttonRect, "reboot", "Reboot",
new BMessage(kRebootAction));
AddChild(fRebootButton);
buttonRect.OffsetToSelf(Bounds().Width() - CSEP - buttonWidth,
Bounds().Height() - CSEP - BH);
fLoginButton = new BButton(buttonRect, "ok", "Ok",
new BMessage(kAttemptLogin));
AddChild(fLoginButton);
} }
@ -35,7 +75,16 @@ LoginView::~LoginView()
void void
LoginView::AttachedToWindow() LoginView::AttachedToWindow()
{ {
fLoginControl->MakeFocus(); fUserList->SetTarget(this);
fLoginControl->SetTarget(this);
fPasswordControl->SetTarget(this);
fHidePasswordCheckBox->SetTarget(this);
fHaltButton->SetTarget(be_app_messenger);
fRebootButton->SetTarget(be_app_messenger);
fLoginButton->SetTarget(this);
Window()->SetDefaultButton(fLoginButton);
//fLoginControl->MakeFocus();
fUserList->MakeFocus();
// populate user list // populate user list
BMessenger(this).SendMessage(kAddNextUser); BMessenger(this).SendMessage(kAddNextUser);
} }
@ -45,13 +94,64 @@ void
LoginView::MessageReceived(BMessage *message) LoginView::MessageReceived(BMessage *message)
{ {
switch (message->what) { switch (message->what) {
case kSetProgress: case kSetProgress:
break; break;
case kAddNextUser: case kAddNextUser:
AddNextUser(); AddNextUser();
break; break;
default: case kUserSelected:
BView::MessageReceived(message); {
int32 selection = fUserList->CurrentSelection();
if (selection > -1) {
BStringItem *item = dynamic_cast<BStringItem *>(
fUserList->ItemAt(selection));
if (item)
fLoginControl->SetText(item->Text());
}
break;
}
case kUserInvoked:
fPasswordControl->MakeFocus();
break;
case kLoginEdited:
break;
case kHidePassword:
fPasswordControl->TextView()->HideTyping(
fHidePasswordCheckBox->Value() == 0);
break;
case kAttemptLogin:
{
BMessage *m = new BMessage(kAttemptLogin);
m->AddString("login", fLoginControl->Text());
m->AddString("password", fPasswordControl->Text());
be_app->PostMessage(m, NULL, this);
break;
}
case kLoginBad:
fPasswordControl->SetText("");
EnableControls(false);
if (Window()) {
BPoint savedPos = Window()->Frame().LeftTop();
for (int i = 0; i < 10; i++) {
BPoint p(savedPos);
p.x += (i%2) ? 10 : -10;
Window()->MoveTo(p);
Window()->UpdateIfNeeded();
snooze(30000);
}
Window()->MoveTo(savedPos);
}
EnableControls(true);
break;
case kLoginOk:
// XXX: quit ?
if (Window()) {
Window()->Hide();
}
break;
default:
message->PrintToStream();
BView::MessageReceived(message);
} }
} }
@ -81,3 +181,14 @@ LoginView::AddNextUser()
} }
void
LoginView::EnableControls(bool enable)
{
fLoginControl->SetEnabled(enable);
fPasswordControl->SetEnabled(enable);
fHidePasswordCheckBox->SetEnabled(enable);
fHaltButton->SetEnabled(enable);
fRebootButton->SetEnabled(enable);
fLoginButton->SetEnabled(enable);
}

View File

@ -1,23 +1,35 @@
#include <Button.h>
#include <CheckBox.h>
#include <View.h> #include <View.h>
#include <ListItem.h> #include <ListItem.h>
#include <ListView.h> #include <ListView.h>
#include <TextControl.h> #include <TextControl.h>
const uint32 kUserSelected = 'usel';
const uint32 kUserInvoked = 'uinv';
const uint32 kLoginEdited = 'logc'; const uint32 kLoginEdited = 'logc';
const uint32 kPasswordEdited = 'pasc'; const uint32 kPasswordEdited = 'pasc';
const uint32 kHidePassword = 'hidp';
const uint32 kAddNextUser = 'adnu'; const uint32 kAddNextUser = 'adnu';
const uint32 kSetProgress = 'setp'; const uint32 kSetProgress = 'setp';
class LoginView : public BView { class LoginView : public BView {
public: public:
LoginView(BRect frame); LoginView(BRect frame);
virtual ~LoginView(); virtual ~LoginView();
void AttachedToWindow(); void AttachedToWindow();
void MessageReceived(BMessage *message); void MessageReceived(BMessage *message);
private:
void AddNextUser(); private:
BTextControl *fLoginControl; void AddNextUser();
BTextControl *fPasswordControl; void EnableControls(bool enable);
BListView *fUserList;
BListView* fUserList;
BTextControl* fLoginControl;
BTextControl* fPasswordControl;
BCheckBox* fHidePasswordCheckBox;
BButton* fHaltButton;
BButton* fRebootButton;
BButton* fLoginButton;
}; };

View File

@ -1,3 +1,6 @@
#ifndef _LOGINWINDOW_H_
#define _LOGINWINDOW_H_
#include <Window.h> #include <Window.h>
class LoginWindow : public BWindow { class LoginWindow : public BWindow {
@ -6,3 +9,4 @@ public:
virtual ~LoginWindow(); virtual ~LoginWindow();
}; };
#endif // _LOGINWINDOW_H_