xref: /haiku/src/add-ons/kernel/file_systems/netfs/authentication_server/AuthenticationPanel.cpp (revision 899e0ef82b5624ace2ccfa5f5a58c8ebee54aaef)
1 // AuthenticationPanel.cpp
2 
3 #include <stdio.h>
4 
5 #include <Screen.h>
6 
7 #include <Box.h>
8 #include <Button.h>
9 #include <CheckBox.h>
10 #include <Message.h>
11 #include <String.h>
12 #include <StringView.h>
13 #include <TextControl.h>
14 
15 #include "AuthenticationPanel.h"
16 
17 enum {
18 	MSG_PANEL_OK,
19 	MSG_PANEL_CANCEL,
20 };
21 
22 // constructor
23 AuthenticationPanel::AuthenticationPanel(BRect frame)
24 	: Panel(frame, "Name Panel",
25 			B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
26 			B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
27 	  fCancelled(false),
28 	  fExitSem(B_ERROR)
29 {
30 	fExitSem = create_sem(0, "Authentication Panel");
31 
32 	BRect controlFrame(0.0, 0.0, frame.Width(), 15.0);
33 
34 	fNameTC = new BTextControl(controlFrame, "name", "Username", "", NULL,
35 							   B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
36 
37 	fPassTC = new BTextControl(controlFrame, "pass", "Password", "", NULL,
38 							   B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
39 
40 	fKeepUsingCB = new BCheckBox(controlFrame, "again",
41 								 "Use login for all shares of this host",
42 								 NULL, B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
43 
44 	BRect buttonFrame(0.0, 0.0, 20.0, 15.0);
45 	fOkB = new BButton(buttonFrame, "ok", "OK",
46 					   new BMessage(MSG_PANEL_OK));
47 	fCancelB = new BButton(buttonFrame, "cancel", "Cancel",
48 						   new BMessage(MSG_PANEL_CANCEL));
49 
50 }
51 
52 // destructor
53 AuthenticationPanel::~AuthenticationPanel()
54 {
55 	delete_sem(fExitSem);
56 }
57 
58 // QuitRequested
59 bool
60 AuthenticationPanel::QuitRequested()
61 {
62 	fCancelled = true;
63 	release_sem(fExitSem);
64 	return false;
65 }
66 
67 // MessageReceived
68 void
69 AuthenticationPanel::MessageReceived(BMessage* message)
70 {
71 	switch (message->what) {
72 		case MSG_PANEL_CANCEL:
73 			Cancel();
74 			break;
75 		case MSG_PANEL_OK: {
76 			release_sem(fExitSem);
77 			break;
78 		}
79 		default:
80 			Panel::MessageReceived(message);
81 	}
82 }
83 
84 // GetAuthentication
85 bool
86 AuthenticationPanel::GetAuthentication(const char* server,
87 									   const char* share,
88 									   const char* previousUser,
89 									   const char* previousPass,
90 									   bool previousKeep,
91 									   bool badPassword,
92 									   char* user, char* pass, bool* keep)
93 {
94 	// configure panel and layout controls
95 	BString helper("Enter login for: ");
96 	helper << (server ? server : "<unkown host>") << "/";
97 	helper << (share ? share : "<unkown share>");
98 
99 	// ignore the previous password, if it didn't work
100 	if (badPassword)
101 		previousPass = NULL;
102 
103 	SetTitle(helper.String());
104 
105 	BPoint offset(0.0, 5.0);
106 
107 	fNameTC->SetText(previousUser ? previousUser : "");
108 	fNameTC->ResizeToPreferred();
109 	fNameTC->MoveTo(BPoint(10.0, 10.0));
110 
111 	fPassTC->SetText(previousPass ? previousPass : "");
112 	fPassTC->ResizeToPreferred();
113 	fPassTC->MoveTo(fNameTC->Frame().LeftBottom() + offset);
114 
115 	fKeepUsingCB->SetValue(previousKeep);
116 	fKeepUsingCB->ResizeToPreferred();
117 	fKeepUsingCB->MoveTo(fPassTC->Frame().LeftBottom() + offset);
118 
119 	fCancelB->ResizeToPreferred();
120 
121 	fOkB->ResizeToPreferred();
122 	fOkB->MoveTo(fKeepUsingCB->Frame().RightBottom() + offset + offset - fOkB->Frame().RightTop());
123 
124 	fCancelB->MoveTo(fOkB->Frame().LeftTop() - BPoint(10.0, 0.0) - fCancelB->Frame().RightTop());
125 
126 	BRect frame(fNameTC->Frame().LeftTop(), fOkB->Frame().RightBottom());
127 
128 	// work arround buggy BTextControl resizing
129 	BRect nameFrame = fNameTC->Frame();
130 	BRect passFrame = fPassTC->Frame();
131 
132 	nameFrame.right = nameFrame.left + frame.Width();
133 	passFrame.right = passFrame.left + frame.Width();
134 
135 	float divider = fNameTC->Divider();
136 
137 	if (fPassTC->Divider() > divider)
138 		divider = fPassTC->Divider();
139 
140 	delete fNameTC;
141 	fNameTC = new BTextControl(nameFrame, "name", "Username", "", NULL,
142 							   B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
143 	fNameTC->SetText(previousUser ? previousUser : "");
144 
145 	delete fPassTC;
146 	fPassTC = new BTextControl(passFrame, "pass", "Password", "", NULL,
147 							   B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
148 
149 	fPassTC->TextView()->HideTyping(true);
150 	fPassTC->SetText(previousPass ? previousPass : "");
151 
152 	fNameTC->SetDivider(divider);
153 	fPassTC->SetDivider(divider);
154 
155 
156 	// create background view
157 	frame.InsetBy(-10.0, -10.0);
158 
159 	BBox* bg = new BBox(frame, "bg", B_FOLLOW_ALL,
160 						B_FRAME_EVENTS | B_WILL_DRAW | B_NAVIGABLE_JUMP,
161 						B_PLAIN_BORDER);
162 
163 	bg->AddChild(fNameTC);
164 	bg->AddChild(fPassTC);
165 	bg->AddChild(fKeepUsingCB);
166 
167 	bg->AddChild(fOkB);
168 	bg->AddChild(fCancelB);
169 
170 	frame.OffsetTo(-10000.0, -10000.0);
171 	frame = _CalculateFrame(frame);
172 	MoveTo(frame.LeftTop());
173 	ResizeTo(frame.Width(), frame.Height());
174 
175 	AddChild(bg);
176 	SetDefaultButton(fOkB);
177 	fNameTC->MakeFocus(true);
178 
179 	// start window thread
180 	Show();
181 
182 	// let the window jitter, if the previous password was invalid
183 	if (badPassword) {
184 		BPoint leftTop = Frame().LeftTop();
185 		const float jitterOffsets[] = { -10, 0, 10, 0 };
186 		const int32 jitterOffsetCount = sizeof(jitterOffsets) / sizeof(float);
187 		for (int32 i = 0; i < 30; i++) {
188 			float offset = jitterOffsets[i % jitterOffsetCount];
189 			MoveTo(leftTop.x + offset, leftTop.y);
190 			snooze(10000);
191 		}
192 		MoveTo(leftTop);
193 	}
194 
195 	// block calling thread
196 	acquire_sem(fExitSem);
197 
198 	// window wants to quit
199 	Lock();
200 
201 	strcpy(user, fNameTC->Text());
202 	strcpy(pass, fPassTC->Text());
203 	*keep = fKeepUsingCB->Value() == B_CONTROL_ON;
204 
205 	Quit();
206 	return fCancelled;
207 }
208 
209 // Cancel
210 void
211 AuthenticationPanel::Cancel()
212 {
213 	fCancelled = true;
214 //	release_sem(fExitSem);
215 
216 	Panel::Cancel();
217 }
218 
219 
220 // _CalculateFrame
221 BRect
222 AuthenticationPanel::_CalculateFrame(BRect frame)
223 {
224 	BScreen screen(B_MAIN_SCREEN_ID);
225 	BRect screenFrame = screen.Frame();
226 	if (!screenFrame.Contains(frame)) {
227 		float width = frame.Width();
228 		float height = frame.Height();
229 		BPoint center;
230 		center.x = screenFrame.left + screenFrame.Width() / 2.0;
231 		center.y = screenFrame.top + screenFrame.Height() / 4.0;
232 		frame.left = center.x - width / 2.0;
233 		frame.right = frame.left + width;
234 		frame.top = center.y - height / 2.0;
235 		frame.bottom = frame.top + height;
236 	}
237 	return frame;
238 }
239