add backend support for labels r=ssu, sr=sspitzer 106067

This commit is contained in:
bienvenu%netscape.com 2001-10-23 22:06:03 +00:00
parent 5fb19fec4a
commit 5955ba4686
10 changed files with 382 additions and 243 deletions

View File

@ -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)]

View File

@ -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;
};

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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);