BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / login / LoginView.cpp
blobb053f3d6ffab628d45d51b562fec0fa2876d5a40
1 /*
2 * Copyright 2008, François Revol, <revol@free.fr>. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #include <Catalog.h>
6 #include <ScrollView.h>
7 #include <String.h>
8 #include <Window.h>
9 #ifdef __HAIKU__
10 #include <Layout.h>
11 #endif
13 #include <pwd.h>
15 #include "LoginApp.h"
16 #include "LoginView.h"
18 #undef B_TRANSLATION_CONTEXT
19 #define B_TRANSLATION_CONTEXT "Login View"
21 #define LW 120
22 #define CSEP 15
23 #define BH 20
24 #define BW 60
26 class PwdItem : public BStringItem {
27 public:
28 PwdItem(struct passwd *pwd, uint32 level = 0,
29 bool expanded = true)
30 : BStringItem("", level, expanded)
32 if (pwd) {
33 BString name(pwd->pw_gecos);
34 // TODO: truncate at first ;
35 fLogin = pwd->pw_name;
36 SetText(name.String());
39 virtual ~PwdItem() {};
40 const char* Login() const { return fLogin.String(); };
41 private:
42 BString fLogin;
46 LoginView::LoginView(BRect frame)
47 : BView(frame, "LoginView", B_FOLLOW_ALL, B_PULSE_NEEDED)
49 // TODO: when I don't need to test in BeOS anymore,
50 // rewrite to use layout engine.
51 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
52 SetLowUIColor(ViewUIColor());
53 BRect r;
54 r.Set(CSEP, CSEP, LW, Bounds().Height() - 3 * CSEP - BH);
55 fUserList = new BListView(r, "users");
56 BScrollView *sv = new BScrollView("userssv", fUserList,
57 B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true);
58 AddChild(sv);
59 fUserList->SetSelectionMessage(new BMessage(kUserSelected));
60 fUserList->SetInvocationMessage(new BMessage(kUserInvoked));
62 r.Set(LW + 30, Bounds().top + CSEP,
63 Bounds().right - CSEP, Bounds().top + CSEP + CSEP);
64 fLoginControl = new BTextControl(r, "login", B_TRANSLATE("Login:"), "",
65 new BMessage(kLoginEdited));
66 AddChild(fLoginControl);
68 r.OffsetBySelf(0, CSEP + CSEP);
69 fPasswordControl = new BTextControl(r, "password",
70 B_TRANSLATE("Password:"), "", new BMessage(kPasswordEdited));
71 fPasswordControl->TextView()->HideTyping(true);
72 AddChild(fPasswordControl);
74 r.OffsetBySelf(0, CSEP + CSEP);
75 fHidePasswordCheckBox = new BCheckBox(r, "hidepw",
76 B_TRANSLATE("Hide password"), new BMessage(kHidePassword));
77 fHidePasswordCheckBox->SetValue(1);
78 AddChild(fHidePasswordCheckBox);
80 // buttons
81 float buttonWidth = BW; //(Bounds().Width() - 4 * CSEP) / 3;
82 BRect buttonRect(0, Bounds().bottom - BH,
83 buttonWidth, Bounds().bottom);
84 buttonRect.OffsetBySelf(CSEP, -CSEP);
86 fHaltButton = new BButton(buttonRect, "halt", B_TRANSLATE("Halt"),
87 new BMessage(kHaltAction));
88 fHaltButton->ResizeToPreferred();
89 AddChild(fHaltButton);
91 buttonRect.OffsetBySelf(CSEP + fHaltButton->Frame().Width(), 0);
92 fRebootButton = new BButton(buttonRect, "reboot", B_TRANSLATE("Reboot"),
93 new BMessage(kRebootAction));
95 fRebootButton->ResizeToPreferred();
96 AddChild(fRebootButton);
98 BRect infoRect(buttonRect);
99 infoRect.OffsetBySelf(fRebootButton->Frame().Width() + CSEP, 0);
101 buttonRect.OffsetToSelf(Bounds().Width() - CSEP - buttonWidth,
102 Bounds().Height() - CSEP - BH);
103 fLoginButton = new BButton(buttonRect, "ok", B_TRANSLATE("OK"),
104 new BMessage(kAttemptLogin));
105 fLoginButton->ResizeToPreferred();
106 AddChild(fLoginButton);
108 infoRect.right = buttonRect.left - CSEP + 5;
109 BString info;
110 //info << hostname;
111 fInfoView = new BStringView(infoRect, "info", info.String());
112 AddChild(fInfoView);
116 LoginView::~LoginView()
120 void
121 LoginView::AttachedToWindow()
123 fUserList->SetTarget(this);
124 fLoginControl->SetTarget(this);
125 fPasswordControl->SetTarget(this);
126 fHidePasswordCheckBox->SetTarget(this);
127 fHaltButton->SetTarget(be_app_messenger);
128 fRebootButton->SetTarget(be_app_messenger);
129 fLoginButton->SetTarget(this);
130 Window()->SetDefaultButton(fLoginButton);
131 //fLoginControl->MakeFocus();
132 fUserList->MakeFocus();
133 // populate user list
134 BMessenger(this).SendMessage(kAddNextUser);
136 // size window relative to buttons
137 BRect bounds = Window()->Bounds();
138 float spacing = fHaltButton->Frame().left;
139 bounds.bottom = fLoginButton->Frame().bottom + spacing;
140 bounds.right = fLoginButton->Frame().right + spacing;
141 Window()->ResizeTo(bounds.Width(), bounds.Height());
143 // Center info view
144 BPoint leftTop = fInfoView->Frame().LeftTop();
145 leftTop.y += fHaltButton->Frame().Height() / 2;
146 leftTop.y -= fInfoView->Bounds().Height() / 2;
147 fInfoView->MoveTo(leftTop);
151 void
152 LoginView::MessageReceived(BMessage *message)
154 switch (message->what) {
155 case kSetProgress:
156 break;
157 case kAddNextUser:
158 AddNextUser();
159 break;
160 case kUserSelected:
162 int32 selection = fUserList->CurrentSelection();
163 if (selection > -1) {
164 PwdItem *item = dynamic_cast<PwdItem *>(
165 fUserList->ItemAt(selection));
166 if (item)
167 fLoginControl->SetText(item->Login());
169 break;
171 case kUserInvoked:
172 fPasswordControl->MakeFocus();
173 break;
174 case kLoginEdited:
175 break;
176 case kHidePassword:
177 fPasswordControl->TextView()->HideTyping(
178 fHidePasswordCheckBox->Value());
179 break;
180 case kAttemptLogin:
182 // if no pass specified and we were selecting the user,
183 // give a chance to enter the password
184 // else we might want to enter an empty password.
185 if (strlen(fPasswordControl->Text()) < 1
186 && (fUserList->IsFocus() || fLoginControl->IsFocus())) {
187 fPasswordControl->MakeFocus();
188 break;
190 BMessage *m = new BMessage(kAttemptLogin);
191 m->AddString("login", fLoginControl->Text());
192 m->AddString("password", fPasswordControl->Text());
193 be_app->PostMessage(m, NULL, this);
194 break;
196 case kLoginBad:
197 fPasswordControl->SetText("");
198 EnableControls(false);
199 fInfoView->SetText(B_TRANSLATE("Invalid login!"));
200 if (Window()) {
201 BPoint savedPos = Window()->Frame().LeftTop();
202 for (int i = 0; i < 10; i++) {
203 BPoint p(savedPos);
204 p.x += (i%2) ? 10 : -10;
205 Window()->MoveTo(p);
206 Window()->UpdateIfNeeded();
207 snooze(30000);
209 Window()->MoveTo(savedPos);
211 EnableControls(true);
212 break;
213 case kLoginOk:
214 // XXX: quit ?
215 if (Window()) {
216 Window()->Hide();
218 break;
219 default:
220 message->PrintToStream();
221 BView::MessageReceived(message);
226 void
227 LoginView::Pulse()
229 BString info;
230 time_t now = time(NULL);
231 struct tm *t = localtime(&now);
232 // TODO: use strftime and locale settings
233 info << asctime(t);
234 info.RemoveSet("\r\n");
235 fInfoView->SetText(info.String());
239 void
240 LoginView::AddNextUser()
242 struct passwd *pwd;
243 if (fUserList->CountItems() < 1)
244 setpwent();
246 pwd = getpwent();
248 if (pwd && pwd->pw_shell &&
249 strcmp(pwd->pw_shell, "false") &&
250 strcmp(pwd->pw_shell, "true") &&
251 strcmp(pwd->pw_shell, "/bin/false") &&
252 strcmp(pwd->pw_shell, "/bin/true")) {
253 // not disabled
254 PwdItem *item = new PwdItem(pwd);
255 fUserList->AddItem(item);
257 if (pwd)
258 BMessenger(this).SendMessage(kAddNextUser);
259 else
260 endpwent();
264 void
265 LoginView::EnableControls(bool enable)
267 int32 i;
268 for (i = 0; i < fUserList->CountItems(); i++) {
269 fUserList->ItemAt(i)->SetEnabled(enable);
271 fLoginControl->SetEnabled(enable);
272 fPasswordControl->SetEnabled(enable);
273 fHidePasswordCheckBox->SetEnabled(enable);
274 fHaltButton->SetEnabled(enable);
275 fRebootButton->SetEnabled(enable);
276 fLoginButton->SetEnabled(enable);