IMAP: Extra local messages are now deleted.
* When a message on the server is deleted, it will now be deleted locally, too.
This commit is contained in:
@@ -370,8 +370,7 @@ public:
|
||||
fTotalBytes += entries[i].size;
|
||||
fUIDsToFetch.push_back(entries[i].uid);
|
||||
} else {
|
||||
fFolder->UpdateMessageFlags(entries[i].uid,
|
||||
entries[i].flags);
|
||||
fFolder->SyncMessageFlags(entries[i].uid, entries[i].flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,6 +378,8 @@ public:
|
||||
fLastIndex = from - 1;
|
||||
|
||||
if (from == 1) {
|
||||
fFolder->MessageEntriesFetched();
|
||||
|
||||
if (fUIDsToFetch.size() > 0) {
|
||||
// Add pending command to fetch the message headers
|
||||
WorkerCommand* command = new FetchHeadersCommand(*fFolder,
|
||||
|
||||
@@ -178,6 +178,7 @@ IMAPFolder::SetUIDValidity(uint32 uidValidity)
|
||||
if (fUIDValidity == uidValidity)
|
||||
return;
|
||||
|
||||
// TODO: delete all mails that have the same UID validity value we had
|
||||
fUIDValidity = uidValidity;
|
||||
|
||||
BNode node(&fRef);
|
||||
@@ -221,8 +222,11 @@ IMAPFolder::MessageFlags(uint32 uid)
|
||||
}
|
||||
|
||||
|
||||
/*! Synchronizes the message flags/state from the server with the local
|
||||
one.
|
||||
*/
|
||||
void
|
||||
IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
|
||||
IMAPFolder::SyncMessageFlags(uint32 uid, uint32 mailboxFlags)
|
||||
{
|
||||
if (uid > LastUID())
|
||||
return;
|
||||
@@ -233,7 +237,8 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
|
||||
while (true) {
|
||||
status_t status = GetMessageEntryRef(uid, ref);
|
||||
if (status == B_ENTRY_NOT_FOUND) {
|
||||
// The message does not exist anymore locally, delete it on the server
|
||||
// The message does not exist anymore locally, delete it on the
|
||||
// server
|
||||
// TODO: copy it to the trash directory first!
|
||||
fProtocol.UpdateMessageFlags(*this, uid, IMAP::kDeleted);
|
||||
return;
|
||||
@@ -247,6 +252,7 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
|
||||
|
||||
break;
|
||||
}
|
||||
fSynchronizedUIDsSet.insert(uid);
|
||||
|
||||
uint32 previousFlags = MessageFlags(uid);
|
||||
uint32 currentFlags = previousFlags;
|
||||
@@ -279,6 +285,21 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IMAPFolder::MessageEntriesFetched()
|
||||
{
|
||||
// Delete all local messages that weren't synchronized with the server
|
||||
UIDToRefMap::const_iterator iterator = fRefMap.begin();
|
||||
for (; iterator != fRefMap.end(); iterator++) {
|
||||
uint32 uid = iterator->first;
|
||||
if (fSynchronizedUIDsSet.find(uid) == fSynchronizedUIDsSet.end())
|
||||
_DeleteLocalMessage(uid);
|
||||
}
|
||||
|
||||
fSynchronizedUIDsSet.clear();
|
||||
}
|
||||
|
||||
|
||||
/*! Stores the given \a stream into a temporary file using the provided
|
||||
BFile object. A new file will be created, and the \a ref object will
|
||||
point to it. The file will remain open when this method exits without
|
||||
@@ -416,6 +437,9 @@ IMAPFolder::StoringBodyFailed(const entry_ref& ref, uint32 uid, status_t error)
|
||||
void
|
||||
IMAPFolder::DeleteMessage(uint32 uid)
|
||||
{
|
||||
// TODO: move message to trash (server side)
|
||||
|
||||
_DeleteLocalMessage(uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +495,6 @@ IMAPFolder::_InitializeFolderState()
|
||||
// _WriteUniqueID(node, uid);
|
||||
// }
|
||||
//
|
||||
fRefMap.insert(std::make_pair(uid, ref));
|
||||
}
|
||||
|
||||
fInitializing = false;
|
||||
@@ -519,6 +542,22 @@ IMAPFolder::_GetMessageEntryRef(uint32 uid, entry_ref& ref) const
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
IMAPFolder::_DeleteLocalMessage(uint32 uid)
|
||||
{
|
||||
entry_ref ref;
|
||||
status_t status = GetMessageEntryRef(uid, ref);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fRefMap.erase(uid);
|
||||
fFlagsMap.erase(uid);
|
||||
|
||||
BEntry entry(&ref);
|
||||
return entry.Remove();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IMAPFolder::_IMAPToMailFlags(uint32 flags, BMessage& attributes)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <Entry.h>
|
||||
@@ -69,8 +71,9 @@ public:
|
||||
uint32& uid) const;
|
||||
uint32 MessageFlags(uint32 uid);
|
||||
|
||||
void UpdateMessageFlags(uint32 uid,
|
||||
void SyncMessageFlags(uint32 uid,
|
||||
uint32 mailboxFlags);
|
||||
void MessageEntriesFetched();
|
||||
|
||||
status_t StoreMessage(uint32 fetchFlags, BDataIO& stream,
|
||||
size_t& length, entry_ref& ref,
|
||||
@@ -101,6 +104,7 @@ private:
|
||||
uint32 uid, status_t status);
|
||||
status_t _GetMessageEntryRef(uint32 uid,
|
||||
entry_ref& ref) const;
|
||||
status_t _DeleteLocalMessage(uint32 uid);
|
||||
|
||||
void _IMAPToMailFlags(uint32 flags,
|
||||
BMessage& attributes);
|
||||
@@ -130,10 +134,12 @@ private:
|
||||
typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap;
|
||||
typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap;
|
||||
typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap;
|
||||
typedef __gnu_cxx::hash_set<uint32> UIDSet;
|
||||
#else
|
||||
typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
|
||||
typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
|
||||
typedef std::hash_map<uint32, MessengerList> MessengerMap;
|
||||
typedef std::hash_set<uint32> UIDSet;
|
||||
#endif
|
||||
|
||||
IMAPProtocol& fProtocol;
|
||||
@@ -147,6 +153,7 @@ private:
|
||||
bool fInitializing;
|
||||
UIDToRefMap fRefMap;
|
||||
UIDToFlagsMap fFlagsMap;
|
||||
UIDSet fSynchronizedUIDsSet;
|
||||
MessengerMap fPendingBodies;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user