* Ordered methods in the order of their declaration.
* Minor coding style cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42945 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cdffe7e544
commit
d396412d0b
@ -35,7 +35,21 @@
|
||||
#define B_TRANSLATE_CONTEXT "MailDaemon"
|
||||
|
||||
|
||||
void
|
||||
struct send_mails_info {
|
||||
send_mails_info()
|
||||
{
|
||||
totalSize = 0;
|
||||
}
|
||||
|
||||
vector<entry_ref> files;
|
||||
off_t totalSize;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static void
|
||||
makeIndices()
|
||||
{
|
||||
const char* stringIndices[] = {
|
||||
@ -67,7 +81,7 @@ makeIndices()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
addAttribute(BMessage& msg, const char* name, const char* publicName,
|
||||
int32 type = B_STRING_TYPE, bool viewable = true, bool editable = false,
|
||||
int32 width = 200)
|
||||
@ -212,6 +226,406 @@ MailDaemonApp::RefsReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case 'moto':
|
||||
if (fSettingsFile.CheckOnlyIfPPPUp()) {
|
||||
// TODO: check whether internet is up and running!
|
||||
}
|
||||
// supposed to fall through
|
||||
case kMsgCheckAndSend: // check & send messages
|
||||
msg->what = kMsgSendMessages;
|
||||
PostMessage(msg);
|
||||
// supposed to fall trough
|
||||
case kMsgCheckMessage: // check messages
|
||||
GetNewMessages(msg);
|
||||
break;
|
||||
|
||||
case kMsgSendMessages: // send messages
|
||||
SendPendingMessages(msg);
|
||||
break;
|
||||
|
||||
case kMsgSettingsUpdated:
|
||||
fSettingsFile.Reload();
|
||||
_UpdateAutoCheck(fSettingsFile.AutoCheckInterval());
|
||||
fMailStatusWindow->SetShowCriterion(fSettingsFile.ShowStatusWindow());
|
||||
break;
|
||||
|
||||
case kMsgAccountsChanged:
|
||||
_ReloadAccounts(msg);
|
||||
break;
|
||||
|
||||
case kMsgSetStatusWindowMode: // when to show the status window
|
||||
{
|
||||
int32 mode;
|
||||
if (msg->FindInt32("ShowStatusWindow", &mode) == B_OK)
|
||||
fMailStatusWindow->SetShowCriterion(mode);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgMarkMessageAsRead:
|
||||
{
|
||||
int32 account = msg->FindInt32("account");
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("ref", &ref) != B_OK)
|
||||
break;
|
||||
read_flags read = (read_flags)msg->FindInt32("read");
|
||||
AccountMap::iterator it = fAccounts.find(account);
|
||||
if (it == fAccounts.end())
|
||||
break;
|
||||
InboundProtocolThread* inboundThread = it->second.inboundThread;
|
||||
inboundThread->MarkMessageAsRead(ref, read);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgFetchBody:
|
||||
RefsReceived(msg);
|
||||
break;
|
||||
|
||||
case 'lkch': // status window look changed
|
||||
case 'wsch': // workspace changed
|
||||
fMailStatusWindow->PostMessage(msg);
|
||||
break;
|
||||
|
||||
case 'stwg': // Status window gone
|
||||
{
|
||||
BMessage reply('mnuc');
|
||||
reply.AddInt32("num_new_messages", fNewMessages);
|
||||
|
||||
while ((msg = fFetchDoneRespondents.RemoveItemAt(0))) {
|
||||
msg->SendReply(&reply);
|
||||
delete msg;
|
||||
}
|
||||
|
||||
if (fAlertString != B_EMPTY_STRING) {
|
||||
fAlertString.Truncate(fAlertString.Length() - 1);
|
||||
BAlert* alert = new BAlert(B_TRANSLATE("New Messages"),
|
||||
fAlertString.String(), "OK", NULL, NULL, B_WIDTH_AS_USUAL);
|
||||
alert->SetFeel(B_NORMAL_WINDOW_FEEL);
|
||||
alert->Go(NULL);
|
||||
fAlertString = B_EMPTY_STRING;
|
||||
}
|
||||
|
||||
if (fCentralBeep) {
|
||||
system_beep("New E-mail");
|
||||
fCentralBeep = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'mcbp':
|
||||
if (fNewMessages > 0)
|
||||
fCentralBeep = true;
|
||||
break;
|
||||
|
||||
case kMsgCountNewMessages: // Number of new messages
|
||||
{
|
||||
BMessage reply('mnuc'); // Mail New message Count
|
||||
if (msg->FindBool("wait_for_fetch_done")) {
|
||||
fFetchDoneRespondents.AddItem(DetachCurrentMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
reply.AddInt32("num_new_messages", fNewMessages);
|
||||
msg->SendReply(&reply);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'mblk': // Mail Blink
|
||||
if (fNewMessages > 0)
|
||||
fLEDAnimation->Start();
|
||||
break;
|
||||
|
||||
case 'enda': // End Auto Check
|
||||
delete fAutoCheckRunner;
|
||||
fAutoCheckRunner = NULL;
|
||||
break;
|
||||
|
||||
case 'numg':
|
||||
{
|
||||
int32 numMessages = msg->FindInt32("num_messages");
|
||||
BString numString;
|
||||
|
||||
if (numMessages > 1)
|
||||
fAlertString << B_TRANSLATE("%num new messages for %name\n");
|
||||
else
|
||||
fAlertString << B_TRANSLATE("%num new message for %name\n");
|
||||
|
||||
numString << numMessages;
|
||||
fAlertString.ReplaceFirst("%num", numString);
|
||||
fAlertString.ReplaceFirst("%name", msg->FindString("name"));
|
||||
break;
|
||||
}
|
||||
|
||||
case B_QUERY_UPDATE:
|
||||
{
|
||||
int32 what;
|
||||
msg->FindInt32("opcode", &what);
|
||||
switch (what) {
|
||||
case B_ENTRY_CREATED:
|
||||
fNewMessages++;
|
||||
break;
|
||||
case B_ENTRY_REMOVED:
|
||||
fNewMessages--;
|
||||
break;
|
||||
}
|
||||
|
||||
BString string, numString;
|
||||
|
||||
if (fNewMessages > 0) {
|
||||
if (fNewMessages != 1)
|
||||
string << B_TRANSLATE("%num new messages.");
|
||||
else
|
||||
string << B_TRANSLATE("%num new message.");
|
||||
|
||||
numString << fNewMessages;
|
||||
string.ReplaceFirst("%num", numString);
|
||||
}
|
||||
else
|
||||
string << B_TRANSLATE("No new messages.");
|
||||
|
||||
fMailStatusWindow->SetDefaultMessage(string.String());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::Pulse()
|
||||
{
|
||||
bigtime_t idle = idle_time();
|
||||
if (fLEDAnimation->IsRunning() && idle < 100000)
|
||||
fLEDAnimation->Stop();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MailDaemonApp::QuitRequested()
|
||||
{
|
||||
RemoveDeskbarIcon();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::InstallDeskbarIcon()
|
||||
{
|
||||
BDeskbar deskbar;
|
||||
|
||||
if (!deskbar.HasItem("mail_daemon")) {
|
||||
BRoster roster;
|
||||
entry_ref ref;
|
||||
|
||||
status_t status = roster.FindApp("application/x-vnd.Be-POST", &ref);
|
||||
if (status < B_OK) {
|
||||
fprintf(stderr, "Can't find application to tell deskbar: %s\n",
|
||||
strerror(status));
|
||||
return;
|
||||
}
|
||||
|
||||
status = deskbar.AddItem(&ref);
|
||||
if (status < B_OK) {
|
||||
fprintf(stderr, "Can't add deskbar replicant: %s\n", strerror(status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::RemoveDeskbarIcon()
|
||||
{
|
||||
BDeskbar deskbar;
|
||||
if (deskbar.HasItem("mail_daemon"))
|
||||
deskbar.RemoveItem("mail_daemon");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::GetNewMessages(BMessage* msg)
|
||||
{
|
||||
int32 account = -1;
|
||||
if (msg->FindInt32("account", &account) == B_OK && account >= 0) {
|
||||
InboundProtocolThread* protocol = _FindInboundProtocol(account);
|
||||
if (!protocol)
|
||||
return;
|
||||
protocol->SyncMessages();
|
||||
return;
|
||||
}
|
||||
|
||||
// else check all accounts
|
||||
AccountMap::const_iterator it = fAccounts.begin();
|
||||
for (; it != fAccounts.end(); it++) {
|
||||
InboundProtocolThread* protocol = it->second.inboundThread;
|
||||
if (!protocol)
|
||||
continue;
|
||||
protocol->SyncMessages();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::SendPendingMessages(BMessage* msg)
|
||||
{
|
||||
BVolumeRoster roster;
|
||||
BVolume volume;
|
||||
|
||||
map<int32, send_mails_info> messages;
|
||||
|
||||
|
||||
int32 account = -1;
|
||||
if (msg->FindInt32("account", &account) != B_OK)
|
||||
account = -1;
|
||||
|
||||
if (!msg->HasString("message_path")) {
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
BQuery query;
|
||||
query.SetVolume(&volume);
|
||||
query.PushAttr(B_MAIL_ATTR_FLAGS);
|
||||
query.PushInt32(B_MAIL_PENDING);
|
||||
query.PushOp(B_EQ);
|
||||
|
||||
query.PushAttr(B_MAIL_ATTR_FLAGS);
|
||||
query.PushInt32(B_MAIL_PENDING | B_MAIL_SAVE);
|
||||
query.PushOp(B_EQ);
|
||||
|
||||
if (account >= 0) {
|
||||
query.PushAttr(B_MAIL_ATTR_ACCOUNT_ID);
|
||||
query.PushInt32(account);
|
||||
query.PushOp(B_EQ);
|
||||
query.PushOp(B_AND);
|
||||
}
|
||||
|
||||
query.PushOp(B_OR);
|
||||
query.Fetch();
|
||||
BEntry entry;
|
||||
while (query.GetNextEntry(&entry) == B_OK) {
|
||||
if (_IsEntryInTrash(entry))
|
||||
continue;
|
||||
|
||||
BNode node;
|
||||
while (node.SetTo(&entry) == B_BUSY)
|
||||
snooze(1000);
|
||||
if (!_IsPending(node))
|
||||
continue;
|
||||
|
||||
int32 messageAccount;
|
||||
if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0,
|
||||
&messageAccount, sizeof(int32)) < 0)
|
||||
messageAccount = -1;
|
||||
|
||||
off_t size = 0;
|
||||
node.GetSize(&size);
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
|
||||
messages[messageAccount].files.push_back(ref);
|
||||
messages[messageAccount].totalSize += size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const char* path;
|
||||
if (msg->FindString("message_path", &path) != B_OK)
|
||||
return;
|
||||
|
||||
off_t size = 0;
|
||||
if (BNode(path).GetSize(&size) != B_OK)
|
||||
return;
|
||||
BEntry entry(path);
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
|
||||
messages[account].files.push_back(ref);
|
||||
messages[account].totalSize += size;
|
||||
}
|
||||
|
||||
map<int32, send_mails_info>::iterator iter = messages.begin();
|
||||
for (; iter != messages.end(); iter++) {
|
||||
OutboundProtocolThread* protocolThread = _FindOutboundProtocol(
|
||||
iter->first);
|
||||
if (!protocolThread)
|
||||
continue;
|
||||
|
||||
send_mails_info& info = iter->second;
|
||||
if (info.files.size() == 0)
|
||||
continue;
|
||||
|
||||
MailProtocol* protocol = protocolThread->Protocol();
|
||||
|
||||
protocolThread->Lock();
|
||||
protocol->SetTotalItems(info.files.size());
|
||||
protocol->SetTotalItemsSize(info.totalSize);
|
||||
protocolThread->Unlock();
|
||||
|
||||
protocolThread->SendMessages(iter->second.files, info.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::MakeMimeTypes(bool remakeMIMETypes)
|
||||
{
|
||||
// Add MIME database entries for the e-mail file types we handle. Either
|
||||
// do a full rebuild from nothing, or just add on the new attributes that
|
||||
// we support which the regular BeOS mail daemon didn't have.
|
||||
|
||||
const uint8 kNTypes = 2;
|
||||
const char* types[kNTypes] = {"text/x-email", "text/x-partial-email"};
|
||||
|
||||
for (size_t i = 0; i < kNTypes; i++) {
|
||||
BMessage info;
|
||||
BMimeType mime(types[i]);
|
||||
if (mime.InitCheck() != B_OK) {
|
||||
fputs("could not init mime type.\n", stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mime.IsInstalled() || remakeMIMETypes) {
|
||||
// install the full mime type
|
||||
mime.Delete();
|
||||
mime.Install();
|
||||
|
||||
// Set up the list of e-mail related attributes that Tracker will
|
||||
// let you display in columns for e-mail messages.
|
||||
addAttribute(info, B_MAIL_ATTR_NAME, "Name");
|
||||
addAttribute(info, B_MAIL_ATTR_SUBJECT, "Subject");
|
||||
addAttribute(info, B_MAIL_ATTR_TO, "To");
|
||||
addAttribute(info, B_MAIL_ATTR_CC, "Cc");
|
||||
addAttribute(info, B_MAIL_ATTR_FROM, "From");
|
||||
addAttribute(info, B_MAIL_ATTR_REPLY, "Reply To");
|
||||
addAttribute(info, B_MAIL_ATTR_STATUS, "Status");
|
||||
addAttribute(info, B_MAIL_ATTR_PRIORITY, "Priority", B_STRING_TYPE,
|
||||
true, true, 40);
|
||||
addAttribute(info, B_MAIL_ATTR_WHEN, "When", B_TIME_TYPE, true,
|
||||
false, 150);
|
||||
addAttribute(info, B_MAIL_ATTR_THREAD, "Thread");
|
||||
addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account", B_STRING_TYPE,
|
||||
true, false, 100);
|
||||
addAttribute(info, B_MAIL_ATTR_READ, "Read", B_INT32_TYPE,
|
||||
true, false, 70);
|
||||
mime.SetAttrInfo(&info);
|
||||
|
||||
if (i == 0) {
|
||||
mime.SetShortDescription("E-mail");
|
||||
mime.SetLongDescription("Electronic Mail Message");
|
||||
mime.SetPreferredApp("application/x-vnd.Be-MAIL");
|
||||
} else {
|
||||
mime.SetShortDescription("Partial E-mail");
|
||||
mime.SetLongDescription("A Partially Downloaded E-mail");
|
||||
mime.SetPreferredApp("application/x-vnd.Be-MAIL");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::_InitAccounts()
|
||||
{
|
||||
@ -400,423 +814,9 @@ MailDaemonApp::_UpdateAutoCheck(bigtime_t interval)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case 'moto':
|
||||
if (fSettingsFile.CheckOnlyIfPPPUp()) {
|
||||
// TODO: check whether internet is up and running!
|
||||
}
|
||||
// supposed to fall through
|
||||
case kMsgCheckAndSend: // check & send messages
|
||||
msg->what = kMsgSendMessages;
|
||||
PostMessage(msg);
|
||||
// supposed to fall trough
|
||||
case kMsgCheckMessage: // check messages
|
||||
GetNewMessages(msg);
|
||||
break;
|
||||
|
||||
case kMsgSendMessages: // send messages
|
||||
SendPendingMessages(msg);
|
||||
break;
|
||||
|
||||
case kMsgSettingsUpdated:
|
||||
fSettingsFile.Reload();
|
||||
_UpdateAutoCheck(fSettingsFile.AutoCheckInterval());
|
||||
fMailStatusWindow->SetShowCriterion(fSettingsFile.ShowStatusWindow());
|
||||
break;
|
||||
|
||||
case kMsgAccountsChanged:
|
||||
_ReloadAccounts(msg);
|
||||
break;
|
||||
|
||||
case kMsgSetStatusWindowMode: // when to show the status window
|
||||
{
|
||||
int32 mode;
|
||||
if (msg->FindInt32("ShowStatusWindow", &mode) == B_OK)
|
||||
fMailStatusWindow->SetShowCriterion(mode);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgMarkMessageAsRead:
|
||||
{
|
||||
int32 account = msg->FindInt32("account");
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("ref", &ref) != B_OK)
|
||||
break;
|
||||
read_flags read = (read_flags)msg->FindInt32("read");
|
||||
AccountMap::iterator it = fAccounts.find(account);
|
||||
if (it == fAccounts.end())
|
||||
break;
|
||||
InboundProtocolThread* inboundThread = it->second.inboundThread;
|
||||
inboundThread->MarkMessageAsRead(ref, read);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgFetchBody:
|
||||
RefsReceived(msg);
|
||||
break;
|
||||
|
||||
case 'lkch': // status window look changed
|
||||
case 'wsch': // workspace changed
|
||||
fMailStatusWindow->PostMessage(msg);
|
||||
break;
|
||||
|
||||
case 'stwg': // Status window gone
|
||||
{
|
||||
BMessage reply('mnuc');
|
||||
reply.AddInt32("num_new_messages", fNewMessages);
|
||||
|
||||
while ((msg = fFetchDoneRespondents.RemoveItemAt(0))) {
|
||||
msg->SendReply(&reply);
|
||||
delete msg;
|
||||
}
|
||||
|
||||
if (fAlertString != B_EMPTY_STRING) {
|
||||
fAlertString.Truncate(fAlertString.Length() - 1);
|
||||
BAlert* alert = new BAlert(B_TRANSLATE("New Messages"),
|
||||
fAlertString.String(), "OK", NULL, NULL, B_WIDTH_AS_USUAL);
|
||||
alert->SetFeel(B_NORMAL_WINDOW_FEEL);
|
||||
alert->Go(NULL);
|
||||
fAlertString = B_EMPTY_STRING;
|
||||
}
|
||||
|
||||
if (fCentralBeep) {
|
||||
system_beep("New E-mail");
|
||||
fCentralBeep = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'mcbp':
|
||||
if (fNewMessages > 0)
|
||||
fCentralBeep = true;
|
||||
break;
|
||||
|
||||
case kMsgCountNewMessages: // Number of new messages
|
||||
{
|
||||
BMessage reply('mnuc'); // Mail New message Count
|
||||
if (msg->FindBool("wait_for_fetch_done")) {
|
||||
fFetchDoneRespondents.AddItem(DetachCurrentMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
reply.AddInt32("num_new_messages", fNewMessages);
|
||||
msg->SendReply(&reply);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'mblk': // Mail Blink
|
||||
if (fNewMessages > 0)
|
||||
fLEDAnimation->Start();
|
||||
break;
|
||||
|
||||
case 'enda': // End Auto Check
|
||||
delete fAutoCheckRunner;
|
||||
fAutoCheckRunner = NULL;
|
||||
break;
|
||||
|
||||
case 'numg':
|
||||
{
|
||||
int32 numMessages = msg->FindInt32("num_messages");
|
||||
BString numString;
|
||||
|
||||
if (numMessages > 1)
|
||||
fAlertString << B_TRANSLATE("%num new messages for %name\n");
|
||||
else
|
||||
fAlertString << B_TRANSLATE("%num new message for %name\n");
|
||||
|
||||
numString << numMessages;
|
||||
fAlertString.ReplaceFirst("%num", numString);
|
||||
fAlertString.ReplaceFirst("%name", msg->FindString("name"));
|
||||
break;
|
||||
}
|
||||
|
||||
case B_QUERY_UPDATE:
|
||||
{
|
||||
int32 what;
|
||||
msg->FindInt32("opcode", &what);
|
||||
switch (what) {
|
||||
case B_ENTRY_CREATED:
|
||||
fNewMessages++;
|
||||
break;
|
||||
case B_ENTRY_REMOVED:
|
||||
fNewMessages--;
|
||||
break;
|
||||
}
|
||||
|
||||
BString string, numString;
|
||||
|
||||
if (fNewMessages > 0) {
|
||||
if (fNewMessages != 1)
|
||||
string << B_TRANSLATE("%num new messages.");
|
||||
else
|
||||
string << B_TRANSLATE("%num new message.");
|
||||
|
||||
numString << fNewMessages;
|
||||
string.ReplaceFirst("%num", numString);
|
||||
}
|
||||
else
|
||||
string << B_TRANSLATE("No new messages.");
|
||||
|
||||
fMailStatusWindow->SetDefaultMessage(string.String());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::InstallDeskbarIcon()
|
||||
{
|
||||
BDeskbar deskbar;
|
||||
|
||||
if (!deskbar.HasItem("mail_daemon")) {
|
||||
BRoster roster;
|
||||
entry_ref ref;
|
||||
|
||||
status_t status = roster.FindApp("application/x-vnd.Be-POST", &ref);
|
||||
if (status < B_OK) {
|
||||
fprintf(stderr, "Can't find application to tell deskbar: %s\n",
|
||||
strerror(status));
|
||||
return;
|
||||
}
|
||||
|
||||
status = deskbar.AddItem(&ref);
|
||||
if (status < B_OK) {
|
||||
fprintf(stderr, "Can't add deskbar replicant: %s\n", strerror(status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::RemoveDeskbarIcon()
|
||||
{
|
||||
BDeskbar deskbar;
|
||||
if (deskbar.HasItem("mail_daemon"))
|
||||
deskbar.RemoveItem("mail_daemon");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MailDaemonApp::QuitRequested()
|
||||
{
|
||||
RemoveDeskbarIcon();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::GetNewMessages(BMessage* msg)
|
||||
{
|
||||
int32 account = -1;
|
||||
if (msg->FindInt32("account", &account) == B_OK && account >= 0) {
|
||||
InboundProtocolThread* protocol = _FindInboundProtocol(account);
|
||||
if (!protocol)
|
||||
return;
|
||||
protocol->SyncMessages();
|
||||
return;
|
||||
}
|
||||
|
||||
// else check all accounts
|
||||
AccountMap::const_iterator it = fAccounts.begin();
|
||||
for (; it != fAccounts.end(); it++) {
|
||||
InboundProtocolThread* protocol = it->second.inboundThread;
|
||||
if (!protocol)
|
||||
continue;
|
||||
protocol->SyncMessages();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::MakeMimeTypes(bool remakeMIMETypes)
|
||||
{
|
||||
// Add MIME database entries for the e-mail file types we handle. Either
|
||||
// do a full rebuild from nothing, or just add on the new attributes that
|
||||
// we support which the regular BeOS mail daemon didn't have.
|
||||
|
||||
const uint8 kNTypes = 2;
|
||||
const char* types[kNTypes] = {"text/x-email", "text/x-partial-email"};
|
||||
|
||||
for (size_t i = 0; i < kNTypes; i++) {
|
||||
BMessage info;
|
||||
BMimeType mime(types[i]);
|
||||
if (mime.InitCheck() != B_OK) {
|
||||
fputs("could not init mime type.\n", stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mime.IsInstalled() || remakeMIMETypes) {
|
||||
// install the full mime type
|
||||
mime.Delete();
|
||||
mime.Install();
|
||||
|
||||
// Set up the list of e-mail related attributes that Tracker will
|
||||
// let you display in columns for e-mail messages.
|
||||
addAttribute(info, B_MAIL_ATTR_NAME, "Name");
|
||||
addAttribute(info, B_MAIL_ATTR_SUBJECT, "Subject");
|
||||
addAttribute(info, B_MAIL_ATTR_TO, "To");
|
||||
addAttribute(info, B_MAIL_ATTR_CC, "Cc");
|
||||
addAttribute(info, B_MAIL_ATTR_FROM, "From");
|
||||
addAttribute(info, B_MAIL_ATTR_REPLY, "Reply To");
|
||||
addAttribute(info, B_MAIL_ATTR_STATUS, "Status");
|
||||
addAttribute(info, B_MAIL_ATTR_PRIORITY, "Priority", B_STRING_TYPE,
|
||||
true, true, 40);
|
||||
addAttribute(info, B_MAIL_ATTR_WHEN, "When", B_TIME_TYPE, true,
|
||||
false, 150);
|
||||
addAttribute(info, B_MAIL_ATTR_THREAD, "Thread");
|
||||
addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account", B_STRING_TYPE,
|
||||
true, false, 100);
|
||||
addAttribute(info, B_MAIL_ATTR_READ, "Read", B_INT32_TYPE,
|
||||
true, false, 70);
|
||||
mime.SetAttrInfo(&info);
|
||||
|
||||
if (i == 0) {
|
||||
mime.SetShortDescription("E-mail");
|
||||
mime.SetLongDescription("Electronic Mail Message");
|
||||
mime.SetPreferredApp("application/x-vnd.Be-MAIL");
|
||||
} else {
|
||||
mime.SetShortDescription("Partial E-mail");
|
||||
mime.SetLongDescription("A Partially Downloaded E-mail");
|
||||
mime.SetPreferredApp("application/x-vnd.Be-MAIL");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct send_mails_info {
|
||||
send_mails_info()
|
||||
{
|
||||
totalSize = 0;
|
||||
}
|
||||
vector<entry_ref> files;
|
||||
off_t totalSize;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::SendPendingMessages(BMessage* msg)
|
||||
{
|
||||
BVolumeRoster roster;
|
||||
BVolume volume;
|
||||
|
||||
map<int32, send_mails_info> messages;
|
||||
|
||||
|
||||
int32 account = -1;
|
||||
if (msg->FindInt32("account", &account) != B_OK)
|
||||
account = -1;
|
||||
|
||||
if (!msg->HasString("message_path")) {
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
BQuery query;
|
||||
query.SetVolume(&volume);
|
||||
query.PushAttr(B_MAIL_ATTR_FLAGS);
|
||||
query.PushInt32(B_MAIL_PENDING);
|
||||
query.PushOp(B_EQ);
|
||||
|
||||
query.PushAttr(B_MAIL_ATTR_FLAGS);
|
||||
query.PushInt32(B_MAIL_PENDING | B_MAIL_SAVE);
|
||||
query.PushOp(B_EQ);
|
||||
|
||||
if (account >= 0) {
|
||||
query.PushAttr(B_MAIL_ATTR_ACCOUNT_ID);
|
||||
query.PushInt32(account);
|
||||
query.PushOp(B_EQ);
|
||||
query.PushOp(B_AND);
|
||||
}
|
||||
|
||||
query.PushOp(B_OR);
|
||||
query.Fetch();
|
||||
BEntry entry;
|
||||
while (query.GetNextEntry(&entry) == B_OK) {
|
||||
if (_IsEntryInTrash(entry))
|
||||
continue;
|
||||
|
||||
BNode node;
|
||||
while (node.SetTo(&entry) == B_BUSY)
|
||||
snooze(1000);
|
||||
if (!_IsPending(node))
|
||||
continue;
|
||||
|
||||
int32 messageAccount;
|
||||
if (node.ReadAttr(B_MAIL_ATTR_ACCOUNT_ID, B_INT32_TYPE, 0,
|
||||
&messageAccount, sizeof(int32)) < 0)
|
||||
messageAccount = -1;
|
||||
|
||||
off_t size = 0;
|
||||
node.GetSize(&size);
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
|
||||
messages[messageAccount].files.push_back(ref);
|
||||
messages[messageAccount].totalSize += size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const char* path;
|
||||
if (msg->FindString("message_path", &path) != B_OK)
|
||||
return;
|
||||
|
||||
off_t size = 0;
|
||||
if (BNode(path).GetSize(&size) != B_OK)
|
||||
return;
|
||||
BEntry entry(path);
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
|
||||
messages[account].files.push_back(ref);
|
||||
messages[account].totalSize += size;
|
||||
}
|
||||
|
||||
map<int32, send_mails_info>::iterator iter = messages.begin();
|
||||
for (; iter != messages.end(); iter++) {
|
||||
OutboundProtocolThread* protocolThread = _FindOutboundProtocol(
|
||||
iter->first);
|
||||
if (!protocolThread)
|
||||
continue;
|
||||
|
||||
send_mails_info& info = iter->second;
|
||||
if (info.files.size() == 0)
|
||||
continue;
|
||||
|
||||
MailProtocol* protocol = protocolThread->Protocol();
|
||||
|
||||
protocolThread->Lock();
|
||||
protocol->SetTotalItems(info.files.size());
|
||||
protocol->SetTotalItemsSize(info.totalSize);
|
||||
protocolThread->Unlock();
|
||||
|
||||
protocolThread->SendMessages(iter->second.files, info.totalSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MailDaemonApp::Pulse()
|
||||
{
|
||||
bigtime_t idle = idle_time();
|
||||
if (fLEDAnimation->IsRunning() && idle < 100000)
|
||||
fLEDAnimation->Stop();
|
||||
}
|
||||
|
||||
|
||||
/*! Work-around for a broken index that contains out-of-date information.
|
||||
*/
|
||||
|
||||
/* static */
|
||||
bool
|
||||
/*static*/ bool
|
||||
MailDaemonApp::_IsPending(BNode& node)
|
||||
{
|
||||
int32 flags;
|
||||
@ -828,8 +828,7 @@ MailDaemonApp::_IsPending(BNode& node)
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
bool
|
||||
/*static*/ bool
|
||||
MailDaemonApp::_IsEntryInTrash(BEntry& entry)
|
||||
{
|
||||
entry_ref ref;
|
||||
|
@ -50,18 +50,18 @@ public:
|
||||
MailDaemonApp();
|
||||
virtual ~MailDaemonApp();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void ReadyToRun();
|
||||
virtual void RefsReceived(BMessage* message);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void Pulse();
|
||||
virtual bool QuitRequested();
|
||||
virtual void ReadyToRun();
|
||||
|
||||
void InstallDeskbarIcon();
|
||||
void RemoveDeskbarIcon();
|
||||
|
||||
void SendPendingMessages(BMessage* message);
|
||||
void GetNewMessages(BMessage* message);
|
||||
void SendPendingMessages(BMessage* message);
|
||||
|
||||
void MakeMimeTypes(bool remakeMIMETypes = false);
|
||||
|
||||
@ -82,6 +82,7 @@ private:
|
||||
OutboundProtocolThread* _FindOutboundProtocol(int32 account);
|
||||
|
||||
void _UpdateAutoCheck(bigtime_t interval);
|
||||
|
||||
static bool _IsPending(BNode& node);
|
||||
static bool _IsEntryInTrash(BEntry& entry);
|
||||
|
||||
@ -97,8 +98,8 @@ private:
|
||||
// account.
|
||||
// Set to TRUE by the 'mcbp' message that the mail Notification
|
||||
// filter sends us, cleared when the beep is done.
|
||||
BObjectList<BMessage> fFetchDoneRespondents;
|
||||
BObjectList<BQuery> fQueries;
|
||||
BObjectList<BMessage> fFetchDoneRespondents;
|
||||
BObjectList<BQuery> fQueries;
|
||||
|
||||
LEDAnimation* fLEDAnimation;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user