#include <stdio.h>
#include <Screen.h>
#include <Box.h>
#include <Button.h>
#include <CheckBox.h>
#include <Message.h>
#include <String.h>
#include <StringView.h>
#include <TextControl.h>
#include "AuthenticationPanel.h"
enum {
MSG_PANEL_OK,
MSG_PANEL_CANCEL,
};
AuthenticationPanel::AuthenticationPanel(BRect frame)
: Panel(frame, "Name Panel",
B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
fCancelled(false),
fExitSem(B_ERROR)
{
fExitSem = create_sem(0, "Authentication Panel");
BRect controlFrame(0.0, 0.0, frame.Width(), 15.0);
fNameTC = new BTextControl(controlFrame, "name", "Username", "", NULL,
B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
fPassTC = new BTextControl(controlFrame, "pass", "Password", "", NULL,
B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
fKeepUsingCB = new BCheckBox(controlFrame, "again",
"Use login for all shares of this host",
NULL, B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
BRect buttonFrame(0.0, 0.0, 20.0, 15.0);
fOkB = new BButton(buttonFrame, "ok", "OK",
new BMessage(MSG_PANEL_OK));
fCancelB = new BButton(buttonFrame, "cancel", "Cancel",
new BMessage(MSG_PANEL_CANCEL));
}
AuthenticationPanel::~AuthenticationPanel()
{
delete_sem(fExitSem);
}
bool
AuthenticationPanel::QuitRequested()
{
fCancelled = true;
release_sem(fExitSem);
return false;
}
void
AuthenticationPanel::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_PANEL_CANCEL:
Cancel();
break;
case MSG_PANEL_OK: {
release_sem(fExitSem);
break;
}
default:
Panel::MessageReceived(message);
}
}
bool
AuthenticationPanel::GetAuthentication(const char* server,
const char* share,
const char* previousUser,
const char* previousPass,
bool previousKeep,
bool badPassword,
char* user, char* pass, bool* keep)
{
BString helper("Enter login for: ");
helper << (server ? server : "<unkown host>") << "/";
helper << (share ? share : "<unkown share>");
if (badPassword)
previousPass = NULL;
SetTitle(helper.String());
BPoint offset(0.0, 5.0);
fNameTC->SetText(previousUser ? previousUser : "");
fNameTC->ResizeToPreferred();
fNameTC->MoveTo(BPoint(10.0, 10.0));
fPassTC->SetText(previousPass ? previousPass : "");
fPassTC->ResizeToPreferred();
fPassTC->MoveTo(fNameTC->Frame().LeftBottom() + offset);
fKeepUsingCB->SetValue(previousKeep);
fKeepUsingCB->ResizeToPreferred();
fKeepUsingCB->MoveTo(fPassTC->Frame().LeftBottom() + offset);
fCancelB->ResizeToPreferred();
fOkB->ResizeToPreferred();
fOkB->MoveTo(fKeepUsingCB->Frame().RightBottom() + offset + offset - fOkB->Frame().RightTop());
fCancelB->MoveTo(fOkB->Frame().LeftTop() - BPoint(10.0, 0.0) - fCancelB->Frame().RightTop());
BRect frame(fNameTC->Frame().LeftTop(), fOkB->Frame().RightBottom());
BRect nameFrame = fNameTC->Frame();
BRect passFrame = fPassTC->Frame();
nameFrame.right = nameFrame.left + frame.Width();
passFrame.right = passFrame.left + frame.Width();
float divider = fNameTC->Divider();
if (fPassTC->Divider() > divider)
divider = fPassTC->Divider();
delete fNameTC;
fNameTC = new BTextControl(nameFrame, "name", "Username", "", NULL,
B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
fNameTC->SetText(previousUser ? previousUser : "");
delete fPassTC;
fPassTC = new BTextControl(passFrame, "pass", "Password", "", NULL,
B_FOLLOW_LEFT | B_FOLLOW_RIGHT);
fPassTC->TextView()->HideTyping(true);
fPassTC->SetText(previousPass ? previousPass : "");
fNameTC->SetDivider(divider);
fPassTC->SetDivider(divider);
frame.InsetBy(-10.0, -10.0);
BBox* bg = new BBox(frame, "bg", B_FOLLOW_ALL,
B_FRAME_EVENTS | B_WILL_DRAW | B_NAVIGABLE_JUMP,
B_PLAIN_BORDER);
bg->AddChild(fNameTC);
bg->AddChild(fPassTC);
bg->AddChild(fKeepUsingCB);
bg->AddChild(fOkB);
bg->AddChild(fCancelB);
frame.OffsetTo(-10000.0, -10000.0);
frame = _CalculateFrame(frame);
MoveTo(frame.LeftTop());
ResizeTo(frame.Width(), frame.Height());
AddChild(bg);
SetDefaultButton(fOkB);
fNameTC->MakeFocus(true);
Show();
if (badPassword) {
BPoint leftTop = Frame().LeftTop();
const float jitterOffsets[] = { -10, 0, 10, 0 };
const int32 jitterOffsetCount = sizeof(jitterOffsets) / sizeof(float);
for (int32 i = 0; i < 30; i++) {
float offset = jitterOffsets[i % jitterOffsetCount];
MoveTo(leftTop.x + offset, leftTop.y);
snooze(10000);
}
MoveTo(leftTop);
}
acquire_sem(fExitSem);
Lock();
strcpy(user, fNameTC->Text());
strcpy(pass, fPassTC->Text());
*keep = fKeepUsingCB->Value() == B_CONTROL_ON;
Quit();
return fCancelled;
}
void
AuthenticationPanel::Cancel()
{
fCancelled = true;
Panel::Cancel();
}
BRect
AuthenticationPanel::_CalculateFrame(BRect frame)
{
BScreen screen(B_MAIN_SCREEN_ID);
BRect screenFrame = screen.Frame();
if (!screenFrame.Contains(frame)) {
float width = frame.Width();
float height = frame.Height();
BPoint center;
center.x = screenFrame.left + screenFrame.Width() / 2.0;
center.y = screenFrame.top + screenFrame.Height() / 4.0;
frame.left = center.x - width / 2.0;
frame.right = frame.left + width;
frame.top = center.y - height / 2.0;
frame.bottom = frame.top + height;
}
return frame;
}