- Extend MarkMailAsRead to take a flag not only a bool value. Write an additional MAIL:read attribute.

- Remove some hard coded paths.
- Catch failure of FindMessage correctly. Thanks Axel.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40593 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2011-02-21 07:24:29 +00:00
parent ba11c28b6b
commit 9967dfd924
20 changed files with 90 additions and 37 deletions
@@ -17,6 +17,7 @@
#include <Entry.h> #include <Entry.h>
#include <File.h> #include <File.h>
#include <E-mail.h>
#include <MailSettings.h> #include <MailSettings.h>
@@ -145,7 +146,7 @@ public:
virtual status_t SyncMessages() = 0; virtual status_t SyncMessages() = 0;
virtual status_t FetchBody(const entry_ref& ref) = 0; virtual status_t FetchBody(const entry_ref& ref) = 0;
virtual status_t MarkMessageAsRead(const entry_ref& ref, virtual status_t MarkMessageAsRead(const entry_ref& ref,
bool read = true); read_flags flag = B_READ);
virtual status_t DeleteMessage(const entry_ref& ref) = 0; virtual status_t DeleteMessage(const entry_ref& ref) = 0;
virtual status_t AppendMessage(const entry_ref& ref); virtual status_t AppendMessage(const entry_ref& ref);
}; };
@@ -196,7 +197,7 @@ public:
void FetchBody(const entry_ref& ref, void FetchBody(const entry_ref& ref,
BMessage* launch = NULL); BMessage* launch = NULL);
void MarkMessageAsRead(const entry_ref& ref, void MarkMessageAsRead(const entry_ref& ref,
bool read = true); read_flags flag = B_READ);
void DeleteMessage(const entry_ref& ref); void DeleteMessage(const entry_ref& ref);
void AppendMessage(const entry_ref& ref); void AppendMessage(const entry_ref& ref);
private: private:
+10
View File
@@ -28,6 +28,16 @@ struct entry_ref;
#define B_MAIL_ATTR_MIME "MAIL:mime" // string #define B_MAIL_ATTR_MIME "MAIL:mime" // string
#define B_MAIL_ATTR_HEADER "MAIL:header_length" // int32 #define B_MAIL_ATTR_HEADER "MAIL:header_length" // int32
#define B_MAIL_ATTR_CONTENT "MAIL:content_length" // int32 #define B_MAIL_ATTR_CONTENT "MAIL:content_length" // int32
#define B_MAIL_ATTR_READ "MAIL:read" // int32
// read flags
enum read_flags {
B_UNREAD = 0,
B_SEEN = 1,
B_READ = 2
};
// mail flags // mail flags
+4 -1
View File
@@ -7,6 +7,9 @@
*/ */
#include <E-mail.h>
const uint32 kMsgCheckAndSend = 'mbth'; const uint32 kMsgCheckAndSend = 'mbth';
const uint32 kMsgCheckMessage = 'mnow'; const uint32 kMsgCheckMessage = 'mnow';
const uint32 kMsgSendMessages = 'msnd'; const uint32 kMsgSendMessages = 'msnd';
@@ -27,7 +30,7 @@ public:
static int32 CountNewMessages( static int32 CountNewMessages(
bool waitForFetchCompletion = false); bool waitForFetchCompletion = false);
static status_t MarkAsRead(int32 account, const entry_ref& ref, static status_t MarkAsRead(int32 account, const entry_ref& ref,
bool read = true); read_flags flag = B_READ);
static status_t FetchBody(const entry_ref& ref, static status_t FetchBody(const entry_ref& ref,
BMessage* launchMessage = NULL); BMessage* launchMessage = NULL);
static status_t Quit(); static status_t Quit();
+1 -1
View File
@@ -39,7 +39,7 @@ typedef enum
} b_mail_status_window_look; } b_mail_status_window_look;
#define kDefaultSentDirectory "/boot/home/mail/sent" BString default_sent_directory();
class BMailSettings { class BMailSettings {
+9
View File
@@ -8,8 +8,17 @@
#include <stdio.h> #include <stdio.h>
#include <Node.h>
#include <E-mail.h>
class BString; class BString;
status_t write_read_attr(BNode& node, read_flags flag);
// The next couple of functions are our wrapper around convert_to_utf8 and // The next couple of functions are our wrapper around convert_to_utf8 and
// convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by // convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by
// specifying the MDR_UTF8_CONVERSION constant as the conversion operation. // specifying the MDR_UTF8_CONVERSION constant as the conversion operation.
@@ -89,7 +89,7 @@ RuleFilter::HeaderFetched(const entry_ref& ref, BFile* file)
case Z_SET_READ: case Z_SET_READ:
{ {
InboundProtocol& protocol = (InboundProtocol&)fMailProtocol; InboundProtocol& protocol = (InboundProtocol&)fMailProtocol;
protocol.MarkMessageAsRead(ref, true); protocol.MarkMessageAsRead(ref, B_READ);
break; break;
} }
default: default:
@@ -484,7 +484,7 @@ IMAPInboundProtocol::FetchBody(const entry_ref& ref)
status_t status_t
IMAPInboundProtocol::MarkMessageAsRead(const entry_ref& ref, bool read) IMAPInboundProtocol::MarkMessageAsRead(const entry_ref& ref, read_flags flag)
{ {
if (!IsConnected()) if (!IsConnected())
Connect(fServer, fUsername, fPassword, fUseSSL); Connect(fServer, fUsername, fPassword, fUseSSL);
@@ -492,14 +492,16 @@ IMAPInboundProtocol::MarkMessageAsRead(const entry_ref& ref, bool read)
fIMAPMailboxThread->StopWatchingMailbox(); fIMAPMailboxThread->StopWatchingMailbox();
int32 uid = fStorage.RefToUID(ref); int32 uid = fStorage.RefToUID(ref);
int32 flags = fStorage.GetFlags(uid); int32 flags = fStorage.GetFlags(uid);
if (read) if (flag == B_READ)
flags |= kSeen; flags |= kSeen;
else else
flags &= ~kSeen; flags &= ~kSeen;
status_t status = fIMAPMailbox.SetFlags( status_t status = fIMAPMailbox.SetFlags(
fIMAPMailbox.UIDToMessageNumber(uid), flags); fIMAPMailbox.UIDToMessageNumber(uid), flags);
fIMAPMailboxThread->SyncAndStartWatchingMailbox(); fIMAPMailboxThread->SyncAndStartWatchingMailbox();
return status; if (status != B_OK)
return status;
return InboundProtocol::MarkMessageAsRead(ref, flag);
} }
@@ -101,7 +101,7 @@ public:
virtual status_t SyncMessages(); virtual status_t SyncMessages();
virtual status_t FetchBody(const entry_ref& ref); virtual status_t FetchBody(const entry_ref& ref);
virtual status_t MarkMessageAsRead(const entry_ref& ref, virtual status_t MarkMessageAsRead(const entry_ref& ref,
bool read = true); read_flags flag = B_READ);
virtual status_t DeleteMessage(const entry_ref& ref); virtual status_t DeleteMessage(const entry_ref& ref);
virtual status_t AppendMessage(const entry_ref& ref); virtual status_t AppendMessage(const entry_ref& ref);
@@ -98,14 +98,15 @@ IMAPRootInboundProtocol::FetchBody(const entry_ref& ref)
status_t status_t
IMAPRootInboundProtocol::MarkMessageAsRead(const entry_ref& ref, bool read) IMAPRootInboundProtocol::MarkMessageAsRead(const entry_ref& ref,
read_flags flag)
{ {
if (InterestingEntry(ref)) if (InterestingEntry(ref))
return IMAPInboundProtocol::MarkMessageAsRead(ref, read); return IMAPInboundProtocol::MarkMessageAsRead(ref, flag);
InboundProtocolThread* thread = _FindThreadFor(ref); InboundProtocolThread* thread = _FindThreadFor(ref);
if (!thread) if (!thread)
return B_BAD_VALUE; return B_BAD_VALUE;
thread->MarkMessageAsRead(ref, read); thread->MarkMessageAsRead(ref, flag);
return B_OK; return B_OK;
} }
@@ -33,7 +33,7 @@ public:
status_t SyncMessages(); status_t SyncMessages();
status_t FetchBody(const entry_ref& ref); status_t FetchBody(const entry_ref& ref);
status_t MarkMessageAsRead(const entry_ref& ref, status_t MarkMessageAsRead(const entry_ref& ref,
bool read = true); read_flags flag = B_READ);
status_t DeleteMessage(const entry_ref& ref); status_t DeleteMessage(const entry_ref& ref);
status_t AppendMessage(const entry_ref& ref); status_t AppendMessage(const entry_ref& ref);
@@ -468,10 +468,6 @@ IMAPStorage::_WriteFlags(int32 flags, BNode& node)
if (writen != sizeof(int32)) if (writen != sizeof(int32))
return writen; return writen;
const char* statusString = (flags & kSeen) ? "Read" : "New";
node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
strlen(statusString));
return B_OK; return B_OK;
} }
@@ -184,9 +184,6 @@ POP3Protocol::SyncMessages()
entry_ref ref; entry_ref ref;
entry.GetRef(&ref); entry.GetRef(&ref);
// the ref becomes invalid after renaming the file thus we already
// write the status here
MarkMessageAsRead(ref, false);
int32 size = MessageSize(toRetrieve); int32 size = MessageSize(toRetrieve);
if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) { if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) {
@@ -71,7 +71,7 @@ SMTPConfigView::SMTPConfigView(MailAddonSettings& settings,
SetTo(settings); SetTo(settings);
fFileView = new BMailFileConfigView("Destination:", "destination", fFileView = new BMailFileConfigView("Destination:", "destination",
false, kDefaultSentDirectory); false, default_sent_directory());
fFileView->SetTo(&settings.Settings(), NULL); fFileView->SetTo(&settings.Settings(), NULL);
AddChild(fFileView); AddChild(fFileView);
float w, h; float w, h;
+2 -2
View File
@@ -852,12 +852,12 @@ TMailWindow::SetCurrentMessageRead(bool read)
if (read && !mailStatus.ICompare("New")) { if (read && !mailStatus.ICompare("New")) {
node.RemoveAttr(B_MAIL_ATTR_STATUS); node.RemoveAttr(B_MAIL_ATTR_STATUS);
WriteAttrString(&node, B_MAIL_ATTR_STATUS, "Read"); WriteAttrString(&node, B_MAIL_ATTR_STATUS, "Read");
BMailDaemon::MarkAsRead(account, *fRef, true); BMailDaemon::MarkAsRead(account, *fRef, B_READ);
} }
if (!read && !mailStatus.ICompare("Read")) { if (!read && !mailStatus.ICompare("Read")) {
node.RemoveAttr(B_MAIL_ATTR_STATUS); node.RemoveAttr(B_MAIL_ATTR_STATUS);
WriteAttrString(&node, B_MAIL_ATTR_STATUS, "New"); WriteAttrString(&node, B_MAIL_ATTR_STATUS, "New");
BMailDaemon::MarkAsRead(account, *fRef, false); BMailDaemon::MarkAsRead(account, *fRef, B_UNREAD);
} }
} }
+6 -2
View File
@@ -54,14 +54,18 @@ HaikuMailFormatFilter::HaikuMailFormatFilter(MailProtocol& protocol,
fAccountId(settings->AccountID()) fAccountId(settings->AccountID())
{ {
const BMessage* outboundSettings = &settings->OutboundSettings().Settings(); const BMessage* outboundSettings = &settings->OutboundSettings().Settings();
fOutboundDirectory = kDefaultSentDirectory; if (outboundSettings->FindString("destination", &fOutboundDirectory)
outboundSettings->FindString("destination", &fOutboundDirectory); != B_OK) {
fOutboundDirectory = default_sent_directory();
}
} }
void void
HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file) HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
{ {
write_read_attr(*file, B_UNREAD);
file->Seek(0, SEEK_SET); file->Seek(0, SEEK_SET);
BMessage attributes; BMessage attributes;
+2 -2
View File
@@ -71,7 +71,7 @@ BMailDaemon::CountNewMessages(bool wait_for_fetch_completion)
status_t status_t
BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, bool read) BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, read_flags flag)
{ {
BMessenger daemon("application/x-vnd.Be-POST"); BMessenger daemon("application/x-vnd.Be-POST");
if (!daemon.IsValid()) if (!daemon.IsValid())
@@ -80,7 +80,7 @@ BMailDaemon::MarkAsRead(int32 account, const entry_ref& ref, bool read)
BMessage message(kMsgMarkMessageAsRead); BMessage message(kMsgMarkMessageAsRead);
message.AddInt32("account", account); message.AddInt32("account", account);
message.AddRef("ref", &ref); message.AddRef("ref", &ref);
message.AddBool("read", read); message.AddInt32("read", flag);
return daemon.SendMessage(&message); return daemon.SendMessage(&message);
} }
+6 -9
View File
@@ -25,6 +25,7 @@
#include <MDRLanguage.h> #include <MDRLanguage.h>
#include <mail_util.h>
#include <MailAddon.h> #include <MailAddon.h>
#include <MailProtocol.h> #include <MailProtocol.h>
#include <MailSettings.h> #include <MailSettings.h>
@@ -403,14 +404,10 @@ InboundProtocol::AppendMessage(const entry_ref& ref)
status_t status_t
InboundProtocol::MarkMessageAsRead(const entry_ref& ref, bool read) InboundProtocol::MarkMessageAsRead(const entry_ref& ref, read_flags flag)
{ {
BNode node(&ref); BNode node(&ref);
const char* statusString = (read == true) ? "Read" : "New"; return write_read_attr(node, flag);
if (node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
strlen(statusString)) < 0)
return B_ERROR;
return B_OK;
} }
@@ -603,7 +600,7 @@ InboundProtocolThread::MessageReceived(BMessage* message)
{ {
entry_ref ref; entry_ref ref;
message->FindRef("ref", &ref); message->FindRef("ref", &ref);
bool read = message->FindBool("read"); read_flags read = (read_flags)message->FindInt32("read");
fProtocol->MarkMessageAsRead(ref, read); fProtocol->MarkMessageAsRead(ref, read);
break; break;
} }
@@ -648,11 +645,11 @@ InboundProtocolThread::FetchBody(const entry_ref& ref, BMessage* launch)
void void
InboundProtocolThread::MarkMessageAsRead(const entry_ref& ref, bool read) InboundProtocolThread::MarkMessageAsRead(const entry_ref& ref, read_flags flag)
{ {
BMessage message(kMsgMarkMessageAsRead); BMessage message(kMsgMarkMessageAsRead);
message.AddRef("ref", &ref); message.AddRef("ref", &ref);
message.AddBool("read", read); message.AddInt32("read", flag);
PostMessage(&message); PostMessage(&message);
} }
+11
View File
@@ -31,6 +31,17 @@ namespace MailInternal {
} }
BString
default_sent_directory()
{
BPath path;
if (find_directory(B_USER_DIRECTORY, &path) != B_OK)
path.SetTo("/boot/home");
path.Append("mail/sent");
return path.Path();
}
// #pragma mark - BMailSettings // #pragma mark - BMailSettings
+19
View File
@@ -86,6 +86,25 @@ extern const CharsetConversionEntry mail_charsets [] =
}; };
status_t
write_read_attr(BNode& node, read_flags flag)
{
if (node.WriteAttr(B_MAIL_ATTR_READ, B_INT32_TYPE, 0, &flag, sizeof(int32))
< 0)
return B_ERROR;
if (flag == B_SEEN)
return B_OK;
const char* statusString = (flag == B_READ) ? "Read" : "New";
if (node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
strlen(statusString)) < 0)
return B_ERROR;
return B_OK;
}
// The next couple of functions are our wrapper around convert_to_utf8 and // The next couple of functions are our wrapper around convert_to_utf8 and
// convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by // convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by
// specifying the B_MAIL_UTF8_CONVERSION constant as the conversion operation. It // specifying the B_MAIL_UTF8_CONVERSION constant as the conversion operation. It
+4 -1
View File
@@ -58,6 +58,7 @@ makeIndices()
fs_create_index(device, B_MAIL_ATTR_WHEN, B_INT32_TYPE, 0); fs_create_index(device, B_MAIL_ATTR_WHEN, B_INT32_TYPE, 0);
fs_create_index(device, B_MAIL_ATTR_FLAGS, B_INT32_TYPE, 0); fs_create_index(device, B_MAIL_ATTR_FLAGS, B_INT32_TYPE, 0);
fs_create_index(device, B_MAIL_ATTR_ACCOUNT, B_INT32_TYPE, 0); fs_create_index(device, B_MAIL_ATTR_ACCOUNT, B_INT32_TYPE, 0);
fs_create_index(device, B_MAIL_ATTR_READ, B_INT32_TYPE, 0);
} }
} }
@@ -432,7 +433,7 @@ MailDaemonApp::MessageReceived(BMessage* msg)
entry_ref ref; entry_ref ref;
if (msg->FindRef("ref", &ref) != B_OK) if (msg->FindRef("ref", &ref) != B_OK)
break; break;
bool read = msg->FindBool("read"); read_flags read = (read_flags)msg->FindInt32("read");
AccountMap::iterator it = fAccounts.find(account); AccountMap::iterator it = fAccounts.find(account);
if (it == fAccounts.end()) if (it == fAccounts.end())
break; break;
@@ -670,6 +671,8 @@ MailDaemonApp::MakeMimeTypes(bool remakeMIMETypes)
addAttribute(info, B_MAIL_ATTR_THREAD, "Thread"); addAttribute(info, B_MAIL_ATTR_THREAD, "Thread");
addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account", B_STRING_TYPE, addAttribute(info, B_MAIL_ATTR_ACCOUNT, "Account", B_STRING_TYPE,
true, false, 100); true, false, 100);
addAttribute(info, B_MAIL_ATTR_READ, "Read", B_INT32_TYPE,
true, false, 70);
mime.SetAttrInfo(&info); mime.SetAttrInfo(&info);
if (i == 0) { if (i == 0) {