Imported MDR. Some code still not entirely functional -- I haven't been able to figure out how to detect SSL, so IMAP and POP have it turned off. PPP auto-detect is also not functional at the moment. Other than that, it seems to work beautifully. Packaging will come later.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9016 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -10,6 +10,7 @@ SubInclude OBOS_TOP src prefs filetypes ;
|
||||
SubInclude OBOS_TOP src prefs fonts ;
|
||||
SubInclude OBOS_TOP src prefs keyboard ;
|
||||
SubInclude OBOS_TOP src prefs keymap ;
|
||||
SubInclude OBOS_TOP src prefs mail ;
|
||||
SubInclude OBOS_TOP src prefs media ;
|
||||
SubInclude OBOS_TOP src prefs menu ;
|
||||
SubInclude OBOS_TOP src prefs mouse ;
|
||||
|
||||
@@ -0,0 +1,671 @@
|
||||
/* Account - provides an "account" view on the mail chains
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "Account.h"
|
||||
#include "ConfigViews.h"
|
||||
#include "CenterContainer.h"
|
||||
|
||||
#include <ListView.h>
|
||||
#include <ListItem.h>
|
||||
#include <TextControl.h>
|
||||
#include <MenuField.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Box.h>
|
||||
#include <Alert.h>
|
||||
#include <List.h>
|
||||
#include <String.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <MailSettings.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <MDRLanguage.h>
|
||||
|
||||
static BList gAccounts;
|
||||
static BListView *gListView;
|
||||
static BView *gConfigView;
|
||||
|
||||
const char *kInboundFilterAddOnPath = "mail_daemon/inbound_filters";
|
||||
const char *kOutboundFilterAddOnPath = "mail_daemon/outbound_filters";
|
||||
const char *kSystemFilterAddOnPath = "mail_daemon/system_filters";
|
||||
const char *kInboundProtocolAddOnPath = "mail_daemon/inbound_protocols";
|
||||
const char *kOutboundProtocolAddOnPath = "mail_daemon/outbound_protocols";
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
AccountItem::AccountItem(const char *label,Account *account,int32 type)
|
||||
: BStringItem(label),
|
||||
account(account),
|
||||
type(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AccountItem::~AccountItem()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void AccountItem::Update(BView *owner, const BFont *font)
|
||||
{
|
||||
if (type == ACCOUNT_ITEM)
|
||||
font = be_bold_font;
|
||||
|
||||
BStringItem::Update(owner,font);
|
||||
}
|
||||
|
||||
|
||||
void AccountItem::DrawItem(BView *owner, BRect rect, bool complete)
|
||||
{
|
||||
owner->PushState();
|
||||
if (type == ACCOUNT_ITEM)
|
||||
{
|
||||
// BFont font;
|
||||
// owner->GetFont(&font);
|
||||
// font.SetFace(B_BOLD_FACE);
|
||||
owner->SetFont(be_bold_font); //&font);
|
||||
}
|
||||
BStringItem::DrawItem(owner,rect,complete);
|
||||
owner->PopState();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Account::Account(BMailChain *inbound,BMailChain *outbound)
|
||||
: fInbound(inbound),
|
||||
fOutbound(outbound),
|
||||
|
||||
fAccountItem(NULL),
|
||||
fInboundItem(NULL),
|
||||
fOutboundItem(NULL),
|
||||
fFilterItem(NULL)
|
||||
{
|
||||
fSettings = fInbound ? fInbound : fOutbound;
|
||||
|
||||
BString label;
|
||||
if (fSettings)
|
||||
label << fSettings->Name();
|
||||
else
|
||||
label << MDR_DIALECT_CHOICE ("Unnamed","名称未定");
|
||||
fAccountItem = new AccountItem(label.String(),this,ACCOUNT_ITEM);
|
||||
|
||||
fInboundItem = new AccountItem(MDR_DIALECT_CHOICE (" · Incoming"," - 受信"),this,INBOUND_ITEM);
|
||||
fOutboundItem = new AccountItem(MDR_DIALECT_CHOICE (" · Outgoing"," - 送信"),this,OUTBOUND_ITEM);
|
||||
fFilterItem = new AccountItem(MDR_DIALECT_CHOICE (" · E-mail Filters"," - フィルタ"),this,FILTER_ITEM);
|
||||
}
|
||||
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
if (gListView)
|
||||
{
|
||||
gListView->RemoveItem(fAccountItem);
|
||||
gListView->RemoveItem(fInboundItem);
|
||||
gListView->RemoveItem(fOutboundItem);
|
||||
gListView->RemoveItem(fFilterItem);
|
||||
}
|
||||
delete fAccountItem; delete fFilterItem;
|
||||
delete fInboundItem; delete fOutboundItem;
|
||||
|
||||
delete fInbound;
|
||||
delete fOutbound;
|
||||
}
|
||||
|
||||
|
||||
void Account::AddToListView()
|
||||
{
|
||||
if (!gListView)
|
||||
return;
|
||||
|
||||
gListView->AddItem(fAccountItem);
|
||||
|
||||
if (fInbound)
|
||||
gListView->AddItem(fInboundItem);
|
||||
|
||||
if (fOutbound)
|
||||
gListView->AddItem(fOutboundItem);
|
||||
|
||||
if (fOutbound || fInbound)
|
||||
gListView->AddItem(fFilterItem);
|
||||
}
|
||||
|
||||
|
||||
void Account::SetName(const char *name)
|
||||
{
|
||||
if (fInbound)
|
||||
fInbound->SetName(name);
|
||||
if (fOutbound)
|
||||
fOutbound->SetName(name);
|
||||
|
||||
if (name && *name)
|
||||
{
|
||||
fAccountItem->SetText(name);
|
||||
gListView->InvalidateItem(gListView->IndexOf(fAccountItem));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *Account::Name() const
|
||||
{
|
||||
if (fInbound)
|
||||
return fInbound->Name();
|
||||
if (fOutbound)
|
||||
return fOutbound->Name();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Account::SetRealName(const char *realName)
|
||||
{
|
||||
BMessage *msg;
|
||||
if (fInbound && (msg = fInbound->MetaData()) != NULL)
|
||||
{
|
||||
if (msg->ReplaceString("real_name",realName) < B_OK)
|
||||
msg->AddString("real_name",realName);
|
||||
}
|
||||
if (fOutbound && (msg = fOutbound->MetaData()) != NULL)
|
||||
{
|
||||
if (msg->ReplaceString("real_name",realName) < B_OK)
|
||||
msg->AddString("real_name",realName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *Account::RealName() const
|
||||
{
|
||||
if (fInbound && fInbound->MetaData())
|
||||
return fInbound->MetaData()->FindString("real_name");
|
||||
if (fOutbound && fOutbound->MetaData())
|
||||
return fOutbound->MetaData()->FindString("real_name");
|
||||
|
||||
if (fInbound)
|
||||
fInbound->MetaData()->PrintToStream();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Account::SetReturnAddress(const char *returnAddress)
|
||||
{
|
||||
BMessage *msg;
|
||||
if (fInbound && (msg = fInbound->MetaData()) != NULL)
|
||||
{
|
||||
if (msg->ReplaceString("reply_to",returnAddress) < B_OK)
|
||||
msg->AddString("reply_to",returnAddress);
|
||||
}
|
||||
if (fOutbound && (msg = fOutbound->MetaData()) != NULL)
|
||||
{
|
||||
if (msg->ReplaceString("reply_to",returnAddress) < B_OK)
|
||||
msg->AddString("reply_to",returnAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *Account::ReturnAddress() const
|
||||
{
|
||||
if (fInbound && fInbound->MetaData())
|
||||
return fInbound->MetaData()->FindString("reply_to");
|
||||
if (fOutbound && fOutbound->MetaData())
|
||||
return fOutbound->MetaData()->FindString("reply_to");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Account::CopyMetaData(BMailChain *targetChain, BMailChain *sourceChain)
|
||||
{
|
||||
BMessage *otherMsg, *thisMsg;
|
||||
if (sourceChain && (otherMsg = sourceChain->MetaData()) != NULL
|
||||
&& (thisMsg = targetChain->MetaData()) != NULL)
|
||||
{
|
||||
const char *string;
|
||||
if ((string = otherMsg->FindString("real_name")) != NULL)
|
||||
{
|
||||
if (thisMsg->ReplaceString("real_name",string) < B_OK)
|
||||
thisMsg->AddString("real_name",string);
|
||||
}
|
||||
if ((string = otherMsg->FindString("reply_to")) != NULL)
|
||||
{
|
||||
if (thisMsg->ReplaceString("reply_to",string) < B_OK)
|
||||
thisMsg->AddString("reply_to",string);
|
||||
}
|
||||
if ((string = sourceChain->Name()) != NULL)
|
||||
targetChain->SetName(string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Account::CreateInbound()
|
||||
{
|
||||
|
||||
if (!(fInbound = NewMailChain()))
|
||||
{
|
||||
(new BAlert(
|
||||
MDR_DIALECT_CHOICE ("E-mail","メール"),
|
||||
MDR_DIALECT_CHOICE ("Could not create inbound chain.","受信チェーンは作成できませんでした。"),
|
||||
MDR_DIALECT_CHOICE ("Ok","了解")))->Go();
|
||||
return;
|
||||
}
|
||||
fInbound->SetChainDirection(inbound);
|
||||
|
||||
BPath path,addOnPath;
|
||||
find_directory(B_USER_ADDONS_DIRECTORY,&addOnPath);
|
||||
|
||||
BMessage msg;
|
||||
entry_ref ref;
|
||||
|
||||
// Protocol
|
||||
path = addOnPath;
|
||||
path.Append(kInboundProtocolAddOnPath);
|
||||
path.Append("POP3");
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kInboundProtocolAddOnPath);
|
||||
path.Append("POP3");
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fInbound->AddFilter(msg,ref);
|
||||
|
||||
// Message Parser
|
||||
path = addOnPath;
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append("Message Parser");
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append("Message Parser");
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fInbound->AddFilter(msg,ref);
|
||||
|
||||
// New Mail Notification
|
||||
path = addOnPath;
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("New Mail Notification", "着信通知方法"));
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("New Mail Notification", "着信通知方法"));
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fInbound->AddFilter(msg,ref);
|
||||
|
||||
// Inbox
|
||||
path = addOnPath;
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("Inbox", "受信箱"));
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("Inbox", "受信箱"));
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fInbound->AddFilter(msg,ref);
|
||||
|
||||
// set already made account settings
|
||||
CopyMetaData(fInbound,fOutbound);
|
||||
}
|
||||
|
||||
|
||||
void Account::CreateOutbound()
|
||||
{
|
||||
|
||||
if (!(fOutbound = NewMailChain()))
|
||||
{
|
||||
(new BAlert(
|
||||
MDR_DIALECT_CHOICE ("E-mail","メール"),
|
||||
MDR_DIALECT_CHOICE ("Could not create outbound chain.","送信チェーンは作成できませんでした。"),
|
||||
MDR_DIALECT_CHOICE ("Ok","了解")))->Go();
|
||||
return;
|
||||
}
|
||||
fOutbound->SetChainDirection(outbound);
|
||||
|
||||
BPath path,addOnPath;
|
||||
find_directory(B_USER_ADDONS_DIRECTORY,&addOnPath);
|
||||
|
||||
BMessage msg;
|
||||
entry_ref ref;
|
||||
|
||||
path = addOnPath;
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("Outbox", "送信箱"));
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kSystemFilterAddOnPath);
|
||||
path.Append(MDR_DIALECT_CHOICE ("Outbox", "送信箱"));
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fOutbound->AddFilter(msg,ref);
|
||||
|
||||
path = addOnPath;
|
||||
path.Append(kOutboundProtocolAddOnPath);
|
||||
path.Append("SMTP");
|
||||
if (!BEntry(path.Path()).Exists()) {
|
||||
find_directory(B_BEOS_ADDONS_DIRECTORY,&path);
|
||||
path.Append(kOutboundProtocolAddOnPath);
|
||||
path.Append("SMTP");
|
||||
}
|
||||
BEntry(path.Path()).GetRef(&ref);
|
||||
fOutbound->AddFilter(msg,ref);
|
||||
|
||||
// set already made account settings
|
||||
CopyMetaData(fOutbound,fInbound);
|
||||
}
|
||||
|
||||
|
||||
void Account::SetType(int32 type)
|
||||
{
|
||||
if (type < INBOUND_TYPE || type > IN_AND_OUTBOUND_TYPE)
|
||||
return;
|
||||
|
||||
int32 index = gListView->IndexOf(fAccountItem) + 1;
|
||||
|
||||
// missing inbound
|
||||
if ((type == INBOUND_TYPE || type == IN_AND_OUTBOUND_TYPE) && !Inbound())
|
||||
{
|
||||
if (!fInbound)
|
||||
CreateInbound();
|
||||
|
||||
if (fInbound)
|
||||
gListView->AddItem(fInboundItem,index);
|
||||
}
|
||||
if (Inbound())
|
||||
index++;
|
||||
|
||||
// missing outbound
|
||||
if ((type == OUTBOUND_TYPE || type == IN_AND_OUTBOUND_TYPE) && !Outbound())
|
||||
{
|
||||
if (!fOutbound)
|
||||
CreateOutbound();
|
||||
|
||||
if (fOutbound)
|
||||
gListView->AddItem(fOutboundItem,index);
|
||||
}
|
||||
if (Outbound())
|
||||
index++;
|
||||
|
||||
// missing filter
|
||||
if (!gListView->HasItem(fFilterItem))
|
||||
gListView->AddItem(fFilterItem,index);
|
||||
|
||||
// remove inbound
|
||||
if (type == OUTBOUND_TYPE && Inbound())
|
||||
gListView->RemoveItem(fInboundItem);
|
||||
|
||||
// remove outbound
|
||||
if (type == INBOUND_TYPE && Outbound())
|
||||
gListView->RemoveItem(fOutboundItem);
|
||||
}
|
||||
|
||||
|
||||
int32 Account::Type() const
|
||||
{
|
||||
return Inbound() ? (Outbound() ? 2 : 0) : (Outbound() ? 1 : -1);
|
||||
}
|
||||
|
||||
|
||||
void Account::Selected(int32 type)
|
||||
{
|
||||
if (!gConfigView)
|
||||
return;
|
||||
|
||||
gConfigView->Hide();
|
||||
((CenterContainer *)gConfigView)->DeleteChildren();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ACCOUNT_ITEM:
|
||||
gConfigView->AddChild(new AccountConfigView(gConfigView->Bounds(),this));
|
||||
break;
|
||||
case INBOUND_ITEM:
|
||||
{
|
||||
if (!fInbound)
|
||||
break;
|
||||
|
||||
int32 count = fInbound->CountFilters();
|
||||
for (int32 i = 0;;i++)
|
||||
{
|
||||
BMessage *msg = new BMessage();
|
||||
entry_ref *ref = new entry_ref;
|
||||
|
||||
// we just want to have the first and the last two filters:
|
||||
// Protocol, Parser, Notifier, Folder
|
||||
if (i == 2)
|
||||
{
|
||||
i = count - 2;
|
||||
if (i < 2) // defensive programming...
|
||||
i = 3;
|
||||
}
|
||||
|
||||
if (fInbound->GetFilter(i,msg,ref) < B_OK)
|
||||
{
|
||||
delete msg;
|
||||
delete ref;
|
||||
break;
|
||||
}
|
||||
|
||||
// the filter view takes ownership of "msg" and "ref"
|
||||
FilterConfigView *view;
|
||||
if (i == 0)
|
||||
view = new ProtocolsConfigView(fInbound,i,msg,ref);
|
||||
else
|
||||
view = new FilterConfigView(fInbound,i,msg,ref);
|
||||
|
||||
if (view->InitCheck() >= B_OK)
|
||||
gConfigView->AddChild(view);
|
||||
else
|
||||
delete view;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUTBOUND_ITEM:
|
||||
{
|
||||
if (!fOutbound)
|
||||
break;
|
||||
|
||||
// we just want to have the first and the last filter here
|
||||
int32 count = fOutbound->CountFilters();
|
||||
for (int32 i = 0;i < count;i += count-1)
|
||||
{
|
||||
BMessage *msg = new BMessage();
|
||||
entry_ref *ref = new entry_ref;
|
||||
|
||||
if (fOutbound->GetFilter(i,msg,ref) < B_OK)
|
||||
{
|
||||
delete msg;
|
||||
delete ref;
|
||||
break;
|
||||
}
|
||||
|
||||
// the filter view takes ownership of "msg" and "ref"
|
||||
if (FilterConfigView *view = new FilterConfigView(fOutbound,i,msg,ref))
|
||||
{
|
||||
if (view->InitCheck() >= B_OK)
|
||||
gConfigView->AddChild(view);
|
||||
else
|
||||
delete view;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FILTER_ITEM:
|
||||
{
|
||||
gConfigView->AddChild(new FiltersConfigView(gConfigView->Bounds(),this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
((CenterContainer *)gConfigView)->Layout();
|
||||
gConfigView->Show();
|
||||
}
|
||||
|
||||
|
||||
void Account::Remove(int32 type)
|
||||
{
|
||||
// this should only be called if necessary, but if it's used
|
||||
// in the GUI, this will always be the case
|
||||
((CenterContainer *)gConfigView)->DeleteChildren();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ACCOUNT_ITEM:
|
||||
gListView->RemoveItem(fAccountItem);
|
||||
gListView->RemoveItem(fInboundItem);
|
||||
gListView->RemoveItem(fOutboundItem);
|
||||
gListView->RemoveItem(fFilterItem);
|
||||
return;
|
||||
case INBOUND_ITEM:
|
||||
if (!fInbound || !gListView)
|
||||
return;
|
||||
|
||||
gListView->RemoveItem(fInboundItem);
|
||||
if (!Outbound())
|
||||
gListView->RemoveItem(fFilterItem);
|
||||
break;
|
||||
case OUTBOUND_ITEM:
|
||||
if (!fOutbound || !gListView)
|
||||
return;
|
||||
|
||||
gListView->RemoveItem(fOutboundItem);
|
||||
if (!Inbound())
|
||||
gListView->RemoveItem(fFilterItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BMailChain *Account::Inbound() const
|
||||
{
|
||||
return gListView && gListView->HasItem(fInboundItem) ? fInbound : NULL;
|
||||
}
|
||||
|
||||
|
||||
BMailChain *Account::Outbound() const
|
||||
{
|
||||
return gListView && gListView->HasItem(fOutboundItem) ? fOutbound : NULL;
|
||||
}
|
||||
|
||||
|
||||
void Account::Save()
|
||||
{
|
||||
if (Inbound())
|
||||
fInbound->Save();
|
||||
else
|
||||
Delete(INBOUND_TYPE);
|
||||
|
||||
if (Outbound())
|
||||
fOutbound->Save();
|
||||
else
|
||||
Delete(OUTBOUND_TYPE);
|
||||
}
|
||||
|
||||
|
||||
void Account::Delete(int32 type)
|
||||
{
|
||||
if (fInbound && (type == INBOUND_TYPE || type == IN_AND_OUTBOUND_TYPE))
|
||||
fInbound->Delete();
|
||||
|
||||
if (fOutbound && (type == OUTBOUND_TYPE || type == IN_AND_OUTBOUND_TYPE))
|
||||
fOutbound->Delete();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int Accounts::Compare(const void *_a, const void *_b)
|
||||
{
|
||||
const char *a = (*(Account **)_a)->Name();
|
||||
const char *b = (*(Account **)_b)->Name();
|
||||
|
||||
if (!a)
|
||||
return b != 0;
|
||||
|
||||
return strcasecmp(a,b);
|
||||
}
|
||||
|
||||
|
||||
void Accounts::Create(BListView *listView, BView *configView)
|
||||
{
|
||||
gListView = listView;
|
||||
gConfigView = configView;
|
||||
|
||||
BList inbound,outbound;
|
||||
|
||||
GetInboundMailChains(&inbound);
|
||||
GetOutboundMailChains(&outbound);
|
||||
|
||||
// create inbound accounts and assign matching outbound chains
|
||||
|
||||
for (int32 i = inbound.CountItems();i-- > 0;)
|
||||
{
|
||||
BMailChain *inChain = (BMailChain *)inbound.ItemAt(i);
|
||||
BMailChain *outChain = NULL;
|
||||
for (int32 j = outbound.CountItems();j-- > 0;)
|
||||
{
|
||||
outChain = (BMailChain *)outbound.ItemAt(j);
|
||||
|
||||
if (!strcmp(inChain->Name(),outChain->Name()))
|
||||
break;
|
||||
outChain = NULL;
|
||||
}
|
||||
gAccounts.AddItem(new Account(inChain,outChain));
|
||||
inbound.RemoveItem(i);
|
||||
if (outChain)
|
||||
outbound.RemoveItem(outChain);
|
||||
}
|
||||
|
||||
// create remaining outbound only accounts
|
||||
|
||||
for (int32 i = outbound.CountItems();i-- > 0;)
|
||||
{
|
||||
BMailChain *outChain = (BMailChain *)outbound.ItemAt(i);
|
||||
|
||||
gAccounts.AddItem(new Account(NULL,outChain));
|
||||
outbound.RemoveItem(i);
|
||||
}
|
||||
|
||||
// sort the list alphabetically
|
||||
gAccounts.SortItems(Accounts::Compare);
|
||||
|
||||
for (int32 i = 0;Account *account = (Account *)gAccounts.ItemAt(i);i++)
|
||||
account->AddToListView();
|
||||
}
|
||||
|
||||
|
||||
void Accounts::NewAccount()
|
||||
{
|
||||
Account *account = new Account();
|
||||
gAccounts.AddItem(account);
|
||||
account->AddToListView();
|
||||
}
|
||||
|
||||
|
||||
void Accounts::Save()
|
||||
{
|
||||
for (int32 i = gAccounts.CountItems();i-- > 0;)
|
||||
((Account *)gAccounts.ItemAt(i))->Save();
|
||||
}
|
||||
|
||||
|
||||
void Accounts::Delete()
|
||||
{
|
||||
for (int32 i = gAccounts.CountItems();i-- > 0;)
|
||||
{
|
||||
Account *account = (Account *)gAccounts.RemoveItem(i);
|
||||
delete account;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifndef ACCOUNT_H
|
||||
#define ACCOUNT_H
|
||||
/* Account - provides an "account" view on the mail chains
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include <ListItem.h>
|
||||
|
||||
class BView;
|
||||
class BListView;
|
||||
class BStringItem;
|
||||
class BMailChain;
|
||||
|
||||
class Account;
|
||||
class Accounts;
|
||||
|
||||
|
||||
enum item_types
|
||||
{
|
||||
ACCOUNT_ITEM = 0,
|
||||
INBOUND_ITEM,
|
||||
OUTBOUND_ITEM,
|
||||
FILTER_ITEM
|
||||
};
|
||||
|
||||
class AccountItem : public BStringItem
|
||||
{
|
||||
public:
|
||||
AccountItem(const char *label,Account *account,int32 type);
|
||||
~AccountItem();
|
||||
|
||||
virtual void Update(BView *owner,const BFont *font);
|
||||
virtual void DrawItem(BView *owner,BRect rect,bool complete);
|
||||
|
||||
Account *account;
|
||||
int32 type;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
||||
|
||||
enum account_types
|
||||
{
|
||||
INBOUND_TYPE = 0,
|
||||
OUTBOUND_TYPE,
|
||||
IN_AND_OUTBOUND_TYPE
|
||||
};
|
||||
|
||||
class Account
|
||||
{
|
||||
public:
|
||||
Account(BMailChain *inbound = NULL,BMailChain *outbound = NULL);
|
||||
~Account();
|
||||
|
||||
void SetName(const char *name);
|
||||
const char *Name() const;
|
||||
|
||||
void SetRealName(const char *realName);
|
||||
const char *RealName() const;
|
||||
|
||||
void SetReturnAddress(const char *returnAddress);
|
||||
const char *ReturnAddress() const;
|
||||
|
||||
void Selected(int32 type);
|
||||
void Remove(int32 type);
|
||||
|
||||
void SetType(int32 type);
|
||||
int32 Type() const;
|
||||
|
||||
BMailChain *Inbound() const;
|
||||
BMailChain *Outbound() const;
|
||||
|
||||
void Save();
|
||||
void Delete(int32 type = IN_AND_OUTBOUND_TYPE);
|
||||
|
||||
private:
|
||||
friend Accounts;
|
||||
void AddToListView();
|
||||
private:
|
||||
void CreateInbound();
|
||||
void CreateOutbound();
|
||||
void CopyMetaData(BMailChain *targetChain,
|
||||
BMailChain *sourceChain);
|
||||
|
||||
BMailChain *fSettings, *fInbound, *fOutbound;
|
||||
AccountItem *fAccountItem, *fInboundItem, *fOutboundItem, *fFilterItem;
|
||||
};
|
||||
|
||||
class Accounts
|
||||
{
|
||||
public:
|
||||
static void Create(BListView *listView,BView *configView);
|
||||
static void NewAccount();
|
||||
static void Save();
|
||||
static void Delete();
|
||||
|
||||
private:
|
||||
static int Compare(const void *,const void *);
|
||||
};
|
||||
|
||||
#endif /* ACCOUNT_H */
|
||||
@@ -0,0 +1,98 @@
|
||||
/* CenterContainer - a container which centers its contents in the middle
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "CenterContainer.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
CenterContainer::CenterContainer(BRect rect,bool centerHoriz)
|
||||
: BView(rect,NULL,B_FOLLOW_ALL,0),
|
||||
fSpacing(7),
|
||||
fWidth(0),
|
||||
fCenterHoriz(centerHoriz)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::AttachedToWindow()
|
||||
{
|
||||
if (Parent() != NULL)
|
||||
SetViewColor(Parent()->ViewColor());
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::AllAttached()
|
||||
{
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::FrameResized(float width,float height)
|
||||
{
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::GetPreferredSize(float *width, float *height)
|
||||
{
|
||||
// calculate dimensions (and, well, layout views)
|
||||
if (fWidth == 0)
|
||||
Layout();
|
||||
|
||||
if (width)
|
||||
*width = fWidth;
|
||||
if (height)
|
||||
*height = fHeight;
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::Layout()
|
||||
{
|
||||
// compute the size of all views
|
||||
fHeight = 0; fWidth = 0;
|
||||
for (int32 i = 0;BView *view = ChildAt(i);i++)
|
||||
{
|
||||
if (i != 0) // the spacing between to items
|
||||
fHeight += fSpacing;
|
||||
fHeight += view->Bounds().Height();
|
||||
|
||||
if (view->Bounds().Width() > fWidth)
|
||||
fWidth = view->Bounds().Width();
|
||||
}
|
||||
|
||||
// layout views
|
||||
float y = (Bounds().Height() - fHeight) / 2;
|
||||
for (int32 i = 0;BView *view = ChildAt(i);i++)
|
||||
{
|
||||
view->MoveTo(fCenterHoriz ? (Bounds().Width() - view->Bounds().Width()) / 2
|
||||
: view->Frame().left,
|
||||
y);
|
||||
y += view->Bounds().Height() + fSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::SetSpacing(float spacing)
|
||||
{
|
||||
if (fSpacing == spacing)
|
||||
return;
|
||||
|
||||
fSpacing = spacing;
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
void CenterContainer::DeleteChildren()
|
||||
{
|
||||
// remove all child views
|
||||
for (int32 i = CountChildren();i-- > 0;)
|
||||
{
|
||||
BView *view = ChildAt(i);
|
||||
if (RemoveChild(view))
|
||||
delete view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef CENTER_CONTAINER_H
|
||||
#define CENTER_CONTAINER_H
|
||||
/* CenterContainer - a container which centers its contents in the middle
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include <View.h>
|
||||
|
||||
|
||||
class CenterContainer : public BView
|
||||
{
|
||||
public:
|
||||
CenterContainer(BRect rect,bool centerHoriz = true);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void AllAttached();
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void GetPreferredSize(float *width, float *height);
|
||||
|
||||
void Layout();
|
||||
void SetSpacing(float spacing);
|
||||
void DeleteChildren();
|
||||
|
||||
private:
|
||||
float fSpacing, fWidth, fHeight;
|
||||
bool fCenterHoriz;
|
||||
};
|
||||
|
||||
#endif /* CENTER_CONTAINER_H */
|
||||
@@ -0,0 +1,847 @@
|
||||
/* ConfigViews - config views for the account, protocols, and filters
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "ConfigViews.h"
|
||||
#include "Account.h"
|
||||
#include "CenterContainer.h"
|
||||
|
||||
#include <TextControl.h>
|
||||
#include <ListView.h>
|
||||
#include <ScrollView.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Button.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Looper.h>
|
||||
#include <Path.h>
|
||||
#include <Alert.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Directory.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <MailSettings.h>
|
||||
|
||||
#include <MDRLanguage.h>
|
||||
|
||||
// AccountConfigView
|
||||
const uint32 kMsgAccountTypeChanged = 'atch';
|
||||
const uint32 kMsgAccountNameChanged = 'anmc';
|
||||
|
||||
// ProtocolsConfigView
|
||||
const uint32 kMsgProtocolChanged = 'prch';
|
||||
|
||||
// FiltersConfigView
|
||||
const uint32 kMsgItemDragged = 'itdr';
|
||||
const uint32 kMsgFilterMoved = 'flmv';
|
||||
const uint32 kMsgChainSelected = 'chsl';
|
||||
const uint32 kMsgAddFilter = 'addf';
|
||||
const uint32 kMsgRemoveFilter = 'rmfi';
|
||||
const uint32 kMsgFilterSelected = 'fsel';
|
||||
|
||||
|
||||
AccountConfigView::AccountConfigView(BRect rect,Account *account)
|
||||
: BBox(rect),
|
||||
fAccount(account)
|
||||
{
|
||||
SetLabel(MDR_DIALECT_CHOICE ("Account Configuration","アカウント設定"));
|
||||
BMailChain *settings = account->Inbound() ? account->Inbound() : account->Outbound();
|
||||
|
||||
rect = Bounds().InsetByCopy(8,8);
|
||||
rect.top += 10;
|
||||
CenterContainer *view = new CenterContainer(rect,false);
|
||||
view->SetSpacing(5);
|
||||
|
||||
// determine font height
|
||||
font_height fontHeight;
|
||||
view->GetFontHeight(&fontHeight);
|
||||
int32 height = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 5;
|
||||
|
||||
rect = view->Bounds();
|
||||
rect.bottom = height + 5;
|
||||
|
||||
float labelWidth = view->StringWidth(MDR_DIALECT_CHOICE ("Account Name:","アカウント名:")) + 6;
|
||||
|
||||
view->AddChild(fNameControl = new BTextControl(rect,NULL,MDR_DIALECT_CHOICE ("Account Name:","アカウント名:"),NULL,new BMessage(kMsgAccountNameChanged)));
|
||||
fNameControl->SetDivider(labelWidth);
|
||||
view->AddChild(fRealNameControl = new BTextControl(rect,NULL,MDR_DIALECT_CHOICE ("Real Name:","名前 :"),NULL,NULL));
|
||||
fRealNameControl->SetDivider(labelWidth);
|
||||
view->AddChild(fReturnAddressControl = new BTextControl(rect,NULL,MDR_DIALECT_CHOICE ("Return Address:","返信アドレス:"),NULL,NULL));
|
||||
fReturnAddressControl->SetDivider(labelWidth);
|
||||
// control->TextView()->HideTyping(true);
|
||||
|
||||
BPopUpMenu *chainsPopUp = new BPopUpMenu(B_EMPTY_STRING);
|
||||
const char *chainModes[] = {
|
||||
MDR_DIALECT_CHOICE ("Inbound Only","受信のみ"),
|
||||
MDR_DIALECT_CHOICE ("Outbound Only","送信のみ"),
|
||||
MDR_DIALECT_CHOICE ("Inbound & Outbound","送受信")};
|
||||
BMenuItem *item;
|
||||
for (int32 i = 0;i < 3;i++)
|
||||
chainsPopUp->AddItem(item = new BMenuItem(chainModes[i],new BMessage(kMsgAccountTypeChanged)));
|
||||
|
||||
fTypeField = new BMenuField(rect,NULL,MDR_DIALECT_CHOICE ("Account Type:","用途 :"),chainsPopUp);
|
||||
fTypeField->SetDivider(labelWidth + 3);
|
||||
view->AddChild(fTypeField);
|
||||
|
||||
float w,h;
|
||||
view->GetPreferredSize(&w,&h);
|
||||
ResizeTo(w + 15,h + 22);
|
||||
view->ResizeTo(w,h);
|
||||
|
||||
AddChild(view);
|
||||
}
|
||||
|
||||
|
||||
void AccountConfigView::DetachedFromWindow()
|
||||
{
|
||||
fAccount->SetName(fNameControl->Text());
|
||||
fAccount->SetRealName(fRealNameControl->Text());
|
||||
fAccount->SetReturnAddress(fReturnAddressControl->Text());
|
||||
}
|
||||
|
||||
|
||||
void AccountConfigView::AttachedToWindow()
|
||||
{
|
||||
UpdateViews();
|
||||
fNameControl->SetTarget(this);
|
||||
fTypeField->Menu()->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
void AccountConfigView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case kMsgAccountTypeChanged:
|
||||
{
|
||||
int32 index;
|
||||
if (msg->FindInt32("index",&index) < B_OK)
|
||||
break;
|
||||
|
||||
if (fAccount->Type() < 0)
|
||||
{
|
||||
fNameControl->SetEnabled(true);
|
||||
fRealNameControl->SetEnabled(true);
|
||||
fReturnAddressControl->SetEnabled(true);
|
||||
}
|
||||
fAccount->SetType(index);
|
||||
UpdateViews();
|
||||
break;
|
||||
}
|
||||
case kMsgAccountNameChanged:
|
||||
fAccount->SetName(fNameControl->Text());
|
||||
break;
|
||||
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AccountConfigView::UpdateViews()
|
||||
{
|
||||
if (!fAccount->Inbound() && !fAccount->Outbound())
|
||||
{
|
||||
if (BMenuItem *item = fTypeField->Menu()->FindMarked())
|
||||
item->SetMarked(false);
|
||||
fTypeField->Menu()->Superitem()->SetLabel(MDR_DIALECT_CHOICE ("<select account type>","<用途を選択してください>"));
|
||||
|
||||
fNameControl->SetEnabled(false);
|
||||
fRealNameControl->SetEnabled(false);
|
||||
fReturnAddressControl->SetEnabled(false);
|
||||
return;
|
||||
}
|
||||
fNameControl->SetText(fAccount->Name());
|
||||
fRealNameControl->SetText(fAccount->RealName());
|
||||
fReturnAddressControl->SetText(fAccount->ReturnAddress());
|
||||
|
||||
if (BMenuItem *item = fTypeField->Menu()->ItemAt(fAccount->Type()))
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
#include <stdio.h>
|
||||
FilterConfigView::FilterConfigView(BMailChain *chain,int32 index,BMessage *msg,entry_ref *ref)
|
||||
: BBox(BRect(0,0,100,100)),
|
||||
fConfigView(NULL),
|
||||
fChain(chain),
|
||||
fIndex(index),
|
||||
fMessage(msg),
|
||||
fEntryRef(ref)
|
||||
{
|
||||
Load(msg,ref);
|
||||
BPath addon(ref);
|
||||
SetLabel(addon.Leaf());
|
||||
}
|
||||
|
||||
|
||||
FilterConfigView::~FilterConfigView()
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
|
||||
|
||||
void FilterConfigView::Load(BMessage *msg,entry_ref *ref)
|
||||
{
|
||||
ResizeTo(264,30);
|
||||
|
||||
BView *(* instantiate_config)(BMessage *,BMessage *);
|
||||
BPath addon(ref);
|
||||
fImage = load_add_on(addon.Path());
|
||||
if (fImage < B_OK)
|
||||
return;
|
||||
|
||||
if (get_image_symbol(fImage,"instantiate_config_panel",B_SYMBOL_TYPE_TEXT,(void **)&instantiate_config) < B_OK)
|
||||
{
|
||||
unload_add_on(fImage);
|
||||
fImage = B_MISSING_SYMBOL;
|
||||
return;
|
||||
}
|
||||
|
||||
fConfigView = (*instantiate_config)(msg,fChain->MetaData());
|
||||
|
||||
float w = fConfigView->Bounds().Width();
|
||||
float h = fConfigView->Bounds().Height();
|
||||
fConfigView->MoveTo(3,13);
|
||||
ResizeTo(w + 6,h + 16);
|
||||
AddChild(fConfigView);
|
||||
}
|
||||
|
||||
|
||||
void FilterConfigView::Remove(bool deleteMessage)
|
||||
{
|
||||
// remove config view here, because they may not be available
|
||||
// anymore, if the add-on is unloaded
|
||||
if (fConfigView && RemoveChild(fConfigView))
|
||||
{
|
||||
delete fConfigView;
|
||||
fConfigView = NULL;
|
||||
}
|
||||
unload_add_on(fImage);
|
||||
|
||||
if (deleteMessage)
|
||||
{
|
||||
delete fMessage;
|
||||
fMessage = NULL;
|
||||
}
|
||||
delete fEntryRef;
|
||||
fEntryRef = NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t FilterConfigView::InitCheck()
|
||||
{
|
||||
return fImage;
|
||||
}
|
||||
|
||||
|
||||
void FilterConfigView::DetachedFromWindow()
|
||||
{
|
||||
if (fConfigView == NULL)
|
||||
return;
|
||||
|
||||
if (fConfigView->Archive(fMessage) >= B_OK)
|
||||
fChain->SetFilter(fIndex,*fMessage,*fEntryRef);
|
||||
}
|
||||
|
||||
|
||||
void FilterConfigView::AttachedToWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ProtocolsConfigView::ProtocolsConfigView(BMailChain *chain,int32 index,BMessage *msg,entry_ref *ref)
|
||||
: FilterConfigView(chain,index,msg,ref)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fImage = status;
|
||||
return;
|
||||
}
|
||||
|
||||
path.Append("mail_daemon");
|
||||
|
||||
if (chain->ChainDirection() == inbound)
|
||||
path.Append("inbound_protocols");
|
||||
else
|
||||
path.Append("outbound_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;
|
||||
menu->AddItem(item = new BMenuItem(name,msg = new BMessage(kMsgProtocolChanged)));
|
||||
msg->AddRef("protocol",&protocolRef);
|
||||
|
||||
if (*ref == protocolRef)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
}
|
||||
|
||||
fProtocolsMenuField = new BMenuField(BRect(0,0,200,40),NULL,NULL,menu);
|
||||
fProtocolsMenuField->ResizeToPreferred();
|
||||
SetLabel(fProtocolsMenuField);
|
||||
|
||||
if (fConfigView)
|
||||
{
|
||||
fConfigView->MoveTo(3,21);
|
||||
ResizeBy(0,8);
|
||||
}
|
||||
else
|
||||
fImage = B_OK;
|
||||
}
|
||||
|
||||
|
||||
void ProtocolsConfigView::AttachedToWindow()
|
||||
{
|
||||
FilterConfigView::AttachedToWindow();
|
||||
fProtocolsMenuField->Menu()->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
void ProtocolsConfigView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case kMsgProtocolChanged:
|
||||
{
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("protocol",&ref) < B_OK)
|
||||
break;
|
||||
|
||||
DetachedFromWindow();
|
||||
Remove(false);
|
||||
|
||||
fEntryRef = new entry_ref(ref);
|
||||
Load(fMessage,fEntryRef);
|
||||
fChain->SetFilter(fIndex,*fMessage,*fEntryRef);
|
||||
|
||||
// resize view
|
||||
if (LockLooperWithTimeout(1000000L) == B_OK)
|
||||
{
|
||||
if (fConfigView)
|
||||
{
|
||||
fConfigView->MoveTo(3,21);
|
||||
ResizeBy(0,8);
|
||||
}
|
||||
UnlockLooper();
|
||||
|
||||
if (CenterContainer *container = dynamic_cast<CenterContainer *>(Parent()))
|
||||
container->Layout();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
#include <stdio.h>
|
||||
class DragListView : public BListView
|
||||
{
|
||||
public:
|
||||
DragListView(BRect frame,const char *name,list_view_type type = B_SINGLE_SELECTION_LIST,
|
||||
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,BMessage *itemMovedMsg = NULL)
|
||||
: BListView(frame,name,type,resizingMode),
|
||||
fDragging(false),
|
||||
fItemMovedMessage(itemMovedMsg)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool InitiateDrag(BPoint point,int32 index,bool wasSelected)
|
||||
{
|
||||
BRect frame(ItemFrame(index));
|
||||
BBitmap *bitmap = new BBitmap(frame.OffsetToCopy(B_ORIGIN),B_RGBA32,true);
|
||||
BView *view = new BView(bitmap->Bounds(),NULL,0,0);
|
||||
bitmap->AddChild(view);
|
||||
|
||||
if (view->LockLooper())
|
||||
{
|
||||
BListItem *item = ItemAt(index);
|
||||
bool selected = item->IsSelected();
|
||||
|
||||
view->SetLowColor(225,225,225,128);
|
||||
view->FillRect(view->Bounds());
|
||||
|
||||
if (selected)
|
||||
item->Deselect();
|
||||
ItemAt(index)->DrawItem(view,view->Bounds(),true);
|
||||
if (selected)
|
||||
item->Select();
|
||||
|
||||
view->UnlockLooper();
|
||||
}
|
||||
fLastDragTarget = -1;
|
||||
fDragIndex = index;
|
||||
fDragging = true;
|
||||
|
||||
BMessage drag(kMsgItemDragged);
|
||||
drag.AddInt32("index",index);
|
||||
DragMessage(&drag,bitmap,B_OP_ALPHA,point - frame.LeftTop(),this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawDragTargetIndicator(int32 target)
|
||||
{
|
||||
PushState();
|
||||
SetDrawingMode(B_OP_INVERT);
|
||||
|
||||
bool last = false;
|
||||
if (target >= CountItems())
|
||||
target = CountItems() - 1, last = true;
|
||||
|
||||
BRect frame = ItemFrame(target);
|
||||
if (last)
|
||||
frame.OffsetBy(0,frame.Height());
|
||||
frame.bottom = frame.top + 1;
|
||||
|
||||
FillRect(frame);
|
||||
|
||||
PopState();
|
||||
}
|
||||
|
||||
virtual void MouseMoved(BPoint point,uint32 transit,const BMessage *msg)
|
||||
{
|
||||
BListView::MouseMoved(point,transit,msg);
|
||||
|
||||
if ((transit != B_ENTERED_VIEW && transit != B_INSIDE_VIEW) || !fDragging)
|
||||
return;
|
||||
|
||||
int32 target = IndexOf(point);
|
||||
if (target == -1)
|
||||
target = CountItems();
|
||||
|
||||
// correct the target insertion index
|
||||
if (target == fDragIndex || target == fDragIndex + 1)
|
||||
target = -1;
|
||||
|
||||
if (target == fLastDragTarget)
|
||||
return;
|
||||
|
||||
// remove old target indicator
|
||||
if (fLastDragTarget != -1)
|
||||
DrawDragTargetIndicator(fLastDragTarget);
|
||||
|
||||
// draw new one
|
||||
fLastDragTarget = target;
|
||||
if (target != -1)
|
||||
DrawDragTargetIndicator(target);
|
||||
}
|
||||
|
||||
virtual void MouseUp(BPoint point)
|
||||
{
|
||||
if (fDragging)
|
||||
{
|
||||
fDragging = false;
|
||||
if (fLastDragTarget != -1)
|
||||
DrawDragTargetIndicator(fLastDragTarget);
|
||||
}
|
||||
BListView::MouseUp(point);
|
||||
}
|
||||
|
||||
virtual void MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch(msg->what)
|
||||
{
|
||||
case kMsgItemDragged:
|
||||
{
|
||||
int32 source = msg->FindInt32("index");
|
||||
BPoint point = msg->FindPoint("_drop_point_");
|
||||
ConvertFromScreen(&point);
|
||||
int32 to = IndexOf(point);
|
||||
if (to > fDragIndex)
|
||||
to--;
|
||||
if (to == -1)
|
||||
to = CountItems() - 1;
|
||||
|
||||
if (source != to)
|
||||
{
|
||||
MoveItem(source,to);
|
||||
|
||||
if (fItemMovedMessage != NULL)
|
||||
{
|
||||
BMessage msg(fItemMovedMessage->what);
|
||||
msg.AddInt32("from",source);
|
||||
msg.AddInt32("to",to);
|
||||
Messenger().SendMessage(&msg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
BListView::MessageReceived(msg);
|
||||
}
|
||||
|
||||
private:
|
||||
bool fDragging;
|
||||
int32 fLastDragTarget,fDragIndex;
|
||||
BMessage *fItemMovedMessage;
|
||||
};
|
||||
|
||||
|
||||
void GetPrettyDescriptiveName(BPath &path, char *name, BMessage *msg = NULL)
|
||||
{
|
||||
strcpy(name, path.Leaf());
|
||||
|
||||
image_id image = load_add_on(path.Path());
|
||||
if (image < B_OK)
|
||||
return;
|
||||
|
||||
if (msg)
|
||||
{
|
||||
status_t (* descriptive_name)(BMessage *,char *);
|
||||
if (get_image_symbol(image,"descriptive_name",B_SYMBOL_TYPE_TEXT,(void **)&descriptive_name) == B_OK)
|
||||
(*descriptive_name)(msg,name);
|
||||
}
|
||||
unload_add_on(image);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
FiltersConfigView::FiltersConfigView(BRect rect,Account *account)
|
||||
: BBox(rect),
|
||||
fAccount(account),
|
||||
fFilterView(NULL)
|
||||
{
|
||||
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING);
|
||||
|
||||
BMenuItem *item;
|
||||
BMessage *msg;
|
||||
if (fChain = fAccount->Inbound())
|
||||
{
|
||||
menu->AddItem(item = new BMenuItem(MDR_DIALECT_CHOICE ("Incoming E-mail Filters","受信フィルタ"),msg = new BMessage(kMsgChainSelected)));
|
||||
msg->AddPointer("chain",fChain);
|
||||
item->SetMarked(true);
|
||||
}
|
||||
if (BMailChain *chain = fAccount->Outbound())
|
||||
{
|
||||
menu->AddItem(item = new BMenuItem(MDR_DIALECT_CHOICE ("Outgoing E-mail Filters","送信フィルタ"),msg = new BMessage(kMsgChainSelected)));
|
||||
msg->AddPointer("chain",chain);
|
||||
if (fChain == NULL)
|
||||
{
|
||||
item->SetMarked(true);
|
||||
fChain = chain;
|
||||
}
|
||||
}
|
||||
|
||||
fChainsField = new BMenuField(BRect(0,0,200,40),NULL,NULL,menu);
|
||||
fChainsField->ResizeToPreferred();
|
||||
SetLabel(fChainsField);
|
||||
|
||||
// determine font height
|
||||
font_height fontHeight;
|
||||
fChainsField->GetFontHeight(&fontHeight);
|
||||
int32 height = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 5;
|
||||
|
||||
rect = Bounds().InsetByCopy(10,10);
|
||||
rect.top += 18;
|
||||
rect.right -= B_V_SCROLL_BAR_WIDTH;
|
||||
rect.bottom = rect.top + 4 * height + 2;
|
||||
fListView = new DragListView(rect,NULL,B_SINGLE_SELECTION_LIST,B_FOLLOW_ALL,new BMessage(kMsgFilterMoved));
|
||||
AddChild(new BScrollView(NULL,fListView,B_FOLLOW_ALL,0,false,true));
|
||||
rect.right += B_V_SCROLL_BAR_WIDTH;
|
||||
|
||||
// fListView->Select(gSettings.formats.IndexOf(format));
|
||||
fListView->SetSelectionMessage(new BMessage(kMsgFilterSelected));
|
||||
|
||||
rect.top = rect.bottom + 8; rect.bottom = rect.top + height;
|
||||
BRect sizeRect = rect; sizeRect.right = sizeRect.left + 30 + fChainsField->StringWidth(MDR_DIALECT_CHOICE ("Add Filter","フィルタの追加"));
|
||||
|
||||
menu = new BPopUpMenu(MDR_DIALECT_CHOICE ("Add Filter","フィルタの追加"));
|
||||
menu->SetRadioMode(false);
|
||||
|
||||
fAddField = new BMenuField(rect,NULL,NULL,menu);
|
||||
fAddField->ResizeToPreferred();
|
||||
AddChild(fAddField);
|
||||
|
||||
sizeRect.left = sizeRect.right + 5; sizeRect.right = sizeRect.left + 30 + fChainsField->StringWidth(MDR_DIALECT_CHOICE ("Remove","削除"));
|
||||
sizeRect.top--;
|
||||
AddChild(fRemoveButton = new BButton(sizeRect,NULL,MDR_DIALECT_CHOICE ("Remove","削除"),new BMessage(kMsgRemoveFilter),B_FOLLOW_BOTTOM));
|
||||
|
||||
ResizeTo(Bounds().Width(),sizeRect.bottom + 10);
|
||||
SetTo(fChain);
|
||||
}
|
||||
|
||||
|
||||
FiltersConfigView::~FiltersConfigView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FiltersConfigView::SelectFilter(int32 index)
|
||||
{
|
||||
if (Parent())
|
||||
Parent()->Hide();
|
||||
|
||||
// remove old config view
|
||||
if (fFilterView)
|
||||
{
|
||||
Parent()->RemoveChild(fFilterView);
|
||||
|
||||
// update the name in the list
|
||||
BStringItem *item = (BStringItem *)fListView->ItemAt(fFilterView->fIndex - fFirst);
|
||||
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BPath path(fFilterView->fEntryRef);
|
||||
GetPrettyDescriptiveName(path, name, fFilterView->fMessage);
|
||||
item->SetText(name);
|
||||
|
||||
delete fFilterView;
|
||||
fFilterView = NULL;
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
// add new config view
|
||||
BMessage *msg = new BMessage();
|
||||
entry_ref *ref = new entry_ref();
|
||||
if (fChain->GetFilter(index + fFirst,msg,ref) >= B_OK && Parent())
|
||||
{
|
||||
fFilterView = new FilterConfigView(fChain,index + fFirst,msg,ref);
|
||||
if (fFilterView->InitCheck() >= B_OK)
|
||||
Parent()->AddChild(fFilterView);
|
||||
else
|
||||
{
|
||||
delete fFilterView;
|
||||
fFilterView = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete msg;
|
||||
delete ref;
|
||||
}
|
||||
}
|
||||
|
||||
// re-layout the view containing the config view
|
||||
if (CenterContainer *container = dynamic_cast<CenterContainer *>(Parent()))
|
||||
container->Layout();
|
||||
|
||||
if (Parent())
|
||||
Parent()->Show();
|
||||
}
|
||||
|
||||
|
||||
void FiltersConfigView::SetTo(BMailChain *chain)
|
||||
{
|
||||
// remove the filter config view
|
||||
SelectFilter(-1);
|
||||
|
||||
for (int32 i = fListView->CountItems();i-- > 0;)
|
||||
{
|
||||
BStringItem *item = (BStringItem *)fListView->RemoveItem(i);
|
||||
delete item;
|
||||
}
|
||||
|
||||
if (chain->ChainDirection() == inbound)
|
||||
{
|
||||
fFirst = 2; // skip protocol (e.g. POP3), and Parser
|
||||
fLast = 2; // skip Notifier, and Folder
|
||||
}
|
||||
else
|
||||
{
|
||||
fFirst = 1; // skip Producer
|
||||
fLast = 1; // skip protocol (e.g. SMTP)
|
||||
}
|
||||
int32 last = chain->CountFilters() - fLast;
|
||||
for (int32 i = fFirst;i < last;i++)
|
||||
{
|
||||
BMessage msg;
|
||||
entry_ref ref;
|
||||
if (chain->GetFilter(i,&msg,&ref) == B_OK)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BPath addon(&ref);
|
||||
GetPrettyDescriptiveName(addon, name, &msg);
|
||||
|
||||
fListView->AddItem(new BStringItem(name));
|
||||
}
|
||||
}
|
||||
fChain = chain;
|
||||
|
||||
/*** search inbound/outbound filters ***/
|
||||
|
||||
// remove old filter items
|
||||
BMenu *menu = fAddField->Menu();
|
||||
for (int32 i = menu->CountItems();i-- > 0;)
|
||||
{
|
||||
BMenuItem *item = menu->RemoveItem(i);
|
||||
delete item;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
path.Append("mail_daemon");
|
||||
|
||||
if (fChain->ChainDirection() == inbound)
|
||||
path.Append("inbound_filters");
|
||||
else
|
||||
path.Append("outbound_filters");
|
||||
|
||||
BDirectory dir(path.Path());
|
||||
entry_ref ref;
|
||||
while (dir.GetNextRef(&ref) == B_OK)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BPath path(&ref);
|
||||
GetPrettyDescriptiveName(path, name);
|
||||
|
||||
BMenuItem *item;
|
||||
BMessage *msg;
|
||||
menu->AddItem(item = new BMenuItem(name,msg = new BMessage(kMsgAddFilter)));
|
||||
msg->AddRef("filter",&ref);
|
||||
}
|
||||
}
|
||||
menu->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
void FiltersConfigView::AttachedToWindow()
|
||||
{
|
||||
fChainsField->Menu()->SetTargetForItems(this);
|
||||
fListView->SetTarget(this);
|
||||
fAddField->Menu()->SetTargetForItems(this);
|
||||
fRemoveButton->SetTarget(this);
|
||||
}
|
||||
|
||||
|
||||
void FiltersConfigView::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case kMsgChainSelected:
|
||||
{
|
||||
BMailChain *chain;
|
||||
if (msg->FindPointer("chain",(void **)&chain) < B_OK)
|
||||
break;
|
||||
|
||||
SetTo(chain);
|
||||
break;
|
||||
}
|
||||
case kMsgAddFilter:
|
||||
{
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("filter",&ref) < B_OK)
|
||||
break;
|
||||
|
||||
BMessage msg;
|
||||
if (fChain->AddFilter(fChain->CountFilters() - fLast, msg, ref) >= B_OK)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BPath path(&ref);
|
||||
GetPrettyDescriptiveName(path, name, &msg);
|
||||
fListView->AddItem(new BStringItem(name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMsgRemoveFilter:
|
||||
{
|
||||
int32 index = fListView->CurrentSelection();
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
SelectFilter(-1);
|
||||
if (BStringItem *item = (BStringItem *)fListView->RemoveItem(index))
|
||||
{
|
||||
fChain->RemoveFilter(index + fFirst);
|
||||
delete item;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMsgFilterSelected:
|
||||
{
|
||||
int32 index;
|
||||
if (msg->FindInt32("index",&index) < B_OK)
|
||||
break;
|
||||
|
||||
SelectFilter(index);
|
||||
break;
|
||||
}
|
||||
case kMsgFilterMoved:
|
||||
{
|
||||
int32 from = msg->FindInt32("from");
|
||||
int32 to = msg->FindInt32("to");
|
||||
if (from == to)
|
||||
break;
|
||||
|
||||
from += fFirst;
|
||||
to += fFirst;
|
||||
|
||||
entry_ref ref;
|
||||
BMessage settings;
|
||||
if (fChain->GetFilter(from,&settings,&ref) == B_OK)
|
||||
{
|
||||
// disable filter view saving
|
||||
if (fFilterView && fFilterView->fIndex == from)
|
||||
fFilterView->fIndex = -1;
|
||||
|
||||
fChain->RemoveFilter(from);
|
||||
|
||||
if (fChain->AddFilter(to,settings,ref) < B_OK)
|
||||
{
|
||||
(new BAlert("E-mail",MDR_DIALECT_CHOICE (
|
||||
"Could not move filter, filter deleted.",
|
||||
"フィルタが削除された為、移動できません"),"Ok"))->Go();
|
||||
|
||||
// the filter view belongs to the moved filter
|
||||
if (fFilterView && fFilterView->fIndex == -1)
|
||||
SelectFilter(-1);
|
||||
|
||||
fListView->RemoveItem(msg->FindInt32("to"));
|
||||
}
|
||||
else if (fFilterView)
|
||||
{
|
||||
int32 index = fFilterView->fIndex;
|
||||
if (index == -1)
|
||||
// the view belongs to the moved filter
|
||||
fFilterView->fIndex = to;
|
||||
else if (index > from && index < to)
|
||||
// the view belongs to another filter (between the
|
||||
// 'from' & 'to' positions) - all others can keep
|
||||
// their index value
|
||||
fFilterView->fIndex--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#ifndef CONFIG_VIEWS_H
|
||||
#define CONFIG_VIEWS_H
|
||||
/* ConfigViews - config views for the account, protocols, and filters
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include <interface/Box.h>
|
||||
#include <kernel/image.h>
|
||||
|
||||
class BTextControl;
|
||||
class BListView;
|
||||
class BMenuField;
|
||||
class BButton;
|
||||
|
||||
class BMailChain;
|
||||
|
||||
class Account;
|
||||
|
||||
|
||||
class AccountConfigView : public BBox
|
||||
{
|
||||
public:
|
||||
AccountConfigView(BRect rect,Account *account);
|
||||
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
|
||||
void UpdateViews();
|
||||
|
||||
private:
|
||||
BTextControl *fNameControl, *fRealNameControl, *fReturnAddressControl;
|
||||
BMenuField *fTypeField;
|
||||
Account *fAccount;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
class ProtocolsConfigView;
|
||||
class FiltersConfigView;
|
||||
|
||||
class FilterConfigView : public BBox
|
||||
{
|
||||
public:
|
||||
FilterConfigView(BMailChain *chain,int32 index,BMessage *msg,entry_ref *ref);
|
||||
~FilterConfigView();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
protected:
|
||||
friend FiltersConfigView;
|
||||
|
||||
void Load(BMessage *msg,entry_ref *ref);
|
||||
void Remove(bool deleteMessage = true);
|
||||
|
||||
BView *fConfigView;
|
||||
|
||||
BMailChain *fChain;
|
||||
int32 fIndex;
|
||||
BMessage *fMessage;
|
||||
entry_ref *fEntryRef;
|
||||
image_id fImage;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class ProtocolsConfigView : public FilterConfigView
|
||||
{
|
||||
public:
|
||||
ProtocolsConfigView(BMailChain *chain, int32 index, BMessage *msg, entry_ref *ref);
|
||||
|
||||
void AttachedToWindow();
|
||||
void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
BMenuField *fProtocolsMenuField;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class FiltersConfigView : public BBox
|
||||
{
|
||||
public:
|
||||
FiltersConfigView(BRect rect,Account *account);
|
||||
~FiltersConfigView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
// virtual void DetachedFromWindow();
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
void SelectFilter(int32 index);
|
||||
void SetTo(BMailChain *chain);
|
||||
|
||||
Account *fAccount;
|
||||
BMailChain *fChain;
|
||||
int32 fFirst, fLast;
|
||||
|
||||
BMenuField *fChainsField;
|
||||
BListView *fListView;
|
||||
BMenuField *fAddField;
|
||||
BButton *fRemoveButton;
|
||||
FilterConfigView *fFilterView;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_VIEWS_H */
|
||||
@@ -0,0 +1,866 @@
|
||||
/* ConfigWindow - main eMail config window
|
||||
**
|
||||
** Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "ConfigWindow.h"
|
||||
#include "CenterContainer.h"
|
||||
#include "Account.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <ListView.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StringView.h>
|
||||
#include <Button.h>
|
||||
#include <CheckBox.h>
|
||||
#include <MenuField.h>
|
||||
#include <TextControl.h>
|
||||
#include <TextView.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Screen.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <MenuBar.h>
|
||||
#include <TabView.h>
|
||||
#include <Box.h>
|
||||
#include <Alert.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Roster.h>
|
||||
#include <Resources.h>
|
||||
#include <Region.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <AppFileInfo.h>
|
||||
|
||||
#include <MailSettings.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <MDRLanguage.h>
|
||||
|
||||
// define if you want to have an apply button
|
||||
//#define HAVE_APPLY_BUTTON
|
||||
|
||||
const char *kEMail = "[email protected]";
|
||||
const char *kMailto = "mailto:[email protected]";
|
||||
const char *kBugsitePretty = "Bug-Tracker at SourceForge.net";
|
||||
const char *kBugsite = "http://sourceforge.net/tracker/?func=add&group_id=26926&atid=388726";
|
||||
const char *kWebsite = "http://www.bug-br.org.br/zoidberg/";
|
||||
const rgb_color kLinkColor = {40,40,180};
|
||||
|
||||
|
||||
const uint32 kMsgAccountSelected = 'acsl';
|
||||
const uint32 kMsgAddAccount = 'adac';
|
||||
const uint32 kMsgRemoveAccount = 'rmac';
|
||||
|
||||
const uint32 kMsgIntervalUnitChanged = 'iuch';
|
||||
|
||||
const uint32 kMsgShowStatusWindowChanged = 'shst';
|
||||
const uint32 kMsgStatusLookChanged = 'lkch';
|
||||
const uint32 kMsgStatusWorkspaceChanged = 'wsch';
|
||||
|
||||
const uint32 kMsgApplySettings = 'apst';
|
||||
const uint32 kMsgSaveSettings = 'svst';
|
||||
const uint32 kMsgRevertSettings = 'rvst';
|
||||
const uint32 kMsgCancelSettings = 'cnst';
|
||||
|
||||
class AccountsListView : public BListView {
|
||||
public:
|
||||
AccountsListView(BRect rect) : BListView(rect,NULL,B_SINGLE_SELECTION_LIST,B_FOLLOW_ALL) {}
|
||||
virtual void KeyDown(const char *bytes, int32 numBytes) {
|
||||
if (numBytes != 1)
|
||||
return;
|
||||
|
||||
if ((*bytes == B_DELETE) || (*bytes == B_BACKSPACE))
|
||||
Window()->PostMessage(kMsgRemoveAccount);
|
||||
|
||||
BListView::KeyDown(bytes,numBytes);
|
||||
}
|
||||
};
|
||||
|
||||
class BitmapView : public BView
|
||||
{
|
||||
public:
|
||||
BitmapView(BBitmap *bitmap) : BView(bitmap->Bounds(),NULL,B_FOLLOW_NONE,B_WILL_DRAW)
|
||||
{
|
||||
fBitmap = bitmap;
|
||||
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
}
|
||||
|
||||
~BitmapView()
|
||||
{
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
virtual void AttachedToWindow()
|
||||
{
|
||||
SetViewColor(Parent()->ViewColor());
|
||||
|
||||
MoveTo((Parent()->Bounds().Width() - Bounds().Width()) / 2,Frame().top);
|
||||
}
|
||||
|
||||
virtual void Draw(BRect updateRect)
|
||||
{
|
||||
DrawBitmap(fBitmap,updateRect,updateRect);
|
||||
}
|
||||
|
||||
private:
|
||||
BBitmap *fBitmap;
|
||||
};
|
||||
|
||||
|
||||
class AboutTextView : public BTextView
|
||||
{
|
||||
public:
|
||||
AboutTextView(BRect rect) : BTextView(rect,NULL,rect.OffsetToCopy(B_ORIGIN),B_FOLLOW_NONE,B_WILL_DRAW)
|
||||
{
|
||||
int32 major = 0,middle = 0,minor = 0,variety = 0,internal = 1;
|
||||
|
||||
// get version information for app
|
||||
|
||||
app_info appInfo;
|
||||
if (be_app->GetAppInfo(&appInfo) == B_OK)
|
||||
{
|
||||
BFile file(&appInfo.ref,B_READ_ONLY);
|
||||
if (file.InitCheck() == B_OK)
|
||||
{
|
||||
BAppFileInfo info(&file);
|
||||
if (info.InitCheck() == B_OK)
|
||||
{
|
||||
version_info versionInfo;
|
||||
if (info.GetVersionInfo(&versionInfo,B_APP_VERSION_KIND) == B_OK)
|
||||
{
|
||||
major = versionInfo.major;
|
||||
middle = versionInfo.middle;
|
||||
minor = versionInfo.minor;
|
||||
variety = versionInfo.variety;
|
||||
internal = versionInfo.internal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// prepare version variety string
|
||||
const char *varietyStrings[] = {"Development","Alpha","Beta","Gamma","Golden master","Final"};
|
||||
char varietyString[32];
|
||||
strcpy(varietyString,varietyStrings[variety % 6]);
|
||||
if (variety < 5)
|
||||
sprintf(varietyString + strlen(varietyString),"/%li",internal);
|
||||
|
||||
char s[512];
|
||||
sprintf(s, "Mail Daemon Replacement\n\n"
|
||||
"by Dr. Zoidberg Enterprises. All rights reserved.\n\n"
|
||||
"Version %ld.%ld.%ld %s\n\n"
|
||||
"See LICENSE file included in the installation package for more information.\n\n\n\n"
|
||||
"You can contact us at:\n"
|
||||
"%s\n\n"
|
||||
"Please submit bug reports using the %s\n\n"
|
||||
"Project homepage at:\n%s",
|
||||
major,middle,minor,varietyString,
|
||||
kEMail,kBugsitePretty,kWebsite);
|
||||
|
||||
SetText(s);
|
||||
MakeEditable(false);
|
||||
MakeSelectable(false);
|
||||
|
||||
SetAlignment(B_ALIGN_CENTER);
|
||||
SetStylable(true);
|
||||
|
||||
// aethetical changes
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
font.SetSize(24);
|
||||
SetFontAndColor(0,23,&font,B_FONT_SIZE);
|
||||
|
||||
// center the view vertically
|
||||
rect = TextRect(); rect.OffsetTo(0,(Bounds().Height() - TextHeight(0,42)) / 2);
|
||||
SetTextRect(rect);
|
||||
|
||||
// set the link regions
|
||||
int start = strstr(s,kEMail) - s;
|
||||
int finish = start + strlen(kEMail);
|
||||
GetTextRegion(start,finish,&fMail);
|
||||
SetFontAndColor(start,finish,NULL,0,&kLinkColor);
|
||||
|
||||
start = strstr(s,kBugsitePretty) - s;
|
||||
finish = start + strlen(kBugsitePretty);
|
||||
GetTextRegion(start,finish,&fBugsite);
|
||||
SetFontAndColor(start,finish,NULL,0,&kLinkColor);
|
||||
|
||||
start = strstr(s,kWebsite) - s;
|
||||
finish = start + strlen(kWebsite);
|
||||
GetTextRegion(start,finish,&fWebsite);
|
||||
SetFontAndColor(start,finish,NULL,0,&kLinkColor);
|
||||
}
|
||||
|
||||
virtual void Draw(BRect updateRect)
|
||||
{
|
||||
BTextView::Draw(updateRect);
|
||||
|
||||
BRect rect(fMail.Frame());
|
||||
StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2));
|
||||
rect = fBugsite.Frame();
|
||||
StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2));
|
||||
rect = fWebsite.Frame();
|
||||
StrokeLine(BPoint(rect.left,rect.bottom-2),BPoint(rect.right,rect.bottom-2));
|
||||
}
|
||||
|
||||
virtual void MouseDown(BPoint point)
|
||||
{
|
||||
if (fMail.Contains(point)) {
|
||||
char *arg[] = {(char *)kMailto,NULL};
|
||||
be_roster->Launch("text/x-email",1,arg);
|
||||
} else if (fBugsite.Contains(point)) {
|
||||
char *arg[] = {(char *)kBugsite,NULL};
|
||||
be_roster->Launch("text/html",1,arg);
|
||||
} else if (fWebsite.Contains(point)) {
|
||||
char *arg[] = {(char *)kWebsite, NULL};
|
||||
be_roster->Launch("text/html", 1, arg);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BRegion fWebsite,fMail,fBugsite;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ConfigWindow::ConfigWindow()
|
||||
: BWindow(BRect(200.0, 200.0, 640.0, 640.0),
|
||||
"E-mail", B_TITLED_WINDOW,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
|
||||
fLastSelectedAccount(NULL),
|
||||
fSaveSettings(false)
|
||||
{
|
||||
/*** create controls ***/
|
||||
|
||||
BRect rect(Bounds());
|
||||
BView *top = new BView(rect,NULL,B_FOLLOW_ALL,0);
|
||||
top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
AddChild(top);
|
||||
|
||||
// determine font height
|
||||
font_height fontHeight;
|
||||
top->GetFontHeight(&fontHeight);
|
||||
int32 height = (int32)(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 5;
|
||||
|
||||
rect.InsetBy(5,5); rect.bottom -= 11 + height;
|
||||
BTabView *tabView = new BTabView(rect,NULL);
|
||||
|
||||
BView *view;
|
||||
rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4;
|
||||
tabView->AddTab(view = new BView(rect,NULL,B_FOLLOW_ALL,0));
|
||||
tabView->TabAt(0)->SetLabel(MDR_DIALECT_CHOICE ("Accounts","アカウント"));
|
||||
view->SetViewColor(top->ViewColor());
|
||||
|
||||
// accounts listview
|
||||
|
||||
rect = view->Bounds().InsetByCopy(8,8);
|
||||
rect.right = 140 - B_V_SCROLL_BAR_WIDTH;
|
||||
rect.bottom -= height + 12;
|
||||
fAccountsListView = new AccountsListView(rect);
|
||||
view->AddChild(new BScrollView(NULL,fAccountsListView,B_FOLLOW_ALL,0,false,true));
|
||||
rect.right += B_V_SCROLL_BAR_WIDTH;
|
||||
|
||||
rect.top = rect.bottom + 8; rect.bottom = rect.top + height;
|
||||
BRect sizeRect = rect;
|
||||
sizeRect.right = sizeRect.left + 30 + view->StringWidth(MDR_DIALECT_CHOICE ("Add","追加"));
|
||||
view->AddChild(new BButton(sizeRect,NULL,MDR_DIALECT_CHOICE ("Add","追加"),
|
||||
new BMessage(kMsgAddAccount),B_FOLLOW_BOTTOM));
|
||||
|
||||
sizeRect.left = sizeRect.right+3;
|
||||
sizeRect.right = sizeRect.left + 30 + view->StringWidth(MDR_DIALECT_CHOICE ("Remove","削除"));
|
||||
view->AddChild(fRemoveButton = new BButton(sizeRect,NULL,MDR_DIALECT_CHOICE ("Remove","削除"),
|
||||
new BMessage(kMsgRemoveAccount),B_FOLLOW_BOTTOM));
|
||||
|
||||
// accounts config view
|
||||
rect = view->Bounds();
|
||||
rect.left = fAccountsListView->Frame().right + B_V_SCROLL_BAR_WIDTH + 16;
|
||||
rect.right -= 10;
|
||||
view->AddChild(fConfigView = new CenterContainer(rect));
|
||||
|
||||
MakeHowToView();
|
||||
|
||||
// general settings
|
||||
|
||||
rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4;
|
||||
tabView->AddTab(view = new CenterContainer(rect));
|
||||
tabView->TabAt(1)->SetLabel(MDR_DIALECT_CHOICE ("General","一般"));
|
||||
|
||||
rect = view->Bounds().InsetByCopy(8,8);
|
||||
rect.right -= 1; rect.bottom = rect.top + height * 5 + 15;
|
||||
BBox *box = new BBox(rect);
|
||||
box->SetLabel(MDR_DIALECT_CHOICE ("Retrieval Frequency","メールチェック間隔"));
|
||||
view->AddChild(box);
|
||||
|
||||
rect = box->Bounds().InsetByCopy(8,8);
|
||||
rect.top += 7; rect.bottom = rect.top + height + 5;
|
||||
BRect tile = rect.OffsetByCopy(0,1);
|
||||
int32 labelWidth = (int32)view->StringWidth(MDR_DIALECT_CHOICE ("Check every:","メールチェック間隔:"))+6;
|
||||
tile.right = 80 + labelWidth;
|
||||
fIntervalControl = new BTextControl(tile,"time",MDR_DIALECT_CHOICE ("Check every:","メールチェック間隔:"),
|
||||
NULL,NULL);
|
||||
fIntervalControl->SetDivider(labelWidth);
|
||||
box->AddChild(fIntervalControl);
|
||||
|
||||
BPopUpMenu *frequencyPopUp = new BPopUpMenu(B_EMPTY_STRING);
|
||||
const char *frequencyStrings[] = {
|
||||
MDR_DIALECT_CHOICE ("Never","チェックしない"),
|
||||
MDR_DIALECT_CHOICE ("Minutes","分毎チェック"),
|
||||
MDR_DIALECT_CHOICE ("Hours","時間毎チェック"),
|
||||
MDR_DIALECT_CHOICE ("Days","日間毎チェック")};
|
||||
BMenuItem *item;
|
||||
for (int32 i = 0;i < 4;i++)
|
||||
{
|
||||
frequencyPopUp->AddItem(item = new BMenuItem(frequencyStrings[i],new BMessage(kMsgIntervalUnitChanged)));
|
||||
if (i == 1)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
tile.left = tile.right + 5; tile.right = rect.right;
|
||||
tile.OffsetBy(0,-1);
|
||||
fIntervalUnitField = new BMenuField(tile,"frequency", B_EMPTY_STRING, frequencyPopUp);
|
||||
fIntervalUnitField->SetDivider(0.0);
|
||||
box->AddChild(fIntervalUnitField);
|
||||
|
||||
rect.OffsetBy(0,height + 9); rect.bottom -= 2;
|
||||
fPPPActiveCheckBox = new BCheckBox(rect,"ppp active",
|
||||
MDR_DIALECT_CHOICE ("only when PPP is active","PPP接続中時のみ"), NULL);
|
||||
box->AddChild(fPPPActiveCheckBox);
|
||||
|
||||
rect.OffsetBy(0,height + 9); rect.bottom -= 2;
|
||||
fPPPActiveSendCheckBox = new BCheckBox(rect,"ppp activesend",
|
||||
MDR_DIALECT_CHOICE ("Queue outgoing mail when PPP is inactive","PPP切断時、送信メールを送信箱に入れる"), NULL);
|
||||
box->AddChild(fPPPActiveSendCheckBox);
|
||||
|
||||
rect = box->Frame(); rect.bottom = rect.top + 4*height + 20;
|
||||
box = new BBox(rect);
|
||||
box->SetLabel(MDR_DIALECT_CHOICE ("Status Window","送受信状況の表示"));
|
||||
view->AddChild(box);
|
||||
|
||||
BPopUpMenu *statusPopUp = new BPopUpMenu(B_EMPTY_STRING);
|
||||
const char *statusModes[] = {
|
||||
MDR_DIALECT_CHOICE ("Never","表示しない"),
|
||||
MDR_DIALECT_CHOICE ("While Sending","送信時"),
|
||||
MDR_DIALECT_CHOICE ("While Sending / Fetching","送受信時"),
|
||||
MDR_DIALECT_CHOICE ("Always","常に表示")};
|
||||
BMessage *msg;
|
||||
for (int32 i = 0;i < 4;i++)
|
||||
{
|
||||
statusPopUp->AddItem(item = new BMenuItem(statusModes[i],msg = new BMessage(kMsgShowStatusWindowChanged)));
|
||||
msg->AddInt32("ShowStatusWindow",i);
|
||||
if (i == 0)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
rect = box->Bounds().InsetByCopy(8,8);
|
||||
rect.top += 7; rect.bottom = rect.top + height + 5;
|
||||
labelWidth = (int32)view->StringWidth(
|
||||
MDR_DIALECT_CHOICE ("Show Status Window:","ステータスの表示:")) + 8;
|
||||
fStatusModeField = new BMenuField(rect,"show status",
|
||||
MDR_DIALECT_CHOICE ("Show Status Window:","ステータスの表示:"),
|
||||
statusPopUp);
|
||||
fStatusModeField->SetDivider(labelWidth);
|
||||
box->AddChild(fStatusModeField);
|
||||
|
||||
BPopUpMenu *lookPopUp = new BPopUpMenu(B_EMPTY_STRING);
|
||||
const char *windowLookStrings[] = {
|
||||
MDR_DIALECT_CHOICE ("Normal, With Tab","タブ付通常"),
|
||||
MDR_DIALECT_CHOICE ("Normal, Border Only","ボーダーのみ通常"),
|
||||
MDR_DIALECT_CHOICE ("Floating","フローティング"),
|
||||
MDR_DIALECT_CHOICE ("Thin Border","細いボーダー"),
|
||||
MDR_DIALECT_CHOICE ("No Border","ボーダー無し")};
|
||||
for (int32 i = 0;i < 5;i++)
|
||||
{
|
||||
lookPopUp->AddItem(item = new BMenuItem(windowLookStrings[i],msg = new BMessage(kMsgStatusLookChanged)));
|
||||
msg->AddInt32("StatusWindowLook",i);
|
||||
if (i == 0)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
rect.OffsetBy(0, height + 6);
|
||||
fStatusLookField = new BMenuField(rect,"status look",
|
||||
MDR_DIALECT_CHOICE ("Window Look:","ウィンドウ外観:"),lookPopUp);
|
||||
fStatusLookField->SetDivider(labelWidth);
|
||||
box->AddChild(fStatusLookField);
|
||||
|
||||
BPopUpMenu *workspacesPopUp = new BPopUpMenu(B_EMPTY_STRING);
|
||||
workspacesPopUp->AddItem(item = new BMenuItem(
|
||||
MDR_DIALECT_CHOICE ("Current Workspace","使用中ワークスペース"),
|
||||
msg = new BMessage(kMsgStatusWorkspaceChanged)));
|
||||
msg->AddInt32("StatusWindowWorkSpace", 0);
|
||||
workspacesPopUp->AddItem(item = new BMenuItem(
|
||||
MDR_DIALECT_CHOICE ("All Workspaces","全てのワークスペース"),
|
||||
msg = new BMessage(kMsgStatusWorkspaceChanged)));
|
||||
msg->AddInt32("StatusWindowWorkSpace", -1);
|
||||
|
||||
rect.OffsetBy(0,height + 6);
|
||||
fStatusWorkspaceField = new BMenuField(rect,"status workspace",
|
||||
MDR_DIALECT_CHOICE ("Window visible on:","表示場所:"),workspacesPopUp);
|
||||
fStatusWorkspaceField->SetDivider(labelWidth);
|
||||
box->AddChild(fStatusWorkspaceField);
|
||||
|
||||
rect = box->Frame(); rect.bottom = rect.top + 3*height + 13;
|
||||
box = new BBox(rect);
|
||||
box->SetLabel(MDR_DIALECT_CHOICE ("Deskbar Icon","デスクバーアイコンリンク"));
|
||||
view->AddChild(box);
|
||||
|
||||
rect = box->Bounds().InsetByCopy(8,8);
|
||||
rect.top += 7; rect.bottom = rect.top + height + 5;
|
||||
BStringView *stringView = new BStringView(rect,B_EMPTY_STRING, MDR_DIALECT_CHOICE (
|
||||
"The menu links are links to folders in a real folder like the Be menu.",
|
||||
"デスクバーで表示する項目の設定"));
|
||||
box->AddChild(stringView);
|
||||
stringView->SetAlignment(B_ALIGN_CENTER);
|
||||
stringView->ResizeToPreferred();
|
||||
// BStringView::ResizeToPreferred() changes the width, so that the
|
||||
// alignment has no effect anymore
|
||||
stringView->ResizeTo(rect.Width(), stringView->Bounds().Height());
|
||||
|
||||
rect.left += 100; rect.right -= 100;
|
||||
rect.OffsetBy(0,height + 1);
|
||||
BButton *button = new BButton(rect,B_EMPTY_STRING,
|
||||
MDR_DIALECT_CHOICE ("Configure Menu Links","メニューリンクの設定"),
|
||||
msg = new BMessage(B_REFS_RECEIVED));
|
||||
box->AddChild(button);
|
||||
button->SetTarget(BMessenger("application/x-vnd.Be-TRAK"));
|
||||
|
||||
BPath path;
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
path.Append("Mail/Menu Links");
|
||||
BEntry entry(path.Path());
|
||||
if (entry.InitCheck() == B_OK && entry.Exists()) {
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
msg->AddRef("refs", &ref);
|
||||
}
|
||||
else
|
||||
button->SetEnabled(false);
|
||||
|
||||
rect = box->Frame(); rect.bottom = rect.top + 2*height + 6;
|
||||
box = new BBox(rect);
|
||||
box->SetLabel(MDR_DIALECT_CHOICE ("Misc.","その他の設定"));
|
||||
view->AddChild(box);
|
||||
|
||||
rect = box->Bounds().InsetByCopy(8,8);
|
||||
rect.top += 7; rect.bottom = rect.top + height + 5;
|
||||
fAutoStartCheckBox = new BCheckBox(rect,"start daemon",
|
||||
MDR_DIALECT_CHOICE ("Auto-Start Mail Daemon","Mail Daemonを自動起動"),NULL);
|
||||
box->AddChild(fAutoStartCheckBox);
|
||||
|
||||
// about page
|
||||
|
||||
rect = tabView->Bounds(); rect.bottom -= tabView->TabHeight() + 4;
|
||||
tabView->AddTab(view = new BView(rect,NULL,B_FOLLOW_ALL,0));
|
||||
tabView->TabAt(2)->SetLabel(MDR_DIALECT_CHOICE ("About","情報"));
|
||||
view->SetViewColor(top->ViewColor());
|
||||
|
||||
AboutTextView *about = new AboutTextView(rect);
|
||||
about->SetViewColor(top->ViewColor());
|
||||
view->AddChild(about);
|
||||
|
||||
// save/cancel/revert buttons
|
||||
|
||||
top->AddChild(tabView);
|
||||
|
||||
rect = tabView->Frame();
|
||||
rect.top = rect.bottom + 5; rect.bottom = rect.top + height + 5;
|
||||
BButton *saveButton = new BButton(rect,"save",
|
||||
MDR_DIALECT_CHOICE ("Save","保存"),
|
||||
new BMessage(kMsgSaveSettings));
|
||||
float w,h;
|
||||
saveButton->GetPreferredSize(&w,&h);
|
||||
saveButton->ResizeTo(w,h);
|
||||
saveButton->MoveTo(rect.right - w, rect.top);
|
||||
top->AddChild(saveButton);
|
||||
|
||||
BButton *cancelButton = new BButton(rect,"cancel",
|
||||
MDR_DIALECT_CHOICE ("Cancel","中止"),
|
||||
new BMessage(kMsgCancelSettings));
|
||||
cancelButton->GetPreferredSize(&w,&h);
|
||||
cancelButton->ResizeTo(w,h);
|
||||
#ifdef HAVE_APPLY_BUTTON
|
||||
cancelButton->MoveTo(saveButton->Frame().left - w - 5,rect.top);
|
||||
#else
|
||||
cancelButton->MoveTo(saveButton->Frame().left - w - 20,rect.top);
|
||||
#endif
|
||||
top->AddChild(cancelButton);
|
||||
|
||||
#ifdef HAVE_APPLY_BUTTON
|
||||
BButton *applyButton = new BButton(rect,"apply",
|
||||
MDR_DIALECT_CHOICE ("Apply","適用"),
|
||||
new BMessage(kMsgApplySettings));
|
||||
applyButton->GetPreferredSize(&w,&h);
|
||||
applyButton->ResizeTo(w,h);
|
||||
applyButton->MoveTo(cancelButton->Frame().left - w - 20,rect.top);
|
||||
top->AddChild(applyButton);
|
||||
#endif
|
||||
|
||||
BButton *revertButton = new BButton(rect,"revert",
|
||||
MDR_DIALECT_CHOICE ("Revert","復元"),
|
||||
new BMessage(kMsgRevertSettings));
|
||||
revertButton->GetPreferredSize(&w,&h);
|
||||
revertButton->ResizeTo(w,h);
|
||||
#ifdef HAVE_APPLY_BUTTON
|
||||
revertButton->MoveTo(applyButton->Frame().left - w - 5,rect.top);
|
||||
#else
|
||||
revertButton->MoveTo(cancelButton->Frame().left - w - 6,rect.top);
|
||||
#endif
|
||||
top->AddChild(revertButton);
|
||||
|
||||
LoadSettings();
|
||||
|
||||
fAccountsListView->SetSelectionMessage(new BMessage(kMsgAccountSelected));
|
||||
}
|
||||
|
||||
|
||||
ConfigWindow::~ConfigWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigWindow::MakeHowToView()
|
||||
{
|
||||
BResources *resources = BApplication::AppResources();
|
||||
if (resources)
|
||||
{
|
||||
size_t length;
|
||||
char *buffer = (char *)resources->FindResource('ICON',101,&length);
|
||||
if (buffer)
|
||||
{
|
||||
BBitmap *bitmap = new BBitmap(BRect(0,0,63,63),B_CMAP8);
|
||||
if (bitmap && bitmap->InitCheck() == B_OK)
|
||||
{
|
||||
// copy and enlarge a 32x32 8-bit bitmap
|
||||
char *bits = (char *)bitmap->Bits();
|
||||
for (int32 i = 0, j = -64;i < length;i++)
|
||||
{
|
||||
if ((i % 32) == 0)
|
||||
j += 64;
|
||||
|
||||
char *b = bits + (i << 1) + j;
|
||||
b[0] = b[1] = b[64] = b[65] = buffer[i];
|
||||
}
|
||||
fConfigView->AddChild(new BitmapView(bitmap));
|
||||
}
|
||||
else
|
||||
delete bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
BRect rect = fConfigView->Bounds();
|
||||
BTextView *text = new BTextView(rect,NULL,rect,B_FOLLOW_NONE,B_WILL_DRAW);
|
||||
text->SetViewColor(fConfigView->Parent()->ViewColor());
|
||||
text->SetAlignment(B_ALIGN_CENTER);
|
||||
text->SetText(
|
||||
MDR_DIALECT_CHOICE ("\n\nCreate a new account using the \"Add\" button.\n\n"
|
||||
"Delete accounts (or only the inbound/outbound) by using the \"Remove\" button on the selected item.\n\n"
|
||||
"Select an item in the list to edit its configuration.",
|
||||
"\n\nアカウントの新規作成は\"追加\"ボタンを\n使います。"
|
||||
"\n\nアカウント自体またはアカウントの\n送受信設定を削除するには\n項目を選択して\"削除\"ボタンを使います。"
|
||||
"\n\nアカウント内容の変更は、\nマウスで項目をクリックしてください。"));
|
||||
rect = text->Bounds();
|
||||
text->ResizeTo(rect.Width(),text->TextHeight(0,42));
|
||||
text->SetTextRect(rect);
|
||||
|
||||
text->MakeEditable(false);
|
||||
text->MakeSelectable(false);
|
||||
|
||||
fConfigView->AddChild(text);
|
||||
|
||||
static_cast<CenterContainer *>(fConfigView)->Layout();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigWindow::LoadSettings()
|
||||
{
|
||||
Accounts::Delete();
|
||||
Accounts::Create(fAccountsListView,fConfigView);
|
||||
|
||||
// load in general settings
|
||||
BMailSettings *settings = new BMailSettings();
|
||||
status_t status = SetToGeneralSettings(settings);
|
||||
if (status == B_OK)
|
||||
{
|
||||
// adjust own window frame
|
||||
BScreen screen(this);
|
||||
BRect screenFrame(screen.Frame().InsetByCopy(0,5));
|
||||
BRect frame(settings->ConfigWindowFrame());
|
||||
|
||||
if (screenFrame.Contains(frame.LeftTop()))
|
||||
MoveTo(frame.LeftTop());
|
||||
else // center on screen
|
||||
MoveTo((screenFrame.Width() - frame.Width()) / 2,(screenFrame.Height() - frame.Height()) / 2);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MDR_DIALECT_CHOICE (
|
||||
"Error retrieving general settings: %s\n",
|
||||
"一般設定の収得に失敗: %s\n"),
|
||||
strerror(status));
|
||||
|
||||
delete settings;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigWindow::SaveSettings()
|
||||
{
|
||||
// remove config views
|
||||
((CenterContainer *)fConfigView)->DeleteChildren();
|
||||
|
||||
/*** save general settings ***/
|
||||
|
||||
// figure out time interval
|
||||
float interval;
|
||||
sscanf(fIntervalControl->Text(),"%f",&interval);
|
||||
float multiplier = 0;
|
||||
switch (fIntervalUnitField->Menu()->IndexOf(fIntervalUnitField->Menu()->FindMarked())) {
|
||||
case 1: // minutes
|
||||
multiplier = 60;
|
||||
break;
|
||||
case 2: // hours
|
||||
multiplier = 60 * 60;
|
||||
break;
|
||||
case 3: // days
|
||||
multiplier = 24 * 60 * 60;
|
||||
break;
|
||||
}
|
||||
time_t time = (time_t)(multiplier * interval);
|
||||
|
||||
// apply and save general settings
|
||||
BMailSettings settings;
|
||||
if (fSaveSettings) {
|
||||
settings.SetAutoCheckInterval(time * 1e6);
|
||||
settings.SetCheckOnlyIfPPPUp(fPPPActiveCheckBox->Value() == B_CONTROL_ON);
|
||||
settings.SetSendOnlyIfPPPUp(fPPPActiveSendCheckBox->Value() == B_CONTROL_ON);
|
||||
settings.SetDaemonAutoStarts(fAutoStartCheckBox->Value() == B_CONTROL_ON);
|
||||
|
||||
// status mode (alway, fetching/retrieving, ...)
|
||||
int32 index = fStatusModeField->Menu()->IndexOf(fStatusModeField->Menu()->FindMarked());
|
||||
settings.SetShowStatusWindow(index);
|
||||
|
||||
// status look (border style, ...)
|
||||
index = fStatusLookField->Menu()->IndexOf(fStatusLookField->Menu()->FindMarked());
|
||||
settings.SetStatusWindowLook(index);
|
||||
|
||||
// status workspaces
|
||||
index = fStatusWorkspaceField->Menu()->IndexOf(fStatusWorkspaceField->Menu()->FindMarked());
|
||||
uint32 workspaces = 0;
|
||||
if (index == 0) {
|
||||
// current workspace
|
||||
workspaces = Workspaces();
|
||||
// ToDo: correct would be to ask the status window which workspace it is on
|
||||
} else
|
||||
workspaces = B_ALL_WORKSPACES;
|
||||
|
||||
settings.SetStatusWindowWorkspaces(workspaces);
|
||||
} else {
|
||||
// restore status window look
|
||||
settings.SetStatusWindowLook(settings.StatusWindowLook());
|
||||
}
|
||||
|
||||
settings.SetConfigWindowFrame(Frame());
|
||||
settings.Save();
|
||||
|
||||
/*** save accounts ***/
|
||||
|
||||
if (fSaveSettings)
|
||||
Accounts::Save();
|
||||
|
||||
// start the mail_daemon if auto start was selected
|
||||
if (fSaveSettings && fAutoStartCheckBox->Value() == B_CONTROL_ON
|
||||
&& !be_roster->IsRunning("application/x-vnd.Be-POST"))
|
||||
{
|
||||
be_roster->Launch("application/x-vnd.Be-POST");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ConfigWindow::QuitRequested()
|
||||
{
|
||||
SaveSettings();
|
||||
|
||||
Accounts::Delete();
|
||||
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigWindow::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kMsgAccountSelected:
|
||||
{
|
||||
int32 index;
|
||||
if (msg->FindInt32("index", &index) != B_OK || index < 0) {
|
||||
// deselect current item
|
||||
((CenterContainer *)fConfigView)->DeleteChildren();
|
||||
MakeHowToView();
|
||||
break;
|
||||
}
|
||||
AccountItem *item = (AccountItem *)fAccountsListView->ItemAt(index);
|
||||
if (item)
|
||||
item->account->Selected(item->type);
|
||||
break;
|
||||
}
|
||||
case kMsgAddAccount:
|
||||
{
|
||||
Accounts::NewAccount();
|
||||
break;
|
||||
}
|
||||
case kMsgRemoveAccount:
|
||||
{
|
||||
int32 index = fAccountsListView->CurrentSelection();
|
||||
if (index >= 0) {
|
||||
AccountItem *item = (AccountItem *)fAccountsListView->ItemAt(index);
|
||||
if (item) {
|
||||
item->account->Remove(item->type);
|
||||
MakeHowToView();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgIntervalUnitChanged:
|
||||
{
|
||||
int32 index;
|
||||
if (msg->FindInt32("index",&index) == B_OK)
|
||||
fIntervalControl->SetEnabled(index != 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgShowStatusWindowChanged:
|
||||
case kMsgStatusLookChanged:
|
||||
case kMsgStatusWorkspaceChanged:
|
||||
{
|
||||
// the status window stuff is the only "live" setting
|
||||
BMessenger messenger("application/x-vnd.Be-POST");
|
||||
if (messenger.IsValid())
|
||||
messenger.SendMessage(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgRevertSettings:
|
||||
RevertToLastSettings();
|
||||
break;
|
||||
case kMsgApplySettings:
|
||||
fSaveSettings = true;
|
||||
SaveSettings();
|
||||
MakeHowToView();
|
||||
break;
|
||||
case kMsgSaveSettings:
|
||||
fSaveSettings = true;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
case kMsgCancelSettings:
|
||||
fSaveSettings = false;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ConfigWindow::SetToGeneralSettings(BMailSettings *settings)
|
||||
{
|
||||
if (!settings)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t status = settings->InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// retrieval frequency
|
||||
|
||||
time_t interval = time_t(settings->AutoCheckInterval() / 1e6L);
|
||||
char text[25];
|
||||
text[0] = 0;
|
||||
int timeIndex = 0;
|
||||
if (interval >= 60) {
|
||||
timeIndex = 1;
|
||||
sprintf(text, "%ld", interval / (60));
|
||||
}
|
||||
if (interval >= (60*60)) {
|
||||
timeIndex = 2;
|
||||
sprintf(text, "%ld", interval / (60*60));
|
||||
}
|
||||
if (interval >= (60*60*24)) {
|
||||
timeIndex = 3;
|
||||
sprintf(text, "%ld", interval / (60*60*24));
|
||||
}
|
||||
fIntervalControl->SetText(text);
|
||||
|
||||
if (BMenuItem *item = fIntervalUnitField->Menu()->ItemAt(timeIndex))
|
||||
item->SetMarked(true);
|
||||
fIntervalControl->SetEnabled(timeIndex != 0);
|
||||
|
||||
fPPPActiveCheckBox->SetValue(settings->CheckOnlyIfPPPUp());
|
||||
fPPPActiveSendCheckBox->SetValue(settings->SendOnlyIfPPPUp());
|
||||
|
||||
fAutoStartCheckBox->SetValue(settings->DaemonAutoStarts());
|
||||
|
||||
if (BMenuItem *item = fStatusModeField->Menu()->ItemAt(settings->ShowStatusWindow()))
|
||||
item->SetMarked(true);
|
||||
if (BMenuItem *item = fStatusLookField->Menu()->ItemAt(settings->StatusWindowLook()))
|
||||
item->SetMarked(true);
|
||||
if (BMenuItem *item = fStatusWorkspaceField->Menu()->ItemAt(settings->StatusWindowWorkspaces() != B_ALL_WORKSPACES ? 0 : 1))
|
||||
item->SetMarked(true);
|
||||
|
||||
BMessenger messenger("application/x-vnd.Be-POST");
|
||||
if (messenger.IsValid())
|
||||
{
|
||||
BMessage msg(kMsgStatusLookChanged);
|
||||
msg.AddInt32("look", settings->StatusWindowLook());
|
||||
messenger.SendMessage(&msg);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConfigWindow::RevertToLastSettings()
|
||||
{
|
||||
// revert general settings
|
||||
BMailSettings settings;
|
||||
|
||||
// restore status window look
|
||||
settings.SetStatusWindowLook(settings.StatusWindowLook());
|
||||
|
||||
status_t status = SetToGeneralSettings(&settings);
|
||||
if (status != B_OK)
|
||||
{
|
||||
char text[256];
|
||||
sprintf(text,
|
||||
MDR_DIALECT_CHOICE ("\nThe general settings couldn't be reverted.\n\n"
|
||||
"Error retrieving general settings:\n%s\n",
|
||||
"\n一般設定を戻せませんでした。\n\n一般設定収得エラー:\n%s\n"),
|
||||
strerror(status));
|
||||
(new BAlert("Error",text,"Ok",NULL,NULL,B_WIDTH_AS_USUAL,B_WARNING_ALERT))->Go();
|
||||
}
|
||||
|
||||
// revert account data
|
||||
|
||||
if (fAccountsListView->CurrentSelection() != -1)
|
||||
((CenterContainer *)fConfigView)->DeleteChildren();
|
||||
|
||||
Accounts::Delete();
|
||||
Accounts::Create(fAccountsListView,fConfigView);
|
||||
|
||||
if (fConfigView->CountChildren() == 0)
|
||||
MakeHowToView();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef CONFIG_WINDOW_H
|
||||
#define CONFIG_WINDOW_H
|
||||
/* ConfigWindow - main eMail config window
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include <Window.h>
|
||||
#include <List.h>
|
||||
|
||||
class BPopup;
|
||||
class BTextControl;
|
||||
class BCheckBox;
|
||||
class BListView;
|
||||
class BButton;
|
||||
class BMenuField;
|
||||
class BMailSettings;
|
||||
|
||||
class Account;
|
||||
|
||||
|
||||
class ConfigWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
ConfigWindow();
|
||||
~ConfigWindow();
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
void MakeHowToView();
|
||||
|
||||
void LoadSettings();
|
||||
void SaveSettings();
|
||||
|
||||
status_t SetToGeneralSettings(BMailSettings *general);
|
||||
void RevertToLastSettings();
|
||||
|
||||
private:
|
||||
BListView *fAccountsListView;
|
||||
Account *fLastSelectedAccount;
|
||||
BView *fConfigView;
|
||||
BButton *fRemoveButton;
|
||||
|
||||
BTextControl *fIntervalControl;
|
||||
BMenuField *fIntervalUnitField;
|
||||
BCheckBox *fPPPActiveCheckBox;
|
||||
BCheckBox *fPPPActiveSendCheckBox;
|
||||
BMenuField *fStatusModeField,*fStatusLookField,*fStatusWorkspaceField;
|
||||
BCheckBox *fAutoStartCheckBox;
|
||||
|
||||
bool fSaveSettings;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_WINDOW_H */
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
SubDir OBOS_TOP src prefs mail ;
|
||||
|
||||
AddResources E-mail : <$(SOURCE_GRIST)>E-mail.rsrc ;
|
||||
|
||||
UsePrivateHeaders mail ;
|
||||
SubDirHdrs [ FDirName $(OBOS_TOP) headers os add-ons mail_daemon ] ;
|
||||
|
||||
Preference E-mail :
|
||||
Account.cpp
|
||||
CenterContainer.cpp
|
||||
ConfigViews.cpp
|
||||
ConfigWindow.cpp
|
||||
main.cpp ;
|
||||
|
||||
LinkSharedOSLibs E-mail : be mail ;
|
||||
@@ -0,0 +1,40 @@
|
||||
/* main - the application and startup code
|
||||
**
|
||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "ConfigWindow.h"
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
|
||||
class MailConfigApp : public BApplication
|
||||
{
|
||||
public:
|
||||
MailConfigApp();
|
||||
~MailConfigApp();
|
||||
};
|
||||
|
||||
|
||||
MailConfigApp::MailConfigApp() : BApplication("application/x-vnd.Be-mprf")
|
||||
{
|
||||
(new ConfigWindow())->Show();
|
||||
}
|
||||
|
||||
|
||||
MailConfigApp::~MailConfigApp()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
(new MailConfigApp())->Run();
|
||||
|
||||
delete be_app;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user