#include "AutoConfigView.h"
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <Message.h>
#include <MenuItem.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <String.h>
#include <Window.h>
#include <MailSettings.h>
AutoConfigView::AutoConfigView(BRect rect, AutoConfig &config)
: BBox(rect),
fAutoConfig(config)
{
int32 stepSize = 30;
int32 divider = 100;
BPoint topLeft(20, 20);
BPoint rightDown(rect.Width() - 20, 20 + stepSize);
BPopUpMenu *chainsPopUp = new BPopUpMenu(B_EMPTY_STRING);
const char *chainModes[] = {
"Receive mail only",
"Send mail only",
"Send and receive mail"};
BMenuItem *item;
for (int32 i = 0; i < 3; i++)
chainsPopUp->AddItem(item = new BMenuItem(chainModes[i], NULL));
fTypeField = new BMenuField(BRect(topLeft, rightDown), NULL,
"Account Type:", chainsPopUp);
fTypeField->SetDivider(divider);
fTypeField->Menu()->ItemAt(2)->SetMarked(true);
AddChild(fTypeField);
topLeft.y += stepSize;
rightDown.y += stepSize;
fInProtocolsField = SetupProtokolView(BRect(topLeft, rightDown));
if (fInProtocolsField) {
fTypeField->SetDivider(divider);
AddChild(fInProtocolsField);
}
GetSMTPAddonRef(&fSMTPAddonRef);
topLeft.y += stepSize;
rightDown.y += stepSize;
fEmailView = new BTextControl(BRect(topLeft, rightDown),
"email", "E-mail address:", "",
new BMessage(kEMailChangedMsg));
fEmailView->SetDivider(divider);
AddChild(fEmailView);
topLeft.y += stepSize;
rightDown.y += stepSize;
fLoginNameView = new BTextControl(BRect(topLeft, rightDown),
"login", "Login name:", "",
NULL);
fLoginNameView->SetDivider(divider);
AddChild(fLoginNameView);
topLeft.y += stepSize;
rightDown.y += stepSize;
fPasswordView = new BTextControl(BRect(topLeft, rightDown),
"password", "Password:", "",
NULL);
fPasswordView->SetDivider(divider);
fPasswordView->TextView()->HideTyping(true);
AddChild(fPasswordView);
topLeft.y += stepSize;
rightDown.y += stepSize;
fAccountNameView = new BTextControl(BRect(topLeft, rightDown),
"account", "Account name:", "",
NULL);
fAccountNameView->SetDivider(divider);
AddChild(fAccountNameView);
topLeft.y += stepSize;
rightDown.y += stepSize;
fNameView = new BTextControl(BRect(topLeft, rightDown),
"name", "Real name:", "",
NULL);
AddChild(fNameView);
fNameView->SetDivider(divider);
}
void
AutoConfigView::AttachedToWindow()
{
fEmailView->SetTarget(this);
fEmailView->MakeFocus(true);
}
void
AutoConfigView::MessageReceived(BMessage *msg)
{
BString text, login;
switch (msg->what)
{
case kEMailChangedMsg:
{
text = fLoginNameView->Text();
if (text == "")
ProposeUsername();
fLoginNameView->MakeFocus();
fLoginNameView->TextView()->SelectAll();
text = fAccountNameView->Text();
if (text == "")
fAccountNameView->SetText(fEmailView->Text());
break;
}
default:
BView::MessageReceived(msg);
break;
}
}
bool
AutoConfigView::GetBasicAccountInfo(account_info &info)
{
status_t status = B_OK;
BMenuItem* item = fTypeField->Menu()->FindMarked();
info.type = fTypeField->Menu()->IndexOf(item);
BString inboundProtocolName = "";
item = fInProtocolsField->Menu()->FindMarked();
if (item) {
inboundProtocolName = item->Label();
item->Message()->FindRef("protocol", &(info.inboundProtocol));
}
else
status = B_ERROR;
if (inboundProtocolName.FindFirst("IMAP") >= 0)
info.inboundType = IMAP;
else
info.inboundType = POP;
info.outboundProtocol = fSMTPAddonRef;
info.name = fNameView->Text();
info.accountName = fAccountNameView->Text();
info.email = fEmailView->Text();
info.loginName = fLoginNameView->Text();
info.password = fPasswordView->Text();
return status;
}
BMenuField*
AutoConfigView::SetupProtokolView(BRect rect)
{
BPopUpMenu *menu = new BPopUpMenu("Choose Protocol");
for (int i = 0; i < 2; i++) {
BPath path;
status_t status = find_directory((i == 0) ? B_USER_ADDONS_DIRECTORY :
B_BEOS_ADDONS_DIRECTORY, &path);
if (status != B_OK)
return NULL;
path.Append("mail_daemon");
path.Append("inbound_protocols");
BDirectory dir(path.Path());
entry_ref protocolRef;
while (dir.GetNextRef(&protocolRef) == B_OK)
{
char name[B_FILE_NAME_LENGTH];
BEntry entry(&protocolRef);
entry.GetName(name);
BMenuItem *item;
BMessage *msg = new BMessage(kProtokollChangedMsg);
menu->AddItem(item = new BMenuItem(name, msg));
msg->AddRef("protocol",&protocolRef);
item->SetMarked(true);
}
}
BMenuField *protocolsMenuField = new BMenuField(rect, NULL, NULL, menu);
protocolsMenuField->ResizeToPreferred();
return protocolsMenuField;
}
status_t
AutoConfigView::GetSMTPAddonRef(entry_ref *ref)
{
for (int i = 0; i < 2; i++) {
BPath path;
status_t status = find_directory((i == 0) ? B_USER_ADDONS_DIRECTORY :
B_BEOS_ADDONS_DIRECTORY, &path);
if (status != B_OK)
{
return B_ERROR;
}
path.Append("mail_daemon");
path.Append("outbound_protocols");
BDirectory dir(path.Path());
while (dir.GetNextRef(ref) == B_OK)
{
return B_OK;
}
}
return B_ERROR;
}
BString
AutoConfigView::ExtractLocalPart(const char* email)
{
BString emailS(email);
BString localPart;
int32 at = emailS.FindLast("@");
emailS.CopyInto(localPart, 0, at);
return localPart;
}
void
AutoConfigView::ProposeUsername()
{
const char* email = fEmailView->Text();
provider_info info;
status_t status = fAutoConfig.GetInfoFromMailAddress(email, &info);
if (status == B_OK) {
BString localPart = ExtractLocalPart(email);
switch (info.username_pattern) {
case 0:
fLoginNameView->SetText(email);
break;
case 1:
fLoginNameView->SetText(localPart.String());
break;
case 2:
break;
}
}
else {
fLoginNameView->SetText(email);
}
}
bool
AutoConfigView::IsValidMailAddress(BString email)
{
int32 atPos = email.FindFirst("@");
if (atPos < 0)
return false;
BString provider;
email.CopyInto(provider, atPos + 1, email.Length() - atPos);
if (provider.FindLast(".") < 0)
return false;
return true;
}
ServerSettingsView::ServerSettingsView(BRect rect, const account_info &info)
: BView(rect, NULL,B_FOLLOW_ALL,0),
fInboundAccount(false),
fOutboundAccount(false),
fInboundAuthMenu(NULL),
fOutboundAuthMenu(NULL),
fInboundEncrItemStart(NULL),
fOutboundEncrItemStart(NULL)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
int32 divider = 120;
switch (info.type) {
case 0:
fInboundAccount = true;
break;
case 1:
fOutboundAccount = true;
break;
case 2:
fInboundAccount = true;
fOutboundAccount = true;
break;
}
BRect boxRect = Bounds();
boxRect.bottom /= 2;
boxRect.bottom -= 5;
BBox *box = new BBox(boxRect);
box->SetLabel("Inbound");
AddChild(box);
BString serverName;
if (info.inboundType == IMAP)
serverName = info.providerInfo.imap_server;
else
serverName = info.providerInfo.pop_server;
fInboundNameView = new BTextControl(BRect(10, 20, rect.Width() - 20, 35),
"inbound", "Server Name:",
serverName.String(),
new BMessage(kServerChangedMsg));
fInboundNameView->SetDivider(divider);
box->AddChild(fInboundNameView);
GetAuthEncrMenu(info.inboundProtocol, &fInboundAuthMenu,
&fInboundEncryptionMenu);
if (fInboundAuthMenu) {
int authID = info.providerInfo.authentification_pop;
if (info.inboundType == POP)
fInboundAuthMenu->Menu()->ItemAt(authID)->SetMarked(true);
fInboundAuthItemStart = fInboundAuthMenu->Menu()->FindMarked();
box->AddChild(fInboundAuthMenu);
fInboundAuthMenu->SetDivider(divider);
fInboundAuthMenu->MoveTo(10, 50);
}
if (fInboundEncryptionMenu) {
BMenuItem *item = NULL;
if (info.inboundType == POP) {
item = fInboundEncryptionMenu->Menu()
->ItemAt(info.providerInfo.ssl_pop);
if (item)
item->SetMarked(true);
fInboundEncryptionMenu->MoveTo(10, 80);
}
if (info.inboundType == IMAP) {
item = fInboundEncryptionMenu->Menu()
->ItemAt(info.providerInfo.ssl_imap);
if (item)
item->SetMarked(true);
fInboundEncryptionMenu->MoveTo(10, 50);
}
fInboundEncrItemStart = fInboundEncryptionMenu->Menu()->FindMarked();
box->AddChild(fInboundEncryptionMenu);
fInboundEncryptionMenu->SetDivider(divider);
}
if (!fInboundAccount) {
fInboundNameView->SetEnabled(false);
if (fInboundAuthMenu)
fInboundAuthMenu->SetEnabled(false);
}
boxRect = Bounds();
boxRect.top = boxRect.bottom / 2;
boxRect.top += 5;
box = new BBox(boxRect);
box->SetLabel("Outbound");
AddChild(box);
serverName = info.providerInfo.smtp_server;
fOutboundNameView = new BTextControl(BRect(10, 20, rect.Width() - 20, 30),
"outbound", "Server name:",
serverName.String(),
new BMessage(kServerChangedMsg));
fOutboundNameView->SetDivider(divider);
box->AddChild(fOutboundNameView);
GetAuthEncrMenu(info.outboundProtocol, &fOutboundAuthMenu,
&fOutboundEncryptionMenu);
if (fOutboundAuthMenu) {
BMenuItem *item = fOutboundAuthMenu->Menu()
->ItemAt(info.providerInfo.authentification_smtp);
if (item)
item->SetMarked(true);
fOutboundAuthItemStart = item;
box->AddChild(fOutboundAuthMenu);
fOutboundAuthMenu->SetDivider(divider);
fOutboundAuthMenu->MoveTo(10, 50);
}
if (fOutboundEncryptionMenu) {
BMenuItem *item = fOutboundEncryptionMenu->Menu()
->ItemAt(info.providerInfo.ssl_smtp);
if (item)
item->SetMarked(true);
fOutboundEncrItemStart = item;
box->AddChild(fOutboundEncryptionMenu);
fOutboundEncryptionMenu->SetDivider(divider);
fOutboundEncryptionMenu->MoveTo(10, 80);
}
if (!fOutboundAccount) {
fOutboundNameView->SetEnabled(false);
if (fOutboundAuthMenu)
fOutboundAuthMenu->SetEnabled(false);
}
}
void
ServerSettingsView::GetServerInfo(account_info &info)
{
if (info.inboundType == IMAP) {
info.providerInfo.imap_server = fInboundNameView->Text();
if (fInboundEncryptionMenu) {
BMenuItem* item = fInboundEncryptionMenu->Menu()->FindMarked();
if (item)
info.providerInfo.ssl_imap = fInboundEncryptionMenu->Menu()
->IndexOf(item);
}
} else {
info.providerInfo.pop_server = fInboundNameView->Text();
BMenuItem* item = NULL;
if (fInboundAuthMenu) {
item = fInboundAuthMenu->Menu()->FindMarked();
if (item)
info.providerInfo.authentification_pop = fInboundAuthMenu
->Menu()
->IndexOf(item);
}
if (fInboundEncryptionMenu) {
item = fInboundEncryptionMenu->Menu()->FindMarked();
if (item)
info.providerInfo.ssl_pop = fInboundEncryptionMenu->Menu()
->IndexOf(item);
}
}
info.providerInfo.smtp_server = fOutboundNameView->Text();
BMenuItem* item = NULL;
if (fOutboundAuthMenu) {
item = fOutboundAuthMenu->Menu()->FindMarked();
if (item)
info.providerInfo.authentification_smtp = fOutboundAuthMenu->Menu()
->IndexOf(item);
}
if (fOutboundEncryptionMenu) {
item = fOutboundEncryptionMenu->Menu()->FindMarked();
if (item)
info.providerInfo.ssl_smtp = fOutboundEncryptionMenu->Menu()
->IndexOf(item);
}
DetectMenuChanges();
}
void
ServerSettingsView::DetectMenuChanges()
{
bool changed = false;
if (fInboundAuthMenu) {
BMenuItem *item = fInboundAuthMenu->Menu()->FindMarked();
if (fInboundAuthItemStart != item)
changed = true;
}
if (fInboundEncryptionMenu) {
BMenuItem *item = fInboundEncryptionMenu->Menu()->FindMarked();
if (fInboundEncrItemStart != item)
changed = true;
}
if (fOutboundAuthMenu) {
BMenuItem *item = fOutboundAuthMenu->Menu()->FindMarked();
if (fOutboundAuthItemStart != item)
changed = true;
}
if (fOutboundEncryptionMenu) {
BMenuItem *item = fOutboundEncryptionMenu->Menu()->FindMarked();
if (fOutboundEncrItemStart != item)
changed = true;
}
if (changed) {
BMessage msg(kServerChangedMsg);
BMessenger messenger(NULL, Window()->Looper());
messenger.SendMessage(&msg);
}
}
void
ServerSettingsView::GetAuthEncrMenu(const entry_ref &ref,
BMenuField **authField,
BMenuField **sslField)
{
BMessage dummyMsg;
BView *(* instantiate_config)(BMessage *,BMessage *);
BPath addon(&ref);
image_id image = load_add_on(addon.Path());
if (image < B_OK) {
*authField = NULL;
*sslField = NULL;
return;
}
if (get_image_symbol(image,"instantiate_config_panel",
B_SYMBOL_TYPE_TEXT,(void **)&instantiate_config) < B_OK)
{
unload_add_on(image);
image = B_MISSING_SYMBOL;
*authField = NULL;
*sslField = NULL;
return;
}
BView *view = (*instantiate_config)(&dummyMsg, &dummyMsg);
*authField = (BMenuField *)(view->FindView("auth_method"));
*sslField = (BMenuField *)(view->FindView("flavor"));
view->RemoveChild(*authField);
view->RemoveChild(*sslField);
delete view;
unload_add_on(image);
}