1/*
2 * Copyright 2003-2013 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		J��r��me Duval, jerome.duval@free.fr
7 *		Julun, host.haiku@gmx.de
8 *		Michael Phipps
9 *		John Scipione, jscipione@gmail.com
10 */
11
12
13#include "PasswordWindow.h"
14
15#include <Alert.h>
16#include <Box.h>
17#include <Button.h>
18#include <Catalog.h>
19#include <ControlLook.h>
20#include <LayoutBuilder.h>
21#include <LayoutItem.h>
22#include <RadioButton.h>
23#include <Screen.h>
24#include <Size.h>
25#include <TextControl.h>
26
27#include <ctype.h>
28
29#include "ScreenSaverSettings.h"
30
31
32#undef B_TRANSLATION_CONTEXT
33#define B_TRANSLATION_CONTEXT "ScreenSaver"
34
35
36static const uint32 kPasswordTextWidth = 12;
37
38static const uint32 kMsgDone = 'done';
39static const uint32 kMsgPasswordTypeChanged = 'pwtp';
40
41
42PasswordWindow::PasswordWindow(ScreenSaverSettings& settings)
43	:
44	BWindow(BRect(100, 100, 300, 200), B_TRANSLATE("Password Window"),
45		B_MODAL_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, B_NOT_RESIZABLE
46			| B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
47	fSettings(settings)
48{
49	_Setup();
50	Update();
51}
52
53
54void
55PasswordWindow::_Setup()
56{
57	float spacing = be_control_look->DefaultItemSpacing();
58
59	BView* topView = new BView("topView", B_WILL_DRAW);
60	topView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
61	topView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
62
63	BBox* networkBox = new BBox("networkBox");
64	networkBox->SetBorder(B_NO_BORDER);
65
66	fUseNetwork = new BRadioButton("useNetwork",
67		B_TRANSLATE("Use network password"),
68		new BMessage(kMsgPasswordTypeChanged));
69	networkBox->SetLabel(fUseNetwork);
70
71	BBox* customBox = new BBox("customBox");
72
73	fUseCustom = new BRadioButton("useCustom",
74		B_TRANSLATE("Use custom password"),
75		new BMessage(kMsgPasswordTypeChanged));
76	customBox->SetLabel(fUseCustom);
77
78	fPasswordControl = new BTextControl("passwordTextView",
79		B_TRANSLATE("Password:"), B_EMPTY_STRING, NULL);
80	fPasswordControl->TextView()->HideTyping(true);
81	fPasswordControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
82
83	BLayoutItem* passwordTextView
84		= fPasswordControl->CreateTextViewLayoutItem();
85	passwordTextView->SetExplicitMinSize(BSize(spacing * kPasswordTextWidth,
86		B_SIZE_UNSET));
87
88	fConfirmControl = new BTextControl("confirmTextView",
89		B_TRANSLATE("Confirm password:"), B_EMPTY_STRING, NULL);
90	fConfirmControl->SetExplicitMinSize(BSize(spacing * kPasswordTextWidth,
91		B_SIZE_UNSET));
92	fConfirmControl->TextView()->HideTyping(true);
93	fConfirmControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
94
95	BLayoutItem* confirmTextView = fConfirmControl->CreateTextViewLayoutItem();
96	confirmTextView->SetExplicitMinSize(BSize(spacing * kPasswordTextWidth,
97		B_SIZE_UNSET));
98
99	customBox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
100		.SetInsets(B_USE_SMALL_SPACING)
101		.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
102			.Add(fPasswordControl->CreateLabelLayoutItem(), 0, 0)
103			.Add(passwordTextView, 1, 0)
104			.Add(fConfirmControl->CreateLabelLayoutItem(), 0, 1)
105			.Add(confirmTextView, 1, 1)
106			.End()
107		.View());
108
109	BButton* doneButton = new BButton("done", B_TRANSLATE("Done"),
110		new BMessage(kMsgDone));
111
112	BButton* cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
113		new BMessage(B_CANCEL));
114
115	BLayoutBuilder::Group<>(topView, B_VERTICAL, 0)
116		.SetInsets(B_USE_DEFAULT_SPACING)
117		.Add(networkBox)
118		.Add(customBox)
119		.AddStrut(B_USE_DEFAULT_SPACING)
120		.AddGroup(B_HORIZONTAL)
121			.AddGlue()
122			.Add(cancelButton)
123			.Add(doneButton)
124			.End()
125		.End();
126
127	doneButton->MakeDefault(true);
128
129	SetLayout(new BGroupLayout(B_VERTICAL));
130	GetLayout()->AddView(topView);
131}
132
133
134void
135PasswordWindow::Update()
136{
137	if (fSettings.IsNetworkPassword())
138		fUseNetwork->SetValue(B_CONTROL_ON);
139	else
140		fUseCustom->SetValue(B_CONTROL_ON);
141
142	bool useNetPassword = (fUseCustom->Value() > 0);
143	fConfirmControl->SetEnabled(useNetPassword);
144	fPasswordControl->SetEnabled(useNetPassword);
145}
146
147
148void
149PasswordWindow::MessageReceived(BMessage* message)
150{
151	switch (message->what) {
152		case kMsgDone:
153			fSettings.SetLockMethod(fUseCustom->Value() ? "custom" : "network");
154			if (fUseCustom->Value()) {
155				if (strcmp(fPasswordControl->Text(), fConfirmControl->Text())
156						!= 0) {
157					BAlert* alert = new BAlert("noMatch",
158						B_TRANSLATE("Passwords don't match. Please try again."),
159						B_TRANSLATE("OK"));
160					alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
161					alert->Go();
162					break;
163				}
164				fSettings.SetPassword(crypt(fPasswordControl->Text(), NULL));
165			} else
166				fSettings.SetPassword("");
167
168			fPasswordControl->SetText("");
169			fConfirmControl->SetText("");
170			fSettings.Save();
171			Hide();
172			break;
173
174		case B_CANCEL:
175			fPasswordControl->SetText("");
176			fConfirmControl->SetText("");
177			Hide();
178			break;
179
180		case kMsgPasswordTypeChanged:
181			fSettings.SetLockMethod(fUseCustom->Value() > 0 ? "custom" : "network");
182			Update();
183			break;
184
185		default:
186			BWindow::MessageReceived(message);
187 	}
188}
189