mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-05 00:02:37 +00:00
add backend support for labels r=ssu, sr=sspitzer 106067
This commit is contained in:
parent
5fb19fec4a
commit
5955ba4686
@ -90,7 +90,8 @@ interface nsMsgViewSortType
|
||||
const nsMsgViewSortTypeValue byFlagged = 0x1a;
|
||||
const nsMsgViewSortTypeValue byUnread = 0x1b;
|
||||
const nsMsgViewSortTypeValue byRecipient = 0x1c;
|
||||
const nsMsgViewSortTypeValue byLocation = 0x1d;
|
||||
const nsMsgViewSortTypeValue byLocation = 0x1d;
|
||||
const nsMsgViewSortTypeValue byLabel = 0x1e;
|
||||
};
|
||||
|
||||
[scriptable, uuid(255d1c1e-fde7-11d4-a5be-0060b0fc04b7)]
|
||||
@ -184,6 +185,13 @@ interface nsMsgViewCommandType
|
||||
const nsMsgViewCommandTypeValue selectThread = 18;
|
||||
const nsMsgViewCommandTypeValue selectFlagged = 19;
|
||||
const nsMsgViewCommandTypeValue cmdRequiringMsgBody = 20;
|
||||
const nsMsgViewCommandTypeValue label1 = 21;
|
||||
const nsMsgViewCommandTypeValue label2 = 22;
|
||||
const nsMsgViewCommandTypeValue label3 = 23;
|
||||
const nsMsgViewCommandTypeValue label4 = 24;
|
||||
const nsMsgViewCommandTypeValue label5 = 25;
|
||||
const nsMsgViewCommandTypeValue lastLabel = 25;
|
||||
|
||||
};
|
||||
|
||||
[scriptable, uuid(65903eb2-1dd2-11b2-ac45-c5b69c1618d7)]
|
||||
|
@ -119,6 +119,7 @@ interface nsIMsgHdr : nsISupports
|
||||
[noscript] void getRecipientsCollationKey(out octetPtr key, out unsigned long len);
|
||||
|
||||
attribute string Charset;
|
||||
attribute nsMsgLabelValue label;
|
||||
readonly attribute nsIMsgFolder folder;
|
||||
};
|
||||
|
||||
|
@ -96,14 +96,14 @@ typedef PRInt32 MsgFlags;
|
||||
don't want to later deliver it! */
|
||||
#define MSG_FLAG_FORWARDED 0x1000 /* this message has been forwarded */
|
||||
#define MSG_FLAG_PRIORITIES 0xE000 /* These are used to remember the message
|
||||
priority in the mozilla status flags
|
||||
so we can regenerate a priority after a
|
||||
rule (or user) has changed it. They are
|
||||
not returned in MSG_MessageLine.flags,
|
||||
just in mozilla-status, so if you need
|
||||
more non-persistent flags, you could
|
||||
share these bits. But it would be wrong.
|
||||
. */
|
||||
priority in the mozilla status flags
|
||||
so we can regenerate a priority after a
|
||||
rule (or user) has changed it. They are
|
||||
not returned in MSG_MessageLine.flags,
|
||||
just in mozilla-status, so if you need
|
||||
more non-persistent flags, you could
|
||||
share these bits. But it would be wrong.
|
||||
. */
|
||||
|
||||
#define MSG_FLAG_NEW 0x10000 /* This msg is new since the last time
|
||||
the folder was closed.
|
||||
@ -123,6 +123,15 @@ typedef PRInt32 MsgFlags;
|
||||
#define MSG_FLAG_TEMPLATE 0x1000000 /* this message is a template */
|
||||
#define MSG_FLAG_ATTACHMENT 0x10000000 /* this message has files attached to it */
|
||||
|
||||
#define MSG_FLAG_LABELS 0xE000000 /* These are used to remember the message
|
||||
labels in the mozilla status2 flags
|
||||
so we can regenerate a priority after a
|
||||
rule (or user) has changed it. They are
|
||||
not returned in nsMsgHdr.flags,
|
||||
just in mozilla-status2, so if you need
|
||||
more non-persistent flags, you could
|
||||
share these bits. But it would be wrong.
|
||||
. */
|
||||
// we're trying to reserve the high byte of the flags for view flags,
|
||||
// so, don't add flags to the high byte if possible.
|
||||
|
||||
|
@ -409,6 +409,24 @@ nsresult nsMsgDBView::FetchPriority(nsIMsgHdr *aHdr, PRUnichar ** aPriorityStrin
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::FetchLabel(nsIMsgHdr *aHdr, PRUnichar ** aLabelString)
|
||||
{
|
||||
nsMsgLabelValue label = 0;
|
||||
PRUnichar labelString[2];
|
||||
labelString[1] = '\0';
|
||||
aHdr->GetLabel(&label);
|
||||
|
||||
|
||||
if (label)
|
||||
{
|
||||
*labelString = '0' + label;
|
||||
*aLabelString = nsCRT::strdup(labelString);
|
||||
}
|
||||
else
|
||||
*aLabelString = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::SaveSelection(nsMsgKeyArray *aMsgKeyArray)
|
||||
{
|
||||
if (!mOutlinerSelection)
|
||||
@ -974,6 +992,9 @@ NS_IMETHODIMP nsMsgDBView::GetCellText(PRInt32 aRow, const PRUnichar * aColID, P
|
||||
case 'p': // priority
|
||||
rv = FetchPriority(msgHdr, aValue);
|
||||
break;
|
||||
case 'l': // label
|
||||
rv = FetchLabel(msgHdr, aValue);
|
||||
break;
|
||||
case 't':
|
||||
// total msgs in thread column
|
||||
if (aColID[1] == 'o' && (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
|
||||
@ -1065,6 +1086,28 @@ NS_IMETHODIMP nsMsgDBView::CycleCell(PRInt32 row, const PRUnichar *colID)
|
||||
else
|
||||
ApplyCommandToIndices(nsMsgViewCommandType::flagMessages, (nsMsgViewIndex *) &row, 1);
|
||||
break;
|
||||
case 'l': // label column
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
|
||||
nsresult rv = GetMsgHdrForViewIndex(row, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(rv) && msgHdr)
|
||||
{
|
||||
nsMsgLabelValue label;
|
||||
|
||||
if (NS_SUCCEEDED(msgHdr->GetLabel(&label)))
|
||||
{
|
||||
// we have five labels, and the special 0 label, meaning no label.
|
||||
// lastLabel - label1 is 4, so we need to compare label to 4 + 1 to see if we're at the last label
|
||||
if (label != (nsMsgViewCommandType::lastLabel - nsMsgViewCommandType::label1 + 1))
|
||||
msgHdr->SetLabel(label + 1);
|
||||
else
|
||||
msgHdr->SetLabel(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -1339,14 +1382,20 @@ NS_IMETHODIMP nsMsgDBView::DoCommand(nsMsgViewCommandTypeValue command)
|
||||
case nsMsgViewCommandType::deleteMsg:
|
||||
case nsMsgViewCommandType::deleteNoTrash:
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
// since the FE could have constructed the list of indices in
|
||||
// any order (e.g. order of discontiguous selection), we have to
|
||||
// sort the indices in order to find out which nsMsgViewIndex will
|
||||
// be deleted first.
|
||||
if (numIndices > 1)
|
||||
NS_QuickSort (indices, numIndices, sizeof(nsMsgViewIndex), CompareViewIndices, nsnull);
|
||||
case nsMsgViewCommandType::label1:
|
||||
case nsMsgViewCommandType::label2:
|
||||
case nsMsgViewCommandType::label3:
|
||||
case nsMsgViewCommandType::label4:
|
||||
case nsMsgViewCommandType::label5:
|
||||
|
||||
// since the FE could have constructed the list of indices in
|
||||
// any order (e.g. order of discontiguous selection), we have to
|
||||
// sort the indices in order to find out which nsMsgViewIndex will
|
||||
// be deleted first.
|
||||
if (numIndices > 1)
|
||||
NS_QuickSort (indices, numIndices, sizeof(nsMsgViewIndex), CompareViewIndices, nsnull);
|
||||
NoteStartChange(nsMsgViewNotificationCode::none, 0, 0);
|
||||
rv = ApplyCommandToIndices(command, indices, numIndices);
|
||||
rv = ApplyCommandToIndices(command, indices, numIndices);
|
||||
NoteEndChange(nsMsgViewNotificationCode::none, 0, 0);
|
||||
break;
|
||||
case nsMsgViewCommandType::selectAll:
|
||||
@ -1412,6 +1461,11 @@ NS_IMETHODIMP nsMsgDBView::GetCommandStatus(nsMsgViewCommandTypeValue command, P
|
||||
case nsMsgViewCommandType::deleteNoTrash:
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
case nsMsgViewCommandType::downloadSelectedForOffline:
|
||||
case nsMsgViewCommandType::label1:
|
||||
case nsMsgViewCommandType::label2:
|
||||
case nsMsgViewCommandType::label3:
|
||||
case nsMsgViewCommandType::label4:
|
||||
case nsMsgViewCommandType::label5:
|
||||
*selectable_p = (numindices > 0);
|
||||
break;
|
||||
case nsMsgViewCommandType::cmdRequiringMsgBody:
|
||||
@ -1483,93 +1537,100 @@ nsresult
|
||||
nsMsgDBView::ApplyCommandToIndices(nsMsgViewCommandTypeValue command, nsMsgViewIndex* indices,
|
||||
PRInt32 numIndices)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsMsgKeyArray imapUids;
|
||||
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);
|
||||
PRBool thisIsImapFolder = (imapFolder != nsnull);
|
||||
if (command == nsMsgViewCommandType::deleteMsg)
|
||||
rv = DeleteMessages(mMsgWindow, indices, numIndices, PR_FALSE);
|
||||
else if (command == nsMsgViewCommandType::deleteNoTrash)
|
||||
rv = DeleteMessages(mMsgWindow, indices, numIndices, PR_TRUE);
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < numIndices; i++)
|
||||
{
|
||||
if (thisIsImapFolder && command != nsMsgViewCommandType::markThreadRead)
|
||||
imapUids.Add(GetAt(indices[i]));
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case nsMsgViewCommandType::markMessagesRead:
|
||||
rv = SetReadByIndex(indices[i], PR_TRUE);
|
||||
break;
|
||||
case nsMsgViewCommandType::markMessagesUnread:
|
||||
rv = SetReadByIndex(indices[i], PR_FALSE);
|
||||
break;
|
||||
case nsMsgViewCommandType::toggleMessageRead:
|
||||
rv = ToggleReadByIndex(indices[i]);
|
||||
break;
|
||||
case nsMsgViewCommandType::flagMessages:
|
||||
rv = SetFlaggedByIndex(indices[i], PR_TRUE);
|
||||
break;
|
||||
case nsMsgViewCommandType::unflagMessages:
|
||||
rv = SetFlaggedByIndex(indices[i], PR_FALSE);
|
||||
break;
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
rv = SetThreadOfMsgReadByIndex(indices[i], imapUids, PR_TRUE);
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(PR_FALSE, "unhandled command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (thisIsImapFolder)
|
||||
{
|
||||
imapMessageFlagsType flags = kNoImapMsgFlag;
|
||||
PRBool addFlags = PR_FALSE;
|
||||
PRBool isRead = PR_FALSE;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
case nsMsgViewCommandType::markMessagesRead:
|
||||
flags |= kImapMsgSeenFlag;
|
||||
addFlags = PR_TRUE;
|
||||
break;
|
||||
case nsMsgViewCommandType::markMessagesUnread:
|
||||
flags |= kImapMsgSeenFlag;
|
||||
addFlags = PR_FALSE;
|
||||
break;
|
||||
case nsMsgViewCommandType::toggleMessageRead:
|
||||
{
|
||||
flags |= kImapMsgSeenFlag;
|
||||
m_db->IsRead(GetAt(indices[0]), &isRead);
|
||||
if (isRead)
|
||||
addFlags = PR_TRUE;
|
||||
else
|
||||
addFlags = PR_FALSE;
|
||||
}
|
||||
break;
|
||||
case nsMsgViewCommandType::flagMessages:
|
||||
flags |= kImapMsgFlaggedFlag;
|
||||
addFlags = PR_TRUE;
|
||||
break;
|
||||
case nsMsgViewCommandType::unflagMessages:
|
||||
flags |= kImapMsgFlaggedFlag;
|
||||
nsresult rv = NS_OK;
|
||||
nsMsgKeyArray imapUids;
|
||||
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);
|
||||
PRBool thisIsImapFolder = (imapFolder != nsnull);
|
||||
if (command == nsMsgViewCommandType::deleteMsg)
|
||||
rv = DeleteMessages(mMsgWindow, indices, numIndices, PR_FALSE);
|
||||
else if (command == nsMsgViewCommandType::deleteNoTrash)
|
||||
rv = DeleteMessages(mMsgWindow, indices, numIndices, PR_TRUE);
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < numIndices; i++)
|
||||
{
|
||||
if (thisIsImapFolder && command != nsMsgViewCommandType::markThreadRead)
|
||||
imapUids.Add(GetAt(indices[i]));
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case nsMsgViewCommandType::markMessagesRead:
|
||||
rv = SetReadByIndex(indices[i], PR_TRUE);
|
||||
break;
|
||||
case nsMsgViewCommandType::markMessagesUnread:
|
||||
rv = SetReadByIndex(indices[i], PR_FALSE);
|
||||
break;
|
||||
case nsMsgViewCommandType::toggleMessageRead:
|
||||
rv = ToggleReadByIndex(indices[i]);
|
||||
break;
|
||||
case nsMsgViewCommandType::flagMessages:
|
||||
rv = SetFlaggedByIndex(indices[i], PR_TRUE);
|
||||
break;
|
||||
case nsMsgViewCommandType::unflagMessages:
|
||||
rv = SetFlaggedByIndex(indices[i], PR_FALSE);
|
||||
break;
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
rv = SetThreadOfMsgReadByIndex(indices[i], imapUids, PR_TRUE);
|
||||
break;
|
||||
case nsMsgViewCommandType::label1:
|
||||
case nsMsgViewCommandType::label2:
|
||||
case nsMsgViewCommandType::label3:
|
||||
case nsMsgViewCommandType::label4:
|
||||
case nsMsgViewCommandType::label5:
|
||||
rv = SetLabelByIndex(indices[i], (command - nsMsgViewCommandType::label1 + 1));
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(PR_FALSE, "unhandled command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (thisIsImapFolder)
|
||||
{
|
||||
imapMessageFlagsType flags = kNoImapMsgFlag;
|
||||
PRBool addFlags = PR_FALSE;
|
||||
PRBool isRead = PR_FALSE;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case nsMsgViewCommandType::markThreadRead:
|
||||
case nsMsgViewCommandType::markMessagesRead:
|
||||
flags |= kImapMsgSeenFlag;
|
||||
addFlags = PR_TRUE;
|
||||
break;
|
||||
case nsMsgViewCommandType::markMessagesUnread:
|
||||
flags |= kImapMsgSeenFlag;
|
||||
addFlags = PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags != kNoImapMsgFlag) // can't get here without thisIsImapThreadPane == TRUE
|
||||
imapFolder->StoreImapFlags(flags, addFlags, imapUids.GetArray(), imapUids.GetSize());
|
||||
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
break;
|
||||
case nsMsgViewCommandType::toggleMessageRead:
|
||||
{
|
||||
flags |= kImapMsgSeenFlag;
|
||||
m_db->IsRead(GetAt(indices[0]), &isRead);
|
||||
if (isRead)
|
||||
addFlags = PR_TRUE;
|
||||
else
|
||||
addFlags = PR_FALSE;
|
||||
}
|
||||
break;
|
||||
case nsMsgViewCommandType::flagMessages:
|
||||
flags |= kImapMsgFlaggedFlag;
|
||||
addFlags = PR_TRUE;
|
||||
break;
|
||||
case nsMsgViewCommandType::unflagMessages:
|
||||
flags |= kImapMsgFlaggedFlag;
|
||||
addFlags = PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags != kNoImapMsgFlag) // can't get here without thisIsImapThreadPane == TRUE
|
||||
imapFolder->StoreImapFlags(flags, addFlags, imapUids.GetArray(), imapUids.GetSize());
|
||||
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
// view modifications methods by index
|
||||
|
||||
@ -1735,6 +1796,22 @@ nsresult nsMsgDBView::SetFlaggedByIndex(nsMsgViewIndex index, PRBool mark)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::SetLabelByIndex(nsMsgViewIndex index, nsMsgLabelValue label)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!IsValidIndex(index))
|
||||
return NS_MSG_INVALID_DBVIEW_INDEX;
|
||||
|
||||
nsCOMPtr <nsIMsgDatabase> dbToUse;
|
||||
rv = GetDBForViewIndex(index, getter_AddRefs(dbToUse));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = dbToUse->SetLabel(m_keys[index], label);
|
||||
NoteChange(index, 1, nsMsgViewNotificationCode::changed);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// reversing threads involves reversing the threads but leaving the
|
||||
@ -1994,6 +2071,7 @@ nsresult nsMsgDBView::GetFieldTypeAndLenForSort(nsMsgViewSortTypeValue sortType,
|
||||
case nsMsgViewSortType::byFlagged:
|
||||
case nsMsgViewSortType::byUnread:
|
||||
case nsMsgViewSortType::byStatus:
|
||||
case nsMsgViewSortType::byLabel:
|
||||
*pFieldType = kU32;
|
||||
*pMaxLen = sizeof(PRUint32);
|
||||
break;
|
||||
@ -2097,6 +2175,9 @@ nsresult nsMsgDBView::GetLongField(nsIMsgHdr *msgHdr, nsMsgViewSortTypeValue sor
|
||||
case nsMsgViewSortType::byStatus:
|
||||
rv = GetStatusSortValue(msgHdr,result);
|
||||
break;
|
||||
case nsMsgViewSortType::byLabel:
|
||||
rv = msgHdr->GetLabel(result);
|
||||
break;
|
||||
case nsMsgViewSortType::byFlagged:
|
||||
bits = 0;
|
||||
rv = msgHdr->GetFlags(&bits);
|
||||
|
@ -132,6 +132,7 @@ protected:
|
||||
nsresult FetchStatus(PRUint32 aFlags, PRUnichar ** aStatusString);
|
||||
nsresult FetchSize(nsIMsgHdr * aHdr, PRUnichar ** aSizeString);
|
||||
nsresult FetchPriority(nsIMsgHdr *aHdr, PRUnichar ** aPriorityString);
|
||||
nsresult FetchLabel(nsIMsgHdr *aHdr, PRUnichar ** aLabelString);
|
||||
nsresult CycleThreadedColumn(nsIDOMElement * aElement);
|
||||
|
||||
// Save and Restore Selection are a pair of routines you should
|
||||
@ -220,6 +221,7 @@ protected:
|
||||
nsresult SetReadByIndex(nsMsgViewIndex index, PRBool read);
|
||||
nsresult SetThreadOfMsgReadByIndex(nsMsgViewIndex index, nsMsgKeyArray &keysMarkedRead, PRBool read);
|
||||
nsresult SetFlaggedByIndex(nsMsgViewIndex index, PRBool mark);
|
||||
nsresult SetLabelByIndex(nsMsgViewIndex index, nsMsgLabelValue label);
|
||||
nsresult OrExtraFlag(nsMsgViewIndex index, PRUint32 orflag);
|
||||
nsresult AndExtraFlag(nsMsgViewIndex index, PRUint32 andflag);
|
||||
nsresult SetExtraFlag(nsMsgViewIndex index, PRUint32 extraflag);
|
||||
|
@ -214,6 +214,7 @@ interface nsIMsgDatabase : nsIDBChangeAnnouncer {
|
||||
in nsIDBChangeListener instigator);
|
||||
void MarkOffline(in nsMsgKey key, in boolean offline,
|
||||
in nsIDBChangeListener instigator);
|
||||
void SetLabel(in nsMsgKey key, in nsMsgLabelValue label);
|
||||
|
||||
[noscript] void AllMsgKeysImapDeleted(in nsMsgKeyArrayPtr keys, out boolean allDeleted);
|
||||
|
||||
|
@ -235,6 +235,7 @@ virtual nsresult AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr);
|
||||
mdb_token m_messageSizeColumnToken;
|
||||
mdb_token m_flagsColumnToken;
|
||||
mdb_token m_priorityColumnToken;
|
||||
mdb_token m_labelColumnToken;
|
||||
mdb_token m_statusOffsetColumnToken;
|
||||
mdb_token m_numLinesColumnToken;
|
||||
mdb_token m_ccListColumnToken;
|
||||
|
@ -318,134 +318,134 @@ int msg_UnHex(char C)
|
||||
void nsMailDatabase::UpdateFolderFlag(nsIMsgDBHdr *mailHdr, PRBool bSet,
|
||||
MsgFlags flag, nsIOFileStream **ppFileStream)
|
||||
{
|
||||
static char buf[50];
|
||||
nsIOFileStream *fileStream = (m_folderStream) ? m_folderStream : *ppFileStream;
|
||||
//#ifdef GET_FILE_STUFF_TOGETHER
|
||||
static char buf[50];
|
||||
nsIOFileStream *fileStream = (m_folderStream) ? m_folderStream : *ppFileStream;
|
||||
//#ifdef GET_FILE_STUFF_TOGETHER
|
||||
#ifdef XP_MAC
|
||||
/* ducarroz: Do we still need this ??
|
||||
// This is a horrible hack and we should make sure we don't need it anymore.
|
||||
// It has to do with multiple people having the same file open, I believe, but the
|
||||
// mac file system only has one handle, and they compete for the file position.
|
||||
// Prevent closing the file from under the incorporate stuff. #82785.
|
||||
int32 savedPosition = -1;
|
||||
if (!fid && gIncorporatePath && !XP_STRCMP(m_folderSpec, gIncorporatePath))
|
||||
{
|
||||
/* ducarroz: Do we still need this ??
|
||||
// This is a horrible hack and we should make sure we don't need it anymore.
|
||||
// It has to do with multiple people having the same file open, I believe, but the
|
||||
// mac file system only has one handle, and they compete for the file position.
|
||||
// Prevent closing the file from under the incorporate stuff. #82785.
|
||||
int32 savedPosition = -1;
|
||||
if (!fid && gIncorporatePath && !XP_STRCMP(m_folderSpec, gIncorporatePath))
|
||||
{
|
||||
fid = gIncorporateFID;
|
||||
savedPosition = ftell(gIncorporateFID); // so we can restore it.
|
||||
}
|
||||
*/
|
||||
savedPosition = ftell(gIncorporateFID); // so we can restore it.
|
||||
}
|
||||
*/
|
||||
#endif // XP_MAC
|
||||
PRUint32 offset;
|
||||
(void)mailHdr->GetStatusOffset(&offset);
|
||||
if (offset > 0)
|
||||
{
|
||||
|
||||
if (fileStream == NULL)
|
||||
{
|
||||
fileStream = new nsIOFileStream(nsFileSpec(*m_folderSpec));
|
||||
}
|
||||
if (fileStream)
|
||||
{
|
||||
PRUint32 msgOffset;
|
||||
(void)mailHdr->GetMessageOffset(&msgOffset);
|
||||
PRUint32 position = offset + msgOffset;
|
||||
PR_ASSERT(offset < 10000);
|
||||
fileStream->seek(position);
|
||||
buf[0] = '\0';
|
||||
if (fileStream->readline(buf, sizeof(buf)))
|
||||
{
|
||||
if (strncmp(buf, X_MOZILLA_STATUS, X_MOZILLA_STATUS_LEN) == 0 &&
|
||||
strncmp(buf + X_MOZILLA_STATUS_LEN, ": ", 2) == 0 &&
|
||||
strlen(buf) >= X_MOZILLA_STATUS_LEN + 6)
|
||||
{
|
||||
PRUint32 flags;
|
||||
(void)mailHdr->GetFlags(&flags);
|
||||
if (!(flags & MSG_FLAG_EXPUNGED))
|
||||
{
|
||||
int i;
|
||||
char *p = buf + X_MOZILLA_STATUS_LEN + 2;
|
||||
|
||||
for (i=0, flags = 0; i<4; i++, p++)
|
||||
{
|
||||
flags = (flags << 4) | msg_UnHex(*p);
|
||||
}
|
||||
|
||||
PRUint32 curFlags;
|
||||
(void)mailHdr->GetFlags(&curFlags);
|
||||
flags = (flags & MSG_FLAG_QUEUED) |
|
||||
(curFlags & ~MSG_FLAG_RUNTIME_ONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~MSG_FLAG_RUNTIME_ONLY;
|
||||
}
|
||||
fileStream->seek(position);
|
||||
// We are filing out old Cheddar flags here
|
||||
PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS_FORMAT,
|
||||
flags & 0x0000FFFF);
|
||||
fileStream->write(buf, PL_strlen(buf));
|
||||
fileStream->flush();
|
||||
|
||||
// time to upate x-mozilla-status2
|
||||
position = fileStream->tell();
|
||||
fileStream->seek(position + MSG_LINEBREAK_LEN);
|
||||
if (fileStream->readline(buf, sizeof(buf)))
|
||||
{
|
||||
if (strncmp(buf, X_MOZILLA_STATUS2, X_MOZILLA_STATUS2_LEN) == 0 &&
|
||||
strncmp(buf + X_MOZILLA_STATUS2_LEN, ": ", 2) == 0 &&
|
||||
strlen(buf) >= X_MOZILLA_STATUS2_LEN + 10)
|
||||
{
|
||||
PRUint32 dbFlags;
|
||||
(void)mailHdr->GetFlags(&dbFlags);
|
||||
dbFlags &= (MSG_FLAG_MDN_REPORT_NEEDED | MSG_FLAG_MDN_REPORT_SENT | MSG_FLAG_TEMPLATE);
|
||||
fileStream->seek(position + MSG_LINEBREAK_LEN);
|
||||
PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS2_FORMAT, dbFlags);
|
||||
fileStream->write(buf, PL_strlen(buf));
|
||||
fileStream->flush();
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
PRUint32 offset;
|
||||
(void)mailHdr->GetStatusOffset(&offset);
|
||||
if (offset > 0)
|
||||
{
|
||||
|
||||
if (fileStream == NULL)
|
||||
{
|
||||
fileStream = new nsIOFileStream(nsFileSpec(*m_folderSpec));
|
||||
}
|
||||
if (fileStream)
|
||||
{
|
||||
PRUint32 msgOffset;
|
||||
(void)mailHdr->GetMessageOffset(&msgOffset);
|
||||
PRUint32 position = offset + msgOffset;
|
||||
PR_ASSERT(offset < 10000);
|
||||
fileStream->seek(position);
|
||||
buf[0] = '\0';
|
||||
if (fileStream->readline(buf, sizeof(buf)))
|
||||
{
|
||||
if (strncmp(buf, X_MOZILLA_STATUS, X_MOZILLA_STATUS_LEN) == 0 &&
|
||||
strncmp(buf + X_MOZILLA_STATUS_LEN, ": ", 2) == 0 &&
|
||||
strlen(buf) >= X_MOZILLA_STATUS_LEN + 6)
|
||||
{
|
||||
PRUint32 flags;
|
||||
(void)mailHdr->GetFlags(&flags);
|
||||
if (!(flags & MSG_FLAG_EXPUNGED))
|
||||
{
|
||||
int i;
|
||||
char *p = buf + X_MOZILLA_STATUS_LEN + 2;
|
||||
|
||||
for (i=0, flags = 0; i<4; i++, p++)
|
||||
{
|
||||
flags = (flags << 4) | msg_UnHex(*p);
|
||||
}
|
||||
|
||||
PRUint32 curFlags;
|
||||
(void)mailHdr->GetFlags(&curFlags);
|
||||
flags = (flags & MSG_FLAG_QUEUED) |
|
||||
(curFlags & ~MSG_FLAG_RUNTIME_ONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~MSG_FLAG_RUNTIME_ONLY;
|
||||
}
|
||||
fileStream->seek(position);
|
||||
// We are filing out old Cheddar flags here
|
||||
PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS_FORMAT,
|
||||
flags & 0x0000FFFF);
|
||||
fileStream->write(buf, PL_strlen(buf));
|
||||
fileStream->flush();
|
||||
|
||||
// time to upate x-mozilla-status2
|
||||
position = fileStream->tell();
|
||||
fileStream->seek(position + MSG_LINEBREAK_LEN);
|
||||
if (fileStream->readline(buf, sizeof(buf)))
|
||||
{
|
||||
if (strncmp(buf, X_MOZILLA_STATUS2, X_MOZILLA_STATUS2_LEN) == 0 &&
|
||||
strncmp(buf + X_MOZILLA_STATUS2_LEN, ": ", 2) == 0 &&
|
||||
strlen(buf) >= X_MOZILLA_STATUS2_LEN + 10)
|
||||
{
|
||||
PRUint32 dbFlags;
|
||||
(void)mailHdr->GetFlags(&dbFlags);
|
||||
dbFlags &= 0xFFFF0000;
|
||||
fileStream->seek(position + MSG_LINEBREAK_LEN);
|
||||
PR_snprintf(buf, sizeof(buf), X_MOZILLA_STATUS2_FORMAT, dbFlags);
|
||||
fileStream->write(buf, PL_strlen(buf));
|
||||
fileStream->flush();
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Didn't find %s where expected at position %ld\n"
|
||||
"instead, found %s.\n",
|
||||
X_MOZILLA_STATUS, (long) position, buf);
|
||||
printf("Didn't find %s where expected at position %ld\n"
|
||||
"instead, found %s.\n",
|
||||
X_MOZILLA_STATUS, (long) position, buf);
|
||||
#endif
|
||||
SetReparse(PR_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetReparse(PR_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Couldn't read old status line at all at position %ld\n",
|
||||
(long) position);
|
||||
printf("Couldn't read old status line at all at position %ld\n",
|
||||
(long) position);
|
||||
#endif
|
||||
SetReparse(PR_TRUE);
|
||||
}
|
||||
SetReparse(PR_TRUE);
|
||||
}
|
||||
#ifdef XP_MAC
|
||||
/* ducarroz: Do we still need this ??
|
||||
// Restore the file position
|
||||
if (savedPosition >= 0)
|
||||
XP_FileSeek(fid, savedPosition, SEEK_SET);
|
||||
*/
|
||||
/* ducarroz: Do we still need this ??
|
||||
// Restore the file position
|
||||
if (savedPosition >= 0)
|
||||
XP_FileSeek(fid, savedPosition, SEEK_SET);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Couldn't open mail folder for update%s!\n",
|
||||
(const char*)m_folderSpec);
|
||||
printf("Couldn't open mail folder for update%s!\n",
|
||||
(const char*)m_folderSpec);
|
||||
#endif
|
||||
PR_ASSERT(PR_FALSE);
|
||||
}
|
||||
}
|
||||
//#endif // GET_FILE_STUFF_TOGETHER
|
||||
PR_ASSERT(PR_FALSE);
|
||||
}
|
||||
}
|
||||
//#endif // GET_FILE_STUFF_TOGETHER
|
||||
#ifdef XP_MAC
|
||||
if (!m_folderStream /*&& fid != gIncorporateFID*/) /* ducarroz: Do we still need this ?? */
|
||||
if (!m_folderStream /*&& fid != gIncorporateFID*/) /* ducarroz: Do we still need this ?? */
|
||||
#else
|
||||
if (!m_folderStream)
|
||||
if (!m_folderStream)
|
||||
#endif
|
||||
*ppFileStream = fileStream; // This tells the caller that we opened the file, and please to close it.
|
||||
*ppFileStream = fileStream; // This tells the caller that we opened the file, and please to close it.
|
||||
}
|
||||
|
||||
/* static */ nsresult nsMailDatabase::SetSummaryValid(PRBool valid)
|
||||
|
@ -653,6 +653,7 @@ nsMsgDatabase::nsMsgDatabase()
|
||||
m_messageSizeColumnToken(0),
|
||||
m_flagsColumnToken(0),
|
||||
m_priorityColumnToken(0),
|
||||
m_labelColumnToken(0),
|
||||
m_statusOffsetColumnToken(0),
|
||||
m_numLinesColumnToken(0),
|
||||
m_ccListColumnToken(0),
|
||||
@ -712,7 +713,7 @@ nsMsgDatabase::~nsMsgDatabase()
|
||||
}
|
||||
if (m_mdbEnv)
|
||||
{
|
||||
m_mdbEnv->CutStrongRef(m_mdbEnv); //??? is this right?
|
||||
m_mdbEnv->CloseMdbObject(m_mdbEnv); //??? is this right?
|
||||
m_mdbEnv = nsnull;
|
||||
}
|
||||
if (m_ChangeListeners)
|
||||
@ -996,37 +997,40 @@ nsresult nsMsgDatabase::CloseMDB(PRBool commit)
|
||||
// This is evil in the com world, but there are times we need to delete the file.
|
||||
NS_IMETHODIMP nsMsgDatabase::ForceClosed()
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
nsCOMPtr<nsIMsgDatabase> aDb(do_QueryInterface(this, &err));
|
||||
|
||||
// make sure someone has a reference so object won't get deleted out from under us.
|
||||
AddRef();
|
||||
NotifyAnnouncerGoingAway();
|
||||
// OK, remove from cache first and close the store.
|
||||
// RemoveFromCache(this);
|
||||
NS_IF_RELEASE(m_dbFolderInfo);
|
||||
// clear out db ptr in folder info; it might have just become invalid
|
||||
if (m_dbFolderInfo)
|
||||
m_dbFolderInfo->m_mdb = nsnull;
|
||||
m_dbFolderInfo = nsnull;
|
||||
|
||||
err = CloseMDB(PR_FALSE); // since we're about to delete it, no need to commit.
|
||||
ClearHdrCache(PR_FALSE);
|
||||
nsresult err = NS_OK;
|
||||
nsCOMPtr<nsIMsgDatabase> aDb(do_QueryInterface(this, &err));
|
||||
|
||||
// make sure someone has a reference so object won't get deleted out from under us.
|
||||
AddRef();
|
||||
NotifyAnnouncerGoingAway();
|
||||
NS_IF_RELEASE(m_dbFolderInfo);
|
||||
// clear out db ptr in folder info; it might have just become invalid
|
||||
if (m_dbFolderInfo)
|
||||
m_dbFolderInfo->m_mdb = nsnull;
|
||||
m_dbFolderInfo = nsnull;
|
||||
|
||||
err = CloseMDB(PR_FALSE); // since we're about to delete it, no need to commit.
|
||||
ClearHdrCache(PR_FALSE);
|
||||
#ifdef DEBUG_bienvenu
|
||||
if (m_headersInUse && m_headersInUse->entryCount > 0)
|
||||
{
|
||||
// NS_ASSERTION(PR_FALSE, "leaking headers");
|
||||
// NS_ASSERTION(PR_FALSE, "leaking headers");
|
||||
printf("leaking %d headers in %s\n", m_headersInUse->entryCount, (const char *) m_dbName);
|
||||
}
|
||||
#endif
|
||||
ClearUseHdrCache();
|
||||
if (m_mdbStore)
|
||||
{
|
||||
m_mdbStore->CloseMdbObject(m_mdbEnv);
|
||||
m_mdbStore = nsnull;
|
||||
}
|
||||
Release();
|
||||
return err;
|
||||
ClearUseHdrCache();
|
||||
if (m_mdbAllMsgHeadersTable)
|
||||
{
|
||||
m_mdbAllMsgHeadersTable->Release();
|
||||
m_mdbAllMsgHeadersTable = nsnull;
|
||||
}
|
||||
if (m_mdbStore)
|
||||
{
|
||||
m_mdbStore->CloseMdbObject(m_mdbEnv);
|
||||
m_mdbStore = nsnull;
|
||||
}
|
||||
Release();
|
||||
return err;
|
||||
}
|
||||
|
||||
// caller must Release result.
|
||||
@ -1152,6 +1156,7 @@ const char *kDateColumnName = "date";
|
||||
const char *kMessageSizeColumnName = "size";
|
||||
const char *kFlagsColumnName = "flags";
|
||||
const char *kPriorityColumnName = "priority";
|
||||
const char *kLabelColumnName = "label";
|
||||
const char *kStatusOffsetColumnName = "statusOfset";
|
||||
const char *kNumLinesColumnName = "numLines";
|
||||
const char *kCCListColumnName = "ccList";
|
||||
@ -1271,6 +1276,7 @@ nsresult nsMsgDatabase::InitMDBInfo()
|
||||
GetStore()->StringToToken(GetEnv(), kMessageSizeColumnName, &m_messageSizeColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kFlagsColumnName, &m_flagsColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kPriorityColumnName, &m_priorityColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kLabelColumnName, &m_labelColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kStatusOffsetColumnName, &m_statusOffsetColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kNumLinesColumnName, &m_numLinesColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kCCListColumnName, &m_ccListColumnToken);
|
||||
@ -1779,6 +1785,23 @@ NS_IMETHODIMP nsMsgDatabase::MarkOffline(nsMsgKey key, PRBool offline,
|
||||
return SetKeyFlag(key, offline, MSG_FLAG_OFFLINE, instigator);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::SetLabel(nsMsgKey key, nsMsgLabelValue label)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
|
||||
rv = GetMsgHdrForKey(key, getter_AddRefs(msgHdr));
|
||||
if (NS_FAILED(rv) || !msgHdr)
|
||||
return NS_MSG_MESSAGE_NOT_FOUND; // XXX return rv?
|
||||
|
||||
msgHdr->SetLabel(label);
|
||||
// set the flag in the x-mozilla-status2 line.
|
||||
return SetKeyFlag(key, PR_TRUE, label << 25, nsnull);
|
||||
// ### dmb need to use persistent flags in x-mozilla-status2 for this.
|
||||
// so that we don't lose the labels when we reparse the folder.
|
||||
// return SetKeyFlag(key, offline, MSG_FLAG_OFFLINE, instigator);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgDatabase::AllMsgKeysImapDeleted(nsMsgKeyArray *keys, PRBool *allKeysDeleted)
|
||||
{
|
||||
@ -2387,7 +2410,7 @@ nsMsgDBThreadEnumerator::nsMsgDBThreadEnumerator(nsMsgDatabase* db,
|
||||
|
||||
nsMsgDBThreadEnumerator::~nsMsgDBThreadEnumerator()
|
||||
{
|
||||
NS_IF_RELEASE(mTableCursor);
|
||||
mTableCursor->CloseMdbObject(mDB->GetEnv());
|
||||
NS_IF_RELEASE(mResultThread);
|
||||
NS_RELEASE(mDB);
|
||||
}
|
||||
|
@ -545,6 +545,19 @@ NS_IMETHODIMP nsMsgHdr::GetPriority(nsMsgPriorityValue *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgHdr::SetLabel(nsMsgLabelValue label)
|
||||
{
|
||||
SetUInt32Column((PRUint32) label, m_mdb->m_labelColumnToken);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgHdr::GetLabel(nsMsgLabelValue *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
return GetUInt32Column(m_mdb->m_labelColumnToken, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgHdr::GetMessageOffset(PRUint32 *result)
|
||||
{
|
||||
NS_ENSURE_ARG(result);
|
||||
|
Loading…
x
Reference in New Issue
Block a user