btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / src / add-ons / kernel / file_systems / netfs / authentication_server / AuthenticationPanel.cpp
blob52afff47c685d6983ffb441287e1d96eacee1c85
1 // AuthenticationPanel.cpp
3 #include <stdio.h>
5 #include <Screen.h>
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>
15 #include "AuthenticationPanel.h"
17 enum {
18 MSG_PANEL_OK,
19 MSG_PANEL_CANCEL,
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)
30 fExitSem = create_sem(0, "Authentication Panel");
32 BRect controlFrame(0.0, 0.0, frame.Width(), 15.0);
34 fNameTC = new BTextControl(controlFrame, "name", "Username", "", NULL,
35 B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
37 fPassTC = new BTextControl(controlFrame, "pass", "Password", "", NULL,
38 B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
40 fKeepUsingCB = new BCheckBox(controlFrame, "again",
41 "Use login for all shares of this host",
42 NULL, B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
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));
52 // destructor
53 AuthenticationPanel::~AuthenticationPanel()
55 delete_sem(fExitSem);
58 // QuitRequested
59 bool
60 AuthenticationPanel::QuitRequested()
62 fCancelled = true;
63 release_sem(fExitSem);
64 return false;
67 // MessageReceived
68 void
69 AuthenticationPanel::MessageReceived(BMessage* message)
71 switch (message->what) {
72 case MSG_PANEL_CANCEL:
73 Cancel();
74 break;
75 case MSG_PANEL_OK: {
76 release_sem(fExitSem);
77 break;
79 default:
80 Panel::MessageReceived(message);
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)
94 // configure panel and layout controls
95 BString helper("Enter login for: ");
96 helper << (server ? server : "<unkown host>") << "/";
97 helper << (share ? share : "<unkown share>");
99 // ignore the previous password, if it didn't work
100 if (badPassword)
101 previousPass = NULL;
103 SetTitle(helper.String());
105 BPoint offset(0.0, 5.0);
107 fNameTC->SetText(previousUser ? previousUser : "");
108 fNameTC->ResizeToPreferred();
109 fNameTC->MoveTo(BPoint(10.0, 10.0));
111 fPassTC->SetText(previousPass ? previousPass : "");
112 fPassTC->ResizeToPreferred();
113 fPassTC->MoveTo(fNameTC->Frame().LeftBottom() + offset);
115 fKeepUsingCB->SetValue(previousKeep);
116 fKeepUsingCB->ResizeToPreferred();
117 fKeepUsingCB->MoveTo(fPassTC->Frame().LeftBottom() + offset);
119 fCancelB->ResizeToPreferred();
121 fOkB->ResizeToPreferred();
122 fOkB->MoveTo(fKeepUsingCB->Frame().RightBottom() + offset + offset - fOkB->Frame().RightTop());
124 fCancelB->MoveTo(fOkB->Frame().LeftTop() - BPoint(10.0, 0.0) - fCancelB->Frame().RightTop());
126 BRect frame(fNameTC->Frame().LeftTop(), fOkB->Frame().RightBottom());
128 // work arround buggy BTextControl resizing
129 BRect nameFrame = fNameTC->Frame();
130 BRect passFrame = fPassTC->Frame();
132 nameFrame.right = nameFrame.left + frame.Width();
133 passFrame.right = passFrame.left + frame.Width();
135 float divider = fNameTC->Divider();
137 if (fPassTC->Divider() > divider)
138 divider = fPassTC->Divider();
140 delete fNameTC;
141 fNameTC = new BTextControl(nameFrame, "name", "Username", "", NULL,
142 B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
143 fNameTC->SetText(previousUser ? previousUser : "");
145 delete fPassTC;
146 fPassTC = new BTextControl(passFrame, "pass", "Password", "", NULL,
147 B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
149 fPassTC->TextView()->HideTyping(true);
150 fPassTC->SetText(previousPass ? previousPass : "");
152 fNameTC->SetDivider(divider);
153 fPassTC->SetDivider(divider);
156 // create background view
157 frame.InsetBy(-10.0, -10.0);
159 BBox* bg = new BBox(frame, "bg", B_FOLLOW_ALL,
160 B_FRAME_EVENTS | B_WILL_DRAW | B_NAVIGABLE_JUMP,
161 B_PLAIN_BORDER);
163 bg->AddChild(fNameTC);
164 bg->AddChild(fPassTC);
165 bg->AddChild(fKeepUsingCB);
167 bg->AddChild(fOkB);
168 bg->AddChild(fCancelB);
170 frame.OffsetTo(-10000.0, -10000.0);
171 frame = _CalculateFrame(frame);
172 MoveTo(frame.LeftTop());
173 ResizeTo(frame.Width(), frame.Height());
175 AddChild(bg);
176 SetDefaultButton(fOkB);
177 fNameTC->MakeFocus(true);
179 // start window thread
180 Show();
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);
192 MoveTo(leftTop);
195 // block calling thread
196 acquire_sem(fExitSem);
198 // window wants to quit
199 Lock();
201 sprintf(user, fNameTC->Text());
202 sprintf(pass, fPassTC->Text());
203 *keep = fKeepUsingCB->Value() == B_CONTROL_ON;
205 Quit();
206 return fCancelled;
209 // Cancel
210 void
211 AuthenticationPanel::Cancel()
213 fCancelled = true;
214 // release_sem(fExitSem);
216 Panel::Cancel();
220 // _CalculateFrame
221 BRect
222 AuthenticationPanel::_CalculateFrame(BRect frame)
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;
237 return frame;