mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
backend changes for cross-folder virtual folders, sr=mscott 11051
This commit is contained in:
parent
356984010a
commit
666683986e
@ -65,6 +65,7 @@ interface nsMsgViewType {
|
||||
const nsMsgViewTypeValue eShowThreadsWithUnread = 2;
|
||||
const nsMsgViewTypeValue eShowWatchedThreadsWithUnread = 3;
|
||||
const nsMsgViewTypeValue eShowQuickSearchResults = 4;
|
||||
const nsMsgViewtypeValue eShowVirtualFolderResults = 5;
|
||||
};
|
||||
|
||||
[scriptable, uuid(64852276-1dd2-11b2-8103-afe12002c053)]
|
||||
@ -266,7 +267,7 @@ interface nsIMsgDBView : nsISupports
|
||||
readonly attribute nsMsgViewSortTypeValue sortType;
|
||||
readonly attribute nsMsgViewSortOrderValue sortOrder;
|
||||
readonly attribute nsMsgKey keyForFirstSelectedMessage;
|
||||
|
||||
readonly attribute nsMsgViewIndex viewIndexForFirstSelectedMsg;
|
||||
/**
|
||||
* this method will automatically expand the destination thread,
|
||||
* if needs be.
|
||||
@ -290,6 +291,7 @@ interface nsIMsgDBView : nsISupports
|
||||
readonly attribute string URIForFirstSelectedMessage;
|
||||
readonly attribute nsIMsgDBHdr hdrForFirstSelectedMessage;
|
||||
void loadMessageByMsgKey(in nsMsgKey aMsgKey);
|
||||
void loadMessageByViewIndex(in nsMsgViewIndex aIndex);
|
||||
void loadMessageByUrl(in string aUrl);
|
||||
void reloadMessage();
|
||||
void reloadMessageWithAllParts();
|
||||
|
@ -114,6 +114,7 @@ CPPSRCS = \
|
||||
nsMsgSpecialViews.cpp \
|
||||
nsMsgQuickSearchDBView.cpp \
|
||||
nsMsgSearchDBView.cpp \
|
||||
nsMsgXFVirtualFolderDBView.cpp \
|
||||
nsMsgOfflineManager.cpp \
|
||||
nsMsgProgress.cpp \
|
||||
nsMessengerContentHandler.cpp \
|
||||
|
@ -95,6 +95,8 @@
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
#define PREF_MAIL_ACCOUNTMANAGER_ACCOUNTS "mail.accountmanager.accounts"
|
||||
#define PREF_MAIL_ACCOUNTMANAGER_DEFAULTACCOUNT "mail.accountmanager.defaultaccount"
|
||||
#define PREF_MAIL_ACCOUNTMANAGER_LOCALFOLDERSSERVER "mail.accountmanager.localfoldersserver"
|
||||
@ -2632,30 +2634,32 @@ nsresult VirtualFolderChangeListener::Init()
|
||||
/**
|
||||
* nsIDBChangeListener
|
||||
*/
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags, PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags, PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> msgDB;
|
||||
|
||||
nsresult rv = m_folderWatching->GetMsgDatabase(nsnull, getter_AddRefs(msgDB));
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = msgDB->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool oldMatch = PR_FALSE, newMatch = PR_FALSE;
|
||||
rv = m_searchSession->MatchHdr(msgHdr, msgDB, &newMatch);
|
||||
rv = m_searchSession->MatchHdr(aHdrChanged, msgDB, &newMatch);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (m_searchOnMsgStatus)
|
||||
{
|
||||
// if status is a search criteria, check if the header matched before
|
||||
// it changed, in order to determine if we need to bump the counts.
|
||||
msgHdr->SetFlags(aOldFlags);
|
||||
rv = m_searchSession->MatchHdr(msgHdr, msgDB, &oldMatch);
|
||||
msgHdr->SetFlags(aNewFlags); // restore new flags even on match failure.
|
||||
aHdrChanged->SetFlags(aOldFlags);
|
||||
rv = m_searchSession->MatchHdr(aHdrChanged, msgDB, &oldMatch);
|
||||
aHdrChanged->SetFlags(aNewFlags); // restore new flags even on match failure.
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else
|
||||
oldMatch = newMatch;
|
||||
// we don't want to change the total counts if this virtual folder is open in a view,
|
||||
// because we won't remove the header from view while its open.
|
||||
// because we won't remove the header from view while it's open. On the other hand,
|
||||
// it's hard to fix the count when the user clicks away to another folder, w/o re-running
|
||||
// the search, or setting some sort of pending count change.
|
||||
// Maybe this needs to be handled in the view code...the view could do the same calculation
|
||||
// and also keep track of the counts changed. Then, when the view was closed, if it's a virtual
|
||||
// folder, it could update the counts for the db.
|
||||
if (oldMatch != newMatch || (oldMatch && (aOldFlags & MSG_FLAG_READ) != (aNewFlags & MSG_FLAG_READ)))
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> virtDatabase;
|
||||
@ -2664,9 +2668,17 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnKeyChange(nsMsgKey aKeyChanged, PRU
|
||||
rv = m_virtualFolder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(virtDatabase));
|
||||
PRInt32 totalDelta = 0, unreadDelta = 0;
|
||||
if (oldMatch != newMatch)
|
||||
totalDelta = (oldMatch) ? -1 : 1;
|
||||
{
|
||||
// PRBool isOpen = PR_FALSE;
|
||||
// nsCOMPtr <nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID);
|
||||
// if (mailSession && aFolder)
|
||||
// mailSession->IsFolderOpenInWindow(m_virtualFolder, &isOpen);
|
||||
// we can't remove headers that no longer match - but we might add headers that newly match, someday.
|
||||
// if (!isOpen)
|
||||
totalDelta = (oldMatch) ? -1 : 1;
|
||||
}
|
||||
PRBool msgHdrIsRead;
|
||||
msgHdr->GetIsRead(&msgHdrIsRead);
|
||||
aHdrChanged->GetIsRead(&msgHdrIsRead);
|
||||
if (oldMatch == newMatch) // read flag changed state
|
||||
unreadDelta = (msgHdrIsRead) ? -1 : 1;
|
||||
else if (oldMatch) // else header should removed
|
||||
@ -2683,17 +2695,14 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnKeyChange(nsMsgKey aKeyChanged, PRU
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnKeyDeleted(nsMsgKey aKeyDeleted, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnHdrDeleted(nsIMsgDBHdr *aHdrDeleted, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> msgDB;
|
||||
|
||||
nsresult rv = m_folderWatching->GetMsgDatabase(nsnull, getter_AddRefs(msgDB));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = msgDB->GetMsgHdrForKey(aKeyDeleted, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool match = PR_FALSE;
|
||||
rv = m_searchSession->MatchHdr(msgHdr, msgDB, &match);
|
||||
rv = m_searchSession->MatchHdr(aHdrDeleted, msgDB, &match);
|
||||
if (match)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> virtDatabase;
|
||||
@ -2701,7 +2710,7 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnKeyDeleted(nsMsgKey aKeyDeleted, ns
|
||||
|
||||
nsresult rv = m_virtualFolder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(virtDatabase));
|
||||
PRBool msgHdrIsRead;
|
||||
msgHdr->GetIsRead(&msgHdrIsRead);
|
||||
aHdrDeleted->GetIsRead(&msgHdrIsRead);
|
||||
if (!msgHdrIsRead)
|
||||
dbFolderInfo->ChangeNumUnreadMessages(-1);
|
||||
dbFolderInfo->ChangeNumMessages(-1);
|
||||
@ -2711,17 +2720,14 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnKeyDeleted(nsMsgKey aKeyDeleted, ns
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnKeyAdded(nsMsgKey aNewKey, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnHdrAdded(nsIMsgDBHdr *aNewHdr, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> msgDB;
|
||||
|
||||
nsresult rv = m_folderWatching->GetMsgDatabase(nsnull, getter_AddRefs(msgDB));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = msgDB->GetMsgHdrForKey(aNewKey, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool match = PR_FALSE;
|
||||
rv = m_searchSession->MatchHdr(msgHdr, msgDB, &match);
|
||||
rv = m_searchSession->MatchHdr(aNewHdr, msgDB, &match);
|
||||
if (match)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> virtDatabase;
|
||||
@ -2729,9 +2735,13 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnKeyAdded(nsMsgKey aNewKey, nsMsgKey
|
||||
|
||||
rv = m_virtualFolder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(virtDatabase));
|
||||
PRBool msgHdrIsRead;
|
||||
msgHdr->GetIsRead(&msgHdrIsRead);
|
||||
PRUint32 msgFlags;
|
||||
aNewHdr->GetIsRead(&msgHdrIsRead);
|
||||
aNewHdr->GetFlags(&msgFlags);
|
||||
if (!msgHdrIsRead)
|
||||
dbFolderInfo->ChangeNumUnreadMessages(1);
|
||||
if (msgFlags & MSG_FLAG_NEW)
|
||||
m_virtualFolder->SetHasNewMessages(PR_TRUE);
|
||||
dbFolderInfo->ChangeNumMessages(1);
|
||||
m_virtualFolder->UpdateSummaryTotals(true); // force update from db.
|
||||
virtDatabase->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
@ -2746,11 +2756,10 @@ NS_IMETHODIMP VirtualFolderChangeListener::OnParentChanged(nsMsgKey aKeyChanged,
|
||||
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnAnnouncerGoingAway(nsIDBChangeAnnouncer *instigator)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
|
||||
if (msgDBService)
|
||||
msgDBService->UnregisterPendingListener(this);
|
||||
return rv;
|
||||
nsCOMPtr <nsIMsgDatabase> msgDB = do_QueryInterface(instigator);
|
||||
if (msgDB)
|
||||
msgDB->RemoveListener(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP VirtualFolderChangeListener::OnReadChanged(nsIDBChangeListener *aInstigator)
|
||||
@ -2790,67 +2799,90 @@ nsresult nsMsgAccountManager::LoadVirtualFolders()
|
||||
nsCOMPtr<nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = fileStream->Init(file, PR_RDONLY, 0664, PR_FALSE); //just have to read the messages
|
||||
rv = fileStream->Init(file, PR_RDONLY, 0664, PR_FALSE);
|
||||
nsCOMPtr <nsILineInputStream> lineInputStream(do_QueryInterface(fileStream));
|
||||
|
||||
PRBool isMore = PR_TRUE;
|
||||
nsCAutoString buffer;
|
||||
PRInt32 version = -1;
|
||||
nsCOMPtr <nsIMsgFolder> virtualFolder;
|
||||
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
|
||||
nsCOMPtr<nsIRDFResource> resource;
|
||||
nsCOMPtr<nsIRDFService> rdf(do_GetService("@mozilla.org/rdf/rdf-service;1", &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
while (isMore &&
|
||||
NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore)))
|
||||
{
|
||||
if (buffer.Length() > 0)
|
||||
{
|
||||
nsCOMPtr <nsIMsgFolder> folder;
|
||||
nsCOMPtr<nsIRDFService> rdf(do_GetService("@mozilla.org/rdf/rdf-service;1", &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIRDFResource> resource;
|
||||
rv = rdf->GetResource(buffer, getter_AddRefs(resource));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
folder = do_QueryInterface(resource, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (folder)
|
||||
if (version == -1)
|
||||
{
|
||||
// need to add the folder as a sub-folder of its parent.
|
||||
PRInt32 lastSlash = buffer.RFindChar('/');
|
||||
nsDependentCSubstring parentUri(buffer, 0, lastSlash);
|
||||
rdf->GetResource(parentUri, getter_AddRefs(resource));
|
||||
nsCOMPtr <nsIMsgFolder> parentFolder = do_QueryInterface(resource);
|
||||
if (parentFolder)
|
||||
{
|
||||
nsCOMPtr <nsIMsgFolder> childFolder;
|
||||
nsAutoString currentFolderNameStr;
|
||||
CopyUTF8toUTF16(Substring(buffer, lastSlash + 1, buffer.Length()), currentFolderNameStr);
|
||||
rv = parentFolder->AddSubfolder(currentFolderNameStr, getter_AddRefs(childFolder));
|
||||
if (!childFolder)
|
||||
childFolder = folder; // or just use folder?
|
||||
buffer.Cut(0, 8);
|
||||
PRInt32 irv;
|
||||
version = buffer.ToInteger(&irv);
|
||||
continue;
|
||||
}
|
||||
if (Substring(buffer, 0, 4).Equals("uri="))
|
||||
{
|
||||
buffer.Cut(0, 4);
|
||||
|
||||
nsCOMPtr <nsIMsgDatabase> db;
|
||||
childFolder->GetMsgDatabase(nsnull, getter_AddRefs(db)); // force db to get created.
|
||||
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
|
||||
rv = db->GetDBFolderInfo(getter_AddRefs(dbFolderInfo));
|
||||
childFolder->SetFlag(MSG_FOLDER_FLAG_VIRTUAL);
|
||||
nsXPIDLCString realFolderUri;
|
||||
dbFolderInfo->GetCharPtrProperty("searchFolderUri", getter_Copies(realFolderUri));
|
||||
// if we supported cross folder virtual folders, we'd have a list of folders uris,
|
||||
// and we'd have to add a pending listener for each of them.
|
||||
if (realFolderUri.Length())
|
||||
rv = rdf->GetResource(buffer, getter_AddRefs(resource));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
virtualFolder = do_QueryInterface(resource, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (virtualFolder)
|
||||
{
|
||||
// need to add the folder as a sub-folder of its parent.
|
||||
PRInt32 lastSlash = buffer.RFindChar('/');
|
||||
nsDependentCSubstring parentUri(buffer, 0, lastSlash);
|
||||
rdf->GetResource(parentUri, getter_AddRefs(resource));
|
||||
nsCOMPtr <nsIMsgFolder> parentFolder = do_QueryInterface(resource);
|
||||
if (parentFolder)
|
||||
{
|
||||
// we need to load the db for the actual folder so that many hdrs to download
|
||||
// will return false...
|
||||
rdf->GetResource(realFolderUri, getter_AddRefs(resource));
|
||||
nsAutoString currentFolderNameStr;
|
||||
nsCAutoString currentFolderNameCStr(Substring(buffer, lastSlash + 1, buffer.Length()));
|
||||
nsUnescape(currentFolderNameCStr.BeginWriting());
|
||||
CopyUTF8toUTF16(currentFolderNameCStr, currentFolderNameStr);
|
||||
nsCOMPtr <nsIMsgFolder> childFolder;
|
||||
rv = parentFolder->AddSubfolder(currentFolderNameStr, getter_AddRefs(childFolder));
|
||||
|
||||
nsCOMPtr <nsIMsgDatabase> db;
|
||||
virtualFolder->GetMsgDatabase(nsnull, getter_AddRefs(db)); // force db to get created.
|
||||
rv = db->GetDBFolderInfo(getter_AddRefs(dbFolderInfo));
|
||||
virtualFolder->SetFlag(MSG_FOLDER_FLAG_VIRTUAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Substring(buffer, 0, 6).Equals("scope="))
|
||||
{
|
||||
buffer.Cut(0, 6);
|
||||
// if this is a cross folder virtual folder, we have a list of folders uris,
|
||||
// and we have to add a pending listener for each of them.
|
||||
if (buffer.Length())
|
||||
{
|
||||
nsCStringArray folderUris;
|
||||
dbFolderInfo->SetCharPtrProperty("searchFolderUri", buffer.get());
|
||||
folderUris.ParseString(buffer.get(), "|");
|
||||
for (PRInt32 i = 0; i < folderUris.Count(); i++)
|
||||
{
|
||||
rdf->GetResource(*(folderUris[i]), getter_AddRefs(resource));
|
||||
nsCOMPtr <nsIMsgFolder> realFolder = do_QueryInterface(resource);
|
||||
VirtualFolderChangeListener *dbListener = new VirtualFolderChangeListener();
|
||||
m_virtualFolderListeners.AppendObject(dbListener);
|
||||
dbListener->m_virtualFolder = childFolder;
|
||||
dbListener->m_virtualFolder = virtualFolder;
|
||||
dbListener->m_folderWatching = realFolder;
|
||||
dbListener->Init();
|
||||
msgDBService->RegisterPendingListener(realFolder, dbListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Substring(buffer, 0, 6).Equals("terms="))
|
||||
{
|
||||
buffer.Cut(0, 6);
|
||||
dbFolderInfo->SetCharPtrProperty("searchStr", buffer.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2894,13 +2926,24 @@ NS_IMETHODIMP nsMsgAccountManager::SaveVirtualFolders()
|
||||
file,
|
||||
PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
|
||||
0664);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
WriteLineToOutputStream("version=", "1", outputStream);
|
||||
|
||||
}
|
||||
nsCOMPtr <nsIRDFResource> folderRes (do_QueryElementAt(virtualFolders, folderIndex));
|
||||
nsCOMPtr <nsIMsgFolder> msgFolder = do_QueryInterface(folderRes);
|
||||
const char *uri;
|
||||
nsCOMPtr <nsIMsgDatabase> db;
|
||||
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
|
||||
rv = msgFolder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(db)); // force db to get created.
|
||||
nsXPIDLCString srchFolderUri;
|
||||
nsXPIDLCString searchTerms;
|
||||
dbFolderInfo->GetCharPtrProperty("searchFolderUri", getter_Copies(srchFolderUri));
|
||||
dbFolderInfo->GetCharPtrProperty("searchStr", getter_Copies(searchTerms));
|
||||
folderRes->GetValueConst(&uri);
|
||||
PRUint32 writeCount;
|
||||
outputStream->Write(uri, strlen(uri), &writeCount);
|
||||
outputStream->Write("\n", 1, &writeCount);
|
||||
WriteLineToOutputStream("uri=", uri, outputStream);
|
||||
WriteLineToOutputStream("scope=", srchFolderUri.get(), outputStream);
|
||||
WriteLineToOutputStream("terms=", searchTerms.get(), outputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2911,6 +2954,14 @@ NS_IMETHODIMP nsMsgAccountManager::SaveVirtualFolders()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgAccountManager::WriteLineToOutputStream(const char *prefix, const char * line, nsIOutputStream *outputStream)
|
||||
{
|
||||
PRUint32 writeCount;
|
||||
outputStream->Write(prefix, strlen(prefix), &writeCount);
|
||||
outputStream->Write(line, strlen(line), &writeCount);
|
||||
outputStream->Write("\n", 1, &writeCount);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgAccountManager::OnItemAdded(nsIRDFResource *parentItem, nsISupports *item)
|
||||
{
|
||||
@ -2933,7 +2984,6 @@ NS_IMETHODIMP nsMsgAccountManager::OnItemAdded(nsIRDFResource *parentItem, nsISu
|
||||
nsCOMPtr <nsIMsgDatabase> virtDatabase;
|
||||
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
|
||||
m_virtualFolderListeners.AppendObject(dbListener);
|
||||
|
||||
rv = folder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(virtDatabase));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXPIDLCString srchFolderUri;
|
||||
@ -2942,7 +2992,10 @@ NS_IMETHODIMP nsMsgAccountManager::OnItemAdded(nsIRDFResource *parentItem, nsISu
|
||||
// and we'd have to add a pending listener for each of them.
|
||||
rv = GetExistingFolder(srchFolderUri.get(), getter_AddRefs(dbListener->m_folderWatching));
|
||||
if (dbListener->m_folderWatching)
|
||||
{
|
||||
dbListener->Init();
|
||||
msgDBService->RegisterPendingListener(dbListener->m_folderWatching, dbListener);
|
||||
}
|
||||
}
|
||||
rv = SaveVirtualFolders();
|
||||
}
|
||||
|
@ -204,6 +204,7 @@ private:
|
||||
// handle virtual folders
|
||||
nsresult GetVirtualFoldersFile(nsCOMPtr<nsILocalFile>& file);
|
||||
nsresult LoadVirtualFolders();
|
||||
nsresult WriteLineToOutputStream(const char *prefix, const char * line, nsIOutputStream *outputStream);
|
||||
|
||||
static void getUniqueKey(const char* prefix,
|
||||
nsHashtable *hashTable,
|
||||
|
@ -406,6 +406,8 @@
|
||||
#define NS_MSGQUICKSEARCHDBVIEW_CONTRACTID \
|
||||
NS_MSGDBVIEW_CONTRACTID_PREFIX "quicksearch"
|
||||
|
||||
#define NS_MSGXFVFDBVIEW_CONTRACTID \
|
||||
NS_MSGDBVIEW_CONTRACTID_PREFIX "xfvf"
|
||||
|
||||
/* 52f860e0-1dd2-11b2-aa72-bb751981bd00 */
|
||||
#define NS_MSGTHREADEDDBVIEW_CID \
|
||||
@ -432,6 +434,10 @@
|
||||
{0x2dd9d0fe, 0xb609, 0x11d6, \
|
||||
{0xba, 0xcc, 0x00, 0x10, 0x83, 0x35, 0x74, 0x8d}}
|
||||
|
||||
/* 2af6e050-04f6-495a-8387-86b0aeb1863c */
|
||||
#define NS_MSG_XFVFDBVIEW_CID \
|
||||
{0x2af6e050, 0x04f6, 0x495a, \
|
||||
{0x83, 0x87, 0x86, 0xb0, 0xae, 0xb1, 0x86, 0x3c}}
|
||||
//
|
||||
// nsMsgAccountManager
|
||||
//
|
||||
|
@ -134,6 +134,7 @@ nsMsgDBView::nsMsgDBView()
|
||||
m_viewFlags = nsMsgViewFlagsType::kNone;
|
||||
m_cachedMsgKey = nsMsgKey_None;
|
||||
m_currentlyDisplayedMsgKey = nsMsgKey_None;
|
||||
m_currentlyDisplayedViewIndex = nsMsgViewIndex_None;
|
||||
mNumSelectedRows = 0;
|
||||
mSuppressMsgDisplay = PR_FALSE;
|
||||
mSuppressCommandUpdating = PR_FALSE;
|
||||
@ -877,7 +878,7 @@ nsresult nsMsgDBView::RestoreSelection(nsMsgKey aCurrentMsgKey, nsMsgKeyArray *a
|
||||
nsresult nsMsgDBView::GenerateURIForMsgKey(nsMsgKey aMsgKey, nsIMsgFolder *folder, char ** aURI)
|
||||
{
|
||||
NS_ENSURE_ARG(folder);
|
||||
return(folder->GenerateMessageURI(aMsgKey, aURI));
|
||||
return(folder->GenerateMessageURI(aMsgKey, aURI));
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::CycleThreadedColumn(nsIDOMElement * aElement)
|
||||
@ -952,29 +953,32 @@ NS_IMETHODIMP nsMsgDBView::ReloadMessage()
|
||||
|
||||
nsresult nsMsgDBView::ReloadMessageHelper(PRBool forceAllParts)
|
||||
{
|
||||
if (!mSuppressMsgDisplay && m_currentlyDisplayedMsgKey != nsMsgKey_None)
|
||||
if (!mSuppressMsgDisplay && m_currentlyDisplayedViewIndex != nsMsgViewIndex_None)
|
||||
{
|
||||
nsMsgKey currentMsgToReload = m_currentlyDisplayedMsgKey;
|
||||
nsMsgKey currentMsgToReload = m_currentlyDisplayedViewIndex;
|
||||
m_currentlyDisplayedMsgKey = nsMsgKey_None;
|
||||
LoadMessageByMsgKeyHelper(currentMsgToReload, forceAllParts);
|
||||
m_currentlyDisplayedViewIndex = nsMsgViewIndex_None;
|
||||
LoadMessageByViewIndexHelper(m_currentlyDisplayedViewIndex, forceAllParts);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::UpdateDisplayMessage(nsMsgKey aMsgKey)
|
||||
nsresult nsMsgDBView::UpdateDisplayMessage(nsMsgViewIndex viewPosition)
|
||||
{
|
||||
nsresult rv;
|
||||
if (mCommandUpdater)
|
||||
{
|
||||
// get the subject and the folder for the message and inform the front end that
|
||||
// we changed the message we are currently displaying.
|
||||
nsMsgViewIndex viewPosition = FindViewIndex(aMsgKey);
|
||||
if (viewPosition != nsMsgViewIndex_None)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = GetMsgHdrForViewIndex(viewPosition, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
nsCOMPtr <nsIMsgFolder> folder;
|
||||
GetMsgFolder(getter_AddRefs(folder));
|
||||
|
||||
nsXPIDLString subject;
|
||||
FetchSubject(msgHdr, m_flags[viewPosition], getter_Copies(subject));
|
||||
|
||||
@ -982,11 +986,11 @@ nsresult nsMsgDBView::UpdateDisplayMessage(nsMsgKey aMsgKey)
|
||||
rv = msgHdr->GetStringProperty("keywords", getter_Copies(keywords));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
mCommandUpdater->DisplayMessageChanged(m_folder, subject, keywords);
|
||||
mCommandUpdater->DisplayMessageChanged(folder, subject, keywords);
|
||||
|
||||
if (m_folder)
|
||||
{
|
||||
rv = m_folder->SetLastMessageLoaded(aMsgKey);
|
||||
rv = m_folder->SetLastMessageLoaded(m_keys[viewPosition]);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
} // if view position is valid
|
||||
@ -997,26 +1001,46 @@ nsresult nsMsgDBView::UpdateDisplayMessage(nsMsgKey aMsgKey)
|
||||
// given a msg key, we will load the message for it.
|
||||
NS_IMETHODIMP nsMsgDBView::LoadMessageByMsgKey(nsMsgKey aMsgKey)
|
||||
{
|
||||
return LoadMessageByMsgKeyHelper(aMsgKey, PR_FALSE);
|
||||
return LoadMessageByViewIndexHelper(FindViewIndex(aMsgKey), PR_FALSE);
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::LoadMessageByMsgKeyHelper(nsMsgKey aMsgKey, PRBool forceAllParts)
|
||||
NS_IMETHODIMP nsMsgDBView::LoadMessageByViewIndex(nsMsgViewIndex aViewIndex)
|
||||
{
|
||||
NS_ASSERTION(aMsgKey != nsMsgKey_None,"trying to load nsMsgKey_None");
|
||||
if (aMsgKey == nsMsgKey_None) return NS_ERROR_UNEXPECTED;
|
||||
NS_ASSERTION(aViewIndex != nsMsgViewIndex_None,"trying to load nsMsgViewIndex_None");
|
||||
if (aViewIndex == nsMsgViewIndex_None) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (!mSuppressMsgDisplay && (m_currentlyDisplayedMsgKey != aMsgKey))
|
||||
nsXPIDLCString uri;
|
||||
nsresult rv = GetURIForViewIndex(aViewIndex, getter_Copies(uri));
|
||||
if (!mSuppressMsgDisplay && !m_currentlyDisplayedMsgUri.Equals(uri))
|
||||
{
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
mMessengerInstance->OpenURL(uri);
|
||||
m_currentlyDisplayedMsgKey = m_keys[aViewIndex];
|
||||
m_currentlyDisplayedMsgUri = uri;
|
||||
m_currentlyDisplayedViewIndex = aViewIndex;
|
||||
UpdateDisplayMessage(m_currentlyDisplayedViewIndex);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::LoadMessageByViewIndexHelper(nsMsgViewIndex aViewIndex, PRBool forceAllParts)
|
||||
{
|
||||
NS_ASSERTION(aViewIndex != nsMsgViewIndex_None,"trying to load nsMsgViewIndex_None");
|
||||
if (aViewIndex == nsMsgViewIndex_None) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (!mSuppressMsgDisplay && (m_currentlyDisplayedViewIndex != aViewIndex))
|
||||
{
|
||||
nsXPIDLCString uri;
|
||||
nsresult rv = GenerateURIForMsgKey(aMsgKey, m_folder, getter_Copies(uri));
|
||||
nsresult rv = GetURIForViewIndex(aViewIndex, getter_Copies(uri));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (forceAllParts)
|
||||
{
|
||||
uri.Append("?fetchCompleteMessage=true");
|
||||
}
|
||||
|
||||
mMessengerInstance->OpenURL(uri);
|
||||
m_currentlyDisplayedMsgKey = aMsgKey;
|
||||
UpdateDisplayMessage(aMsgKey);
|
||||
m_currentlyDisplayedMsgKey = m_keys[aViewIndex];
|
||||
m_currentlyDisplayedViewIndex = aViewIndex;
|
||||
UpdateDisplayMessage(aViewIndex);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1061,14 +1085,12 @@ NS_IMETHODIMP nsMsgDBView::SelectionChanged()
|
||||
|
||||
if (startRange >= 0 && startRange == endRange && startRange < GetSize())
|
||||
{
|
||||
// get the msgkey for the message
|
||||
nsMsgKey msgkey = m_keys.GetAt(startRange);
|
||||
if (!mRemovingRow)
|
||||
{
|
||||
if (!mSuppressMsgDisplay)
|
||||
LoadMessageByMsgKey(msgkey);
|
||||
LoadMessageByViewIndex(startRange);
|
||||
else
|
||||
UpdateDisplayMessage(msgkey);
|
||||
UpdateDisplayMessage(startRange);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1857,6 +1879,7 @@ NS_IMETHODIMP nsMsgDBView::GetSuppressCommandUpdating(PRBool * aSuppressCommandU
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::SetSuppressMsgDisplay(PRBool aSuppressDisplay)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRBool forceDisplay = PR_FALSE;
|
||||
if (mSuppressMsgDisplay && (mSuppressMsgDisplay != aSuppressDisplay))
|
||||
forceDisplay = PR_TRUE;
|
||||
@ -1864,19 +1887,14 @@ NS_IMETHODIMP nsMsgDBView::SetSuppressMsgDisplay(PRBool aSuppressDisplay)
|
||||
mSuppressMsgDisplay = aSuppressDisplay;
|
||||
if (forceDisplay)
|
||||
{
|
||||
// get the messae key for the currently selected message
|
||||
nsMsgKey msgKey;
|
||||
nsCOMPtr<nsIMsgDBHdr> dbHdr;
|
||||
GetHdrForFirstSelectedMessage(getter_AddRefs(dbHdr));
|
||||
if (dbHdr)
|
||||
{
|
||||
nsresult rv = dbHdr->GetMessageKey(&msgKey);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
LoadMessageByMsgKey(msgKey);
|
||||
}
|
||||
// get the view indexfor the currently selected message
|
||||
nsMsgViewIndex viewIndex;
|
||||
rv = GetViewIndexForFirstSelectedMsg(&viewIndex);
|
||||
if (NS_SUCCEEDED(rv) && viewIndex != nsMsgViewIndex_None)
|
||||
LoadMessageByViewIndex(viewIndex);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::GetSuppressMsgDisplay(PRBool * aSuppressDisplay)
|
||||
@ -1960,13 +1978,12 @@ NS_IMETHODIMP nsMsgDBView::GetURIForViewIndex(nsMsgViewIndex index, char **resul
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsIMsgFolder> folder = m_folder;
|
||||
if (!folder) {
|
||||
if (!folder)
|
||||
{
|
||||
rv = GetFolderForViewIndex(index, getter_AddRefs(folder));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
rv = GenerateURIForMsgKey(m_keys[index], folder, result);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
return NS_OK;
|
||||
return GenerateURIForMsgKey(m_keys[index], folder, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::DoCommandWithFolder(nsMsgViewCommandTypeValue command, nsIMsgFolder *destFolder)
|
||||
@ -2281,14 +2298,16 @@ nsMsgDBView::ApplyCommandToIndices(nsMsgViewCommandTypeValue command, nsMsgViewI
|
||||
if (numIndices == 0)
|
||||
return NS_OK; // return quietly, just in case
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsresult rv = GetFolderForViewIndex(indices[0], getter_AddRefs(folder));
|
||||
|
||||
if (command == nsMsgViewCommandType::deleteMsg)
|
||||
return DeleteMessages(mMsgWindow, indices, numIndices, PR_FALSE);
|
||||
if (command == nsMsgViewCommandType::deleteNoTrash)
|
||||
return DeleteMessages(mMsgWindow, indices, numIndices, PR_TRUE);
|
||||
|
||||
nsMsgKeyArray imapUids;
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(folder);
|
||||
PRBool thisIsImapFolder = (imapFolder != nsnull);
|
||||
nsCOMPtr<nsIJunkMailPlugin> junkPlugin;
|
||||
|
||||
@ -2302,8 +2321,6 @@ nsMsgDBView::ApplyCommandToIndices(nsMsgViewCommandTypeValue command, nsMsgViewI
|
||||
// more junk status column in the 'search messages' dialog
|
||||
// like in earlier versions...)
|
||||
//
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
rv = GetFolderForViewIndex(indices[0], getter_AddRefs(folder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
@ -2345,7 +2362,7 @@ nsMsgDBView::ApplyCommandToIndices(nsMsgViewCommandTypeValue command, nsMsgViewI
|
||||
mNumMessagesRemainingInBatch += numIndices;
|
||||
}
|
||||
|
||||
m_folder->EnableNotifications(nsIMsgFolder::allMessageCountNotifications, PR_FALSE, PR_TRUE /*dbBatching*/);
|
||||
folder->EnableNotifications(nsIMsgFolder::allMessageCountNotifications, PR_FALSE, PR_TRUE /*dbBatching*/);
|
||||
|
||||
for (int32 i = 0; i < numIndices; i++)
|
||||
{
|
||||
@ -2396,7 +2413,7 @@ nsMsgDBView::ApplyCommandToIndices(nsMsgViewCommandTypeValue command, nsMsgViewI
|
||||
}
|
||||
}
|
||||
|
||||
m_folder->EnableNotifications(nsIMsgFolder::allMessageCountNotifications, PR_TRUE, PR_TRUE /*dbBatching*/);
|
||||
folder->EnableNotifications(nsIMsgFolder::allMessageCountNotifications, PR_TRUE, PR_TRUE /*dbBatching*/);
|
||||
|
||||
if (thisIsImapFolder)
|
||||
{
|
||||
@ -3793,6 +3810,13 @@ NS_IMETHODIMP nsMsgDBView::GetKeyAt(nsMsgViewIndex index, nsMsgKey *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsMsgViewIndex nsMsgDBView::FindHdr(nsIMsgDBHdr *msgHdr)
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
msgHdr->GetMessageKey(&msgKey);
|
||||
return FindViewIndex(msgKey);
|
||||
}
|
||||
|
||||
nsMsgKey nsMsgDBView::GetAt(nsMsgViewIndex index)
|
||||
{
|
||||
if (index >= m_keys.GetSize() || index == nsMsgViewIndex_None)
|
||||
@ -4094,20 +4118,14 @@ nsresult nsMsgDBView::CollapseByIndex(nsMsgViewIndex index, PRUint32 *pNumCollap
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool /*ensureListed*/)
|
||||
nsresult nsMsgDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/)
|
||||
{
|
||||
nsresult rv = NS_MSG_MESSAGE_NOT_FOUND;
|
||||
nsresult rv = NS_OK;
|
||||
// views can override this behaviour, which is to append to view.
|
||||
// This is the mail behaviour, but threaded views will want
|
||||
// to insert in order...
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
NS_ASSERTION(m_db, "m_db is null");
|
||||
if (m_db)
|
||||
rv = m_db->GetMsgHdrForKey(newKey, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
|
||||
{
|
||||
rv = AddHdr(msgHdr);
|
||||
}
|
||||
if (newHdr)
|
||||
rv = AddHdr(newHdr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -4555,13 +4573,15 @@ nsresult nsMsgDBView::ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIn
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags,
|
||||
NS_IMETHODIMP nsMsgDBView::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags,
|
||||
PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
// if we're not the instigator, update flags if this key is in our view
|
||||
if (aInstigator != this)
|
||||
{
|
||||
nsMsgViewIndex index = FindViewIndex(aKeyChanged);
|
||||
nsMsgKey msgKey;
|
||||
aHdrChanged->GetMessageKey(&msgKey);
|
||||
nsMsgViewIndex index = FindViewIndex(msgKey);
|
||||
if (index != nsMsgViewIndex_None)
|
||||
{
|
||||
PRUint32 viewOnlyFlags = m_flags[index] & (MSG_VIEW_FLAGS | MSG_FLAG_ELIDED);
|
||||
@ -4578,30 +4598,30 @@ NS_IMETHODIMP nsMsgDBView::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags,
|
||||
PRUint32 deltaFlags = (aOldFlags ^ aNewFlags);
|
||||
if (deltaFlags & (MSG_FLAG_READ | MSG_FLAG_NEW))
|
||||
{
|
||||
nsMsgViewIndex threadIndex = ThreadIndexOfMsg(aKeyChanged);
|
||||
nsMsgViewIndex threadIndex = ThreadIndexOfMsg(msgKey);
|
||||
// may need to fix thread counts
|
||||
if (threadIndex != nsMsgViewIndex_None && threadIndex != index)
|
||||
NoteChange(threadIndex, 1, nsMsgViewNotificationCode::changed);
|
||||
}
|
||||
}
|
||||
}
|
||||
// don't need to propagate notifications, right?
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::OnKeyDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
NS_IMETHODIMP nsMsgDBView::OnHdrDeleted(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
nsMsgViewIndex deletedIndex = m_keys.FindIndex(aKeyChanged);
|
||||
nsMsgViewIndex deletedIndex = FindHdr(aHdrChanged);
|
||||
if (deletedIndex != nsMsgViewIndex_None)
|
||||
RemoveByIndex(deletedIndex);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::OnKeyAdded(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
NS_IMETHODIMP nsMsgDBView::OnHdrAdded(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
return OnNewHeader(aKeyChanged, aParentKey, PR_FALSE);
|
||||
return OnNewHeader(aHdrChanged, aParentKey, PR_FALSE);
|
||||
// probably also want to pass that parent key in, since we went to the trouble
|
||||
// of figuring out what it is.
|
||||
}
|
||||
@ -5575,14 +5595,12 @@ nsMsgDBView::GetURIForFirstSelectedMessage(char **uri)
|
||||
printf("inside GetURIForFirstSelectedMessage\n");
|
||||
#endif
|
||||
nsresult rv;
|
||||
nsMsgKey key;
|
||||
rv = GetKeyForFirstSelectedMessage(&key);
|
||||
nsMsgViewIndex viewIndex;
|
||||
rv = GetViewIndexForFirstSelectedMsg(&viewIndex);
|
||||
// don't assert, it is legal for nothing to be selected
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = GenerateURIForMsgKey(key, m_folder, uri);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
return NS_OK;
|
||||
return GetURIForViewIndex(viewIndex, uri);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -5640,6 +5658,31 @@ PRBool nsMsgDBView::OfflineMsgSelected(nsMsgViewIndex * indices, PRInt32 numIndi
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::GetViewIndexForFirstSelectedMsg(nsMsgViewIndex *aViewIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aViewIndex);
|
||||
// if we don't have an tree selection we must be in stand alone mode....
|
||||
if (!mTreeSelection)
|
||||
{
|
||||
*aViewIndex = m_currentlyDisplayedViewIndex;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 startRange;
|
||||
PRInt32 endRange;
|
||||
nsresult rv = mTreeSelection->GetRangeAt(0, &startRange, &endRange);
|
||||
// don't assert, it is legal for nothing to be selected
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// check that the first index is valid, it may not be if nothing is selected
|
||||
if (startRange >= 0 && startRange < GetSize())
|
||||
*aViewIndex = startRange;
|
||||
else
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgDBView::GetKeyForFirstSelectedMessage(nsMsgKey *key)
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ protected:
|
||||
virtual PRBool WantsThisThread(nsIMsgThread * thread);
|
||||
virtual nsresult AddHdr(nsIMsgDBHdr *msgHdr);
|
||||
PRBool GetShowingIgnored() {return (m_viewFlags & nsMsgViewFlagsType::kShowIgnored) != 0;}
|
||||
virtual nsresult OnNewHeader(nsMsgKey newKey, nsMsgKey parentKey, PRBool ensureListed);
|
||||
virtual nsresult OnNewHeader(nsIMsgDBHdr *aNewHdr, nsMsgKey parentKey, PRBool ensureListed);
|
||||
virtual nsMsgViewIndex GetInsertIndex(nsIMsgDBHdr *msgHdr);
|
||||
nsMsgViewIndex GetIndexForThread(nsIMsgDBHdr *hdr);
|
||||
virtual nsresult GetThreadContainingIndex(nsMsgViewIndex index, nsIMsgThread **thread);
|
||||
@ -207,9 +207,9 @@ protected:
|
||||
nsMsgViewIndex GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread *threadHdr);
|
||||
nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
|
||||
nsMsgViewIndex ThreadIndexOfMsg(nsMsgKey msgKey,
|
||||
nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
|
||||
PRInt32 *pThreadCount = nsnull,
|
||||
PRUint32 *pFlags = nsnull);
|
||||
nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
|
||||
PRInt32 *pThreadCount = nsnull,
|
||||
PRUint32 *pFlags = nsnull);
|
||||
nsMsgKey GetKeyOfFirstMsgInThread(nsMsgKey key);
|
||||
PRInt32 CountExpandedThread(nsMsgViewIndex index);
|
||||
nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
|
||||
@ -220,6 +220,7 @@ protected:
|
||||
nsMsgKey GetAt(nsMsgViewIndex index) ;
|
||||
nsMsgViewIndex FindViewIndex(nsMsgKey key)
|
||||
{return (nsMsgViewIndex) (m_keys.FindIndex(key));}
|
||||
nsMsgViewIndex FindHdr(nsIMsgDBHdr *msgHdr);
|
||||
virtual nsMsgViewIndex FindKey(nsMsgKey key, PRBool expand);
|
||||
virtual nsresult GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase **db);
|
||||
virtual nsresult GetFolders(nsISupportsArray **folders);
|
||||
@ -305,8 +306,8 @@ protected:
|
||||
void InitializeAtomsAndLiterals();
|
||||
PRInt32 FindLevelInThread(nsIMsgDBHdr *msgHdr, nsMsgViewIndex startOfThread, nsMsgViewIndex viewIndex);
|
||||
nsresult GetImapDeleteModel(nsIMsgFolder *folder);
|
||||
nsresult UpdateDisplayMessage(nsMsgKey aMsgKey);
|
||||
nsresult LoadMessageByMsgKeyHelper(nsMsgKey aMsgKey, PRBool forceAllParts);
|
||||
nsresult UpdateDisplayMessage(nsMsgViewIndex viewPosition);
|
||||
nsresult LoadMessageByViewIndexHelper(nsMsgViewIndex aViewIndex, PRBool forceAllParts);
|
||||
nsresult ReloadMessageHelper(PRBool forceAllParts);
|
||||
|
||||
PRBool AdjustReadFlag(nsIMsgDBHdr *msgHdr, PRUint32 *msgFlags);
|
||||
@ -324,6 +325,8 @@ protected:
|
||||
// we need to store the message key for the message we are currenty displaying to ensure we
|
||||
// don't try to redisplay the same message just because the selection changed (i.e. after a sort)
|
||||
nsMsgKey m_currentlyDisplayedMsgKey;
|
||||
nsCString m_currentlyDisplayedMsgUri;
|
||||
nsMsgViewIndex m_currentlyDisplayedViewIndex;
|
||||
// if we're deleting messages, we want to hold off loading messages on selection changed until the delete is done
|
||||
// and we want to batch notifications.
|
||||
PRPackedBool m_deletingRows;
|
||||
|
@ -89,40 +89,35 @@ NS_IMETHODIMP nsMsgQuickSearchDBView::GetViewType(nsMsgViewTypeValue *aViewType)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgQuickSearchDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed)
|
||||
nsresult nsMsgQuickSearchDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = m_db->GetMsgHdrForKey(newKey, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
|
||||
if (newHdr)
|
||||
{
|
||||
PRBool match=PR_FALSE;
|
||||
nsCOMPtr <nsIMsgSearchSession> searchSession = do_QueryReferent(m_searchSession);
|
||||
if (searchSession)
|
||||
searchSession->MatchHdr(msgHdr, m_db, &match);
|
||||
searchSession->MatchHdr(newHdr, m_db, &match);
|
||||
if (match)
|
||||
AddHdr(msgHdr); // do not add a new message if there isn't a match.
|
||||
AddHdr(newHdr); // do not add a new message if there isn't a match.
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgQuickSearchDBView::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags,
|
||||
NS_IMETHODIMP nsMsgQuickSearchDBView::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags,
|
||||
PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
nsresult rv = nsMsgDBView::OnKeyChange(aKeyChanged, aOldFlags, aNewFlags, aInstigator);
|
||||
nsresult rv = nsMsgDBView::OnHdrChange(aHdrChanged, aOldFlags, aNewFlags, aInstigator);
|
||||
// flags haven't really changed - check if the message is newly classified as junk
|
||||
if ((aOldFlags == aNewFlags) && (aOldFlags & MSG_FLAG_NEW))
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = m_db->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
|
||||
if (aHdrChanged)
|
||||
{
|
||||
nsXPIDLCString junkScoreStr;
|
||||
(void) msgHdr->GetStringProperty("junkscore", getter_Copies(junkScoreStr));
|
||||
(void) aHdrChanged->GetStringProperty("junkscore", getter_Copies(junkScoreStr));
|
||||
if (atoi(junkScoreStr.get()) > 50)
|
||||
{
|
||||
nsXPIDLCString originStr;
|
||||
(void) msgHdr->GetStringProperty("junkscoreorigin",
|
||||
(void) aHdrChanged->GetStringProperty("junkscoreorigin",
|
||||
getter_Copies(originStr));
|
||||
|
||||
// if this was classified by the plugin, see if we're supposed to
|
||||
@ -132,11 +127,11 @@ NS_IMETHODIMP nsMsgQuickSearchDBView::OnKeyChange(nsMsgKey aKeyChanged, PRUint32
|
||||
PRBool match=PR_FALSE;
|
||||
nsCOMPtr <nsIMsgSearchSession> searchSession = do_QueryReferent(m_searchSession);
|
||||
if (searchSession)
|
||||
searchSession->MatchHdr(msgHdr, m_db, &match);
|
||||
searchSession->MatchHdr(aHdrChanged, m_db, &match);
|
||||
if (!match)
|
||||
{
|
||||
// remove hdr from view
|
||||
nsMsgViewIndex deletedIndex = m_keys.FindIndex(aKeyChanged);
|
||||
nsMsgViewIndex deletedIndex = FindHdr(aHdrChanged);
|
||||
if (deletedIndex != nsMsgViewIndex_None)
|
||||
RemoveByIndex(deletedIndex);
|
||||
}
|
||||
|
@ -58,12 +58,12 @@ public:
|
||||
NS_IMETHOD SetSearchSession(nsIMsgSearchSession *aSearchSession);
|
||||
NS_IMETHOD GetSearchSession(nsIMsgSearchSession* *aSearchSession);
|
||||
NS_IMETHOD Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
NS_IMETHOD OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags,
|
||||
NS_IMETHOD OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags,
|
||||
PRUint32 aNewFlags, nsIDBChangeListener *aInstigator);
|
||||
|
||||
protected:
|
||||
nsWeakPtr m_searchSession;
|
||||
virtual nsresult OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed);
|
||||
virtual nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed);
|
||||
void SavePreSearchInfo();
|
||||
void ClearPreSearchInfo();
|
||||
|
||||
|
@ -72,6 +72,7 @@ NS_IMETHODIMP nsMsgSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeVal
|
||||
|
||||
if (pCount)
|
||||
*pCount = 0;
|
||||
m_folder = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -112,7 +113,7 @@ nsresult nsMsgSearchDBView::FetchLocation(PRInt32 aRow, PRUnichar ** aLocationSt
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool /*ensureListed*/)
|
||||
nsresult nsMsgSearchDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
@ -239,8 +240,32 @@ nsMsgSearchDBView::DoCommandWithFolder(nsMsgViewCommandTypeValue command, nsIMsg
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchDBView::DoCommand(nsMsgViewCommandTypeValue command)
|
||||
{
|
||||
mCommand = command;
|
||||
mCommand = command;
|
||||
if (command == nsMsgViewCommandType::deleteMsg || command == nsMsgViewCommandType::deleteNoTrash
|
||||
|| command == nsMsgViewCommandType::selectAll)
|
||||
return nsMsgDBView::DoCommand(command);
|
||||
nsresult rv = NS_OK;
|
||||
nsUInt32Array selection;
|
||||
GetSelectedIndices(&selection);
|
||||
|
||||
nsMsgViewIndex *indices = selection.GetData();
|
||||
PRInt32 numIndices = selection.GetSize();
|
||||
|
||||
// we need to break apart the selection by folders, and then call
|
||||
// ApplyCommandToIndices with the command and the indices in the
|
||||
// selection that are from that folder.
|
||||
|
||||
nsUInt32Array *indexArrays;
|
||||
PRInt32 numArrays;
|
||||
rv = PartitionSelectionByFolder(indices, numIndices, &indexArrays, &numArrays);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (PRInt32 folderIndex = 0; folderIndex < numArrays; folderIndex++)
|
||||
{
|
||||
rv = ApplyCommandToIndices(command, indexArrays[folderIndex].GetData(), indexArrays[folderIndex].GetSize());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// This method just removes the specified line from the view. It does
|
||||
@ -258,7 +283,7 @@ nsresult nsMsgSearchDBView::RemoveByIndex(nsMsgViewIndex index)
|
||||
nsresult nsMsgSearchDBView::DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage)
|
||||
{
|
||||
nsresult rv;
|
||||
InitializeGlobalsForDeleteAndFile(indices, numIndices);
|
||||
GetFoldersAndHdrsForSelection(indices, numIndices);
|
||||
if (mDeleteModel != nsMsgImapDeleteModels::MoveToTrash)
|
||||
deleteStorage = PR_TRUE;
|
||||
if (!deleteStorage)
|
||||
@ -272,7 +297,7 @@ nsresult
|
||||
nsMsgSearchDBView::CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder)
|
||||
{
|
||||
nsresult rv;
|
||||
InitializeGlobalsForDeleteAndFile(indices, numIndices);
|
||||
GetFoldersAndHdrsForSelection(indices, numIndices);
|
||||
|
||||
rv = ProcessRequestsInOneFolder(window);
|
||||
|
||||
@ -280,7 +305,43 @@ nsMsgSearchDBView::CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, P
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PRInt32 numIndices)
|
||||
nsMsgSearchDBView::PartitionSelectionByFolder(nsMsgViewIndex *indices, PRInt32 numIndices, nsUInt32Array **indexArrays, PRInt32 *numArrays)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr <nsISupportsArray> uniqueFoldersSelected = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
mCurIndex = 0;
|
||||
|
||||
//Build unique folder list based on headers selected by the user
|
||||
for (nsMsgViewIndex i = 0; i < (nsMsgViewIndex) numIndices; i++)
|
||||
{
|
||||
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_folders->ElementAt(indices[i]));
|
||||
if ( uniqueFoldersSelected->IndexOf(curSupports) < 0)
|
||||
uniqueFoldersSelected->AppendElement(curSupports);
|
||||
}
|
||||
|
||||
PRUint32 numFolders =0;
|
||||
rv = uniqueFoldersSelected->Count(&numFolders); //group the headers selected by each folder
|
||||
*indexArrays = new nsUInt32Array[numFolders];
|
||||
*numArrays = numFolders;
|
||||
NS_ENSURE_TRUE(*indexArrays, NS_ERROR_OUT_OF_MEMORY);
|
||||
for (PRUint32 folderIndex=0; folderIndex < numFolders; folderIndex++)
|
||||
{
|
||||
nsCOMPtr <nsIMsgFolder> curFolder =
|
||||
do_QueryElementAt(uniqueFoldersSelected, folderIndex, &rv);
|
||||
for (nsMsgViewIndex i = 0; i < (nsMsgViewIndex) numIndices; i++)
|
||||
{
|
||||
nsCOMPtr <nsIMsgFolder> msgFolder = do_QueryElementAt(m_folders,
|
||||
indices[i], &rv);
|
||||
if (NS_SUCCEEDED(rv) && msgFolder && msgFolder == curFolder)
|
||||
(*indexArrays)[folderIndex].Add(indices[i]);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::GetFoldersAndHdrsForSelection(nsMsgViewIndex *indices, PRInt32 numIndices)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mCurIndex = 0;
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
// override to get location
|
||||
NS_IMETHOD GetCellText(PRInt32 aRow, nsITreeColumn* aCol, nsAString& aValue);
|
||||
virtual nsresult GetMsgHdrForViewIndex(nsMsgViewIndex index, nsIMsgDBHdr **msgHdr);
|
||||
virtual nsresult OnNewHeader(nsMsgKey newKey, nsMsgKey parentKey, PRBool ensureListed);
|
||||
virtual nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey parentKey, PRBool ensureListed);
|
||||
NS_IMETHOD GetFolderForViewIndex(nsMsgViewIndex index, nsIMsgFolder **folder);
|
||||
|
||||
virtual nsresult GetFolders(nsISupportsArray **aFolders);
|
||||
@ -76,8 +76,9 @@ protected:
|
||||
virtual nsresult RemoveByIndex(nsMsgViewIndex index);
|
||||
virtual nsresult CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder);
|
||||
virtual nsresult DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage);
|
||||
nsresult InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PRInt32 numIndices);
|
||||
nsresult GetFoldersAndHdrsForSelection(nsMsgViewIndex *indices, PRInt32 numIndices);
|
||||
nsresult GroupSearchResultsByFolder();
|
||||
nsresult PartitionSelectionByFolder(nsMsgViewIndex *indices, PRInt32 numIndices, nsUInt32Array **indexArrays, PRInt32 *numArrays);
|
||||
|
||||
nsCOMPtr <nsISupportsArray> m_folders; // maybe we should store ranges, or the actual headers instead.
|
||||
nsCOMPtr <nsISupportsArray> m_hdrsForEachFolder;
|
||||
|
@ -552,18 +552,19 @@ nsresult nsMsgThreadedDBView::InitSort(nsMsgViewSortTypeValue sortType, nsMsgVie
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed)
|
||||
nsresult nsMsgThreadedDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
nsMsgKey newKey;
|
||||
newHdr->GetMessageKey(&newKey);
|
||||
|
||||
// views can override this behaviour, which is to append to view.
|
||||
// This is the mail behaviour, but threaded views want
|
||||
// to insert in order...
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = m_db->GetMsgHdrForKey(newKey, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
|
||||
if (newHdr)
|
||||
{
|
||||
PRUint32 msgFlags;
|
||||
msgHdr->GetFlags(&msgFlags);
|
||||
newHdr->GetFlags(&msgFlags);
|
||||
if ((m_viewFlags & nsMsgViewFlagsType::kUnreadOnly) && !ensureListed && (msgFlags & MSG_FLAG_READ))
|
||||
return NS_OK;
|
||||
// Currently, we only add the header in a threaded view if it's a thread.
|
||||
@ -572,7 +573,7 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
|
||||
|
||||
// for search view we don't support threaded display so just add it to the view.
|
||||
if (!(m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)) // || msgHdr->GetMessageKey() == m_messageDB->GetKeyOfFirstMsgInThread(msgHdr->GetMessageKey()))
|
||||
rv = AddHdr(msgHdr);
|
||||
rv = AddHdr(newHdr);
|
||||
else // need to find the thread we added this to so we can change the hasnew flag
|
||||
// added message to existing thread, but not to view
|
||||
{ // Fix flags on thread header.
|
||||
@ -585,13 +586,13 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
|
||||
PRUint32 flags = m_flags[threadIndex];
|
||||
// if we have a collapsed thread which just got a new
|
||||
// top of thread, change the keys array.
|
||||
PRInt32 level = FindLevelInThread(msgHdr, threadIndex);
|
||||
PRInt32 level = FindLevelInThread(newHdr, threadIndex);
|
||||
if (((flags & MSG_FLAG_ELIDED) || threadCount == 1)
|
||||
&& (!(m_viewFlags & nsMsgViewFlagsType::kUnreadOnly) || !(msgFlags & MSG_FLAG_READ)))
|
||||
{
|
||||
if (level == 0) {
|
||||
nsMsgKey msgKey;
|
||||
msgHdr->GetMessageKey(&msgKey);
|
||||
newHdr->GetMessageKey(&msgKey);
|
||||
m_keys.SetAt(threadIndex, msgKey);
|
||||
}
|
||||
// note change, to update the parent thread's unread and total counts
|
||||
@ -609,7 +610,7 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
|
||||
{ // insert child into thread
|
||||
// levels of other hdrs may have changed!
|
||||
PRUint32 newFlags = msgFlags;
|
||||
nsMsgViewIndex insertIndex = GetInsertInfoForNewHdr(msgHdr, threadIndex, level);
|
||||
nsMsgViewIndex insertIndex = GetInsertInfoForNewHdr(newHdr, threadIndex, level);
|
||||
// this header is the new king! try collapsing the existing thread,
|
||||
// removing it, installing this header as king, and expanding it.
|
||||
if (level == 0)
|
||||
@ -638,10 +639,10 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
|
||||
else // adding msg to thread that's not in view.
|
||||
{
|
||||
nsCOMPtr <nsIMsgThread> threadHdr;
|
||||
m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(threadHdr));
|
||||
m_db->GetThreadContainingMsgHdr(newHdr, getter_AddRefs(threadHdr));
|
||||
if (threadHdr)
|
||||
{
|
||||
AddMsgToThreadNotInView(threadHdr, msgHdr, ensureListed);
|
||||
AddMsgToThreadNotInView(threadHdr, newHdr, ensureListed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
protected:
|
||||
virtual const char * GetViewName(void) {return "ThreadedDBView"; }
|
||||
nsresult InitThreadedView(PRInt32 *pCount);
|
||||
virtual nsresult OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed);
|
||||
virtual nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed);
|
||||
virtual nsresult AddMsgToThreadNotInView(nsIMsgThread *threadHdr, nsIMsgDBHdr *msgHdr, PRBool ensureListed);
|
||||
nsresult ListThreadIds(nsMsgKey *startMsg, PRBool unreadOnly, nsMsgKey *pOutput, PRInt32 *pFlags, char *pLevels,
|
||||
PRInt32 numToList, PRInt32 *pNumListed, PRInt32 *pTotalHeaders);
|
||||
|
@ -788,15 +788,13 @@ nsMsgDBFolder::OnJunkScoreChanged(nsIDBChangeListener * aInstigator)
|
||||
|
||||
|
||||
// 1. When the status of a message changes.
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags, PRUint32 aNewFlags,
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags, PRUint32 aNewFlags,
|
||||
nsIDBChangeListener * aInstigator)
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> pMsgDBHdr;
|
||||
nsresult rv = mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(pMsgDBHdr));
|
||||
if(NS_SUCCEEDED(rv) && pMsgDBHdr)
|
||||
if(aHdrChanged)
|
||||
{
|
||||
nsCOMPtr<nsISupports> msgSupports(do_QueryInterface(pMsgDBHdr, &rv));
|
||||
if(NS_SUCCEEDED(rv))
|
||||
nsCOMPtr<nsISupports> msgSupports(do_QueryInterface(aHdrChanged));
|
||||
if(msgSupports)
|
||||
SendFlagNotifications(msgSupports, aOldFlags, aNewFlags);
|
||||
UpdateSummaryTotals(PR_TRUE);
|
||||
}
|
||||
@ -839,7 +837,7 @@ nsresult nsMsgDBFolder::CheckWithNewMessagesStatus(PRBool messageAdded)
|
||||
|
||||
// 3. When a message gets deleted, we need to see if it was new
|
||||
// When we lose a new message we need to check if there are still new messages
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnKeyDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnHdrDeleted(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags,
|
||||
nsIDBChangeListener * aInstigator)
|
||||
{
|
||||
// check to see if a new message is being deleted
|
||||
@ -847,31 +845,26 @@ NS_IMETHODIMP nsMsgDBFolder::OnKeyDeleted(nsMsgKey aKeyChanged, nsMsgKey aParen
|
||||
// the folder newness has to be cleared.
|
||||
CheckWithNewMessagesStatus(PR_FALSE);
|
||||
|
||||
return OnKeyAddedOrDeleted(aKeyChanged, PR_FALSE);
|
||||
return OnHdrAddedOrDeleted(aHdrChanged, PR_FALSE);
|
||||
}
|
||||
|
||||
// 2. When a new messages gets added, we need to see if it's new.
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnKeyAdded(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags,
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnHdrAdded(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey , PRInt32 aFlags,
|
||||
nsIDBChangeListener * aInstigator)
|
||||
{
|
||||
if(aFlags & MSG_FLAG_NEW)
|
||||
CheckWithNewMessagesStatus(PR_TRUE);
|
||||
|
||||
return OnKeyAddedOrDeleted(aKeyChanged, PR_TRUE);
|
||||
return OnHdrAddedOrDeleted(aHdrChanged, PR_TRUE);
|
||||
}
|
||||
|
||||
nsresult nsMsgDBFolder::OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, PRBool added)
|
||||
nsresult nsMsgDBFolder::OnHdrAddedOrDeleted(nsIMsgDBHdr *aHdrChanged, PRBool added)
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> msgDBHdr;
|
||||
nsresult rv = mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(msgDBHdr));
|
||||
if(NS_SUCCEEDED(rv) && msgDBHdr)
|
||||
{
|
||||
if(added)
|
||||
NotifyItemAdded(msgDBHdr);
|
||||
else
|
||||
NotifyItemRemoved(msgDBHdr);
|
||||
UpdateSummaryTotals(PR_TRUE);
|
||||
}
|
||||
if(added)
|
||||
NotifyItemAdded(aHdrChanged);
|
||||
else
|
||||
NotifyItemRemoved(aHdrChanged);
|
||||
UpdateSummaryTotals(PR_TRUE);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
@ -880,13 +873,18 @@ nsresult nsMsgDBFolder::OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, PRBool added)
|
||||
NS_IMETHODIMP nsMsgDBFolder::OnParentChanged(nsMsgKey aKeyChanged, nsMsgKey oldParent, nsMsgKey newParent,
|
||||
nsIDBChangeListener * aInstigator)
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> hdrChanged;
|
||||
mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(hdrChanged));
|
||||
//In reality we probably want to just change the parent because otherwise we will lose things like
|
||||
//selection.
|
||||
|
||||
//First delete the child from the old threadParent
|
||||
OnKeyAddedOrDeleted(aKeyChanged, PR_FALSE);
|
||||
//Then add it to the new threadParent
|
||||
OnKeyAddedOrDeleted(aKeyChanged, PR_TRUE);
|
||||
if (hdrChanged)
|
||||
{
|
||||
//First delete the child from the old threadParent
|
||||
OnHdrAddedOrDeleted(hdrChanged, PR_FALSE);
|
||||
//Then add it to the new threadParent
|
||||
OnHdrAddedOrDeleted(hdrChanged, PR_TRUE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ protected:
|
||||
virtual nsresult GetDatabase(nsIMsgWindow *aMsgWindow) = 0;
|
||||
virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags);
|
||||
nsresult CheckWithNewMessagesStatus(PRBool messageAdded);
|
||||
nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, PRBool added);
|
||||
nsresult OnHdrAddedOrDeleted(nsIMsgDBHdr *hdrChanged, PRBool added);
|
||||
nsresult CreateFileSpecForDB(const char *userLeafName, nsFileSpec &baseDir, nsIFileSpec **dbFileSpec);
|
||||
|
||||
nsresult GetFolderCacheKey(nsIFileSpec **aFileSpec);
|
||||
|
@ -93,7 +93,7 @@
|
||||
#include "nsMsgFolderCompactor.h"
|
||||
#include "nsMsgThreadedDBView.h"
|
||||
#include "nsMsgSpecialViews.h"
|
||||
#include "nsMsgSearchDBView.h"
|
||||
#include "nsMsgXFVirtualFolderDBView.h"
|
||||
#include "nsMsgQuickSearchDBView.h"
|
||||
#include "nsMsgOfflineManager.h"
|
||||
#include "nsMsgProgress.h"
|
||||
@ -316,6 +316,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgThreadedDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgThreadsWithUnreadDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgWatchedThreadsWithUnreadDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSearchDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgXFVirtualFolderDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgQuickSearchDBView)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgOfflineManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgProgress)
|
||||
@ -734,6 +735,10 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||
NS_MSGQUICKSEARCHDBVIEW_CONTRACTID,
|
||||
nsMsgQuickSearchDBViewConstructor,
|
||||
},
|
||||
{ "cross folder virtual folder db view", NS_MSG_XFVFDBVIEW_CID,
|
||||
NS_MSGXFVFDBVIEW_CONTRACTID,
|
||||
nsMsgXFVirtualFolderDBViewConstructor,
|
||||
},
|
||||
{ "Messenger Offline Manager", NS_MSGOFFLINEMANAGER_CID,
|
||||
NS_MSGOFFLINEMANAGER_CONTRACTID,
|
||||
nsMsgOfflineManagerConstructor,
|
||||
|
@ -39,19 +39,20 @@
|
||||
#include "MailNewsTypes2.idl"
|
||||
|
||||
interface nsIDBChangeListener;
|
||||
interface nsIMsgDBHdr;
|
||||
|
||||
[scriptable, uuid(2aa6733a-2b36-11d3-a51c-0060b0fc04b7)]
|
||||
[scriptable, uuid(22baf00b-939d-42c3-ac51-21d99dfa1f05)]
|
||||
|
||||
interface nsIDBChangeAnnouncer : nsISupports {
|
||||
/* these 2 calls return NS_OK on success, NS_COMFALSE on failure */
|
||||
void AddListener(in nsIDBChangeListener listener);
|
||||
void RemoveListener(in nsIDBChangeListener listener);
|
||||
|
||||
void NotifyKeyChangeAll(in nsMsgKey keyChanged, in unsigned long aOldFlags, in unsigned long aNewFlags,
|
||||
void NotifyHdrChangeAll(in nsIMsgDBHdr aHdrChanged, in unsigned long aOldFlags, in unsigned long aNewFlags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyKeyAddedAll(in nsMsgKey keyAdded, in nsMsgKey parentKey, in long flags,
|
||||
void NotifyHdrAddedAll(in nsIMsgDBHdr aHdrAdded, in nsMsgKey parentKey, in long flags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyKeyDeletedAll(in nsMsgKey keyDeleted, in nsMsgKey parentKey, in long flags,
|
||||
void NotifyHdrDeletedAll(in nsIMsgDBHdr aHdrDeleted, in nsMsgKey parentKey, in long flags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyParentChangedAll(in nsMsgKey keyReparented, in nsMsgKey oldParent, in nsMsgKey newParent, in nsIDBChangeListener instigator);
|
||||
|
||||
|
@ -39,15 +39,16 @@
|
||||
#include "MailNewsTypes2.idl"
|
||||
|
||||
interface nsIDBChangeAnnouncer;
|
||||
interface nsIMsgDBHdr;
|
||||
|
||||
[scriptable, uuid(ad0f7f90-baff-11d2-8d67-00805f8a6617)]
|
||||
[scriptable, uuid(1d409e71-3b4e-4611-9759-6335c7362f5c)]
|
||||
|
||||
interface nsIDBChangeListener : nsISupports {
|
||||
void onKeyChange(in nsMsgKey aKeyChanged, in unsigned long aOldFlags, in unsigned long aNewFlags,
|
||||
void onHdrChange(in nsIMsgDBHdr aHdrChanged, in unsigned long aOldFlags, in unsigned long aNewFlags,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
void onKeyDeleted(in nsMsgKey aKeyChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
void onHdrDeleted(in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
void onKeyAdded(in nsMsgKey aKeyChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
void onHdrAdded(in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
void onParentChanged (in nsMsgKey aKeyChanged, in nsMsgKey oldParent, in nsMsgKey newParent, in nsIDBChangeListener aInstigator);
|
||||
void onAnnouncerGoingAway(in nsIDBChangeAnnouncer instigator);
|
||||
|
@ -571,7 +571,7 @@ NS_IMETHODIMP nsMsgDatabase::RemoveListener(nsIDBChangeListener *listener)
|
||||
}
|
||||
|
||||
// change announcer methods - just broadcast to all listeners.
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyKeyChangeAll(nsMsgKey keyChanged, PRUint32 oldFlags, PRUint32 newFlags,
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyHdrChangeAll(nsIMsgDBHdr *aHdrChanged, PRUint32 oldFlags, PRUint32 newFlags,
|
||||
nsIDBChangeListener *instigator)
|
||||
{
|
||||
if (!m_ChangeListeners)
|
||||
@ -584,7 +584,7 @@ NS_IMETHODIMP nsMsgDatabase::NotifyKeyChangeAll(nsMsgKey keyChanged, PRUint32 ol
|
||||
nsCOMPtr<nsIDBChangeListener> changeListener;
|
||||
m_ChangeListeners->QueryElementAt(i, NS_GET_IID(nsIDBChangeListener), (void **) getter_AddRefs(changeListener));
|
||||
|
||||
nsresult rv = changeListener->OnKeyChange(keyChanged, oldFlags, newFlags, instigator);
|
||||
nsresult rv = changeListener->OnHdrChange(aHdrChanged, oldFlags, newFlags, instigator);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
@ -627,7 +627,7 @@ NS_IMETHODIMP nsMsgDatabase::NotifyJunkScoreChanged(nsIDBChangeListener *instiga
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyKeyDeletedAll(nsMsgKey keyDeleted, nsMsgKey parentKey, PRInt32 flags,
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyHdrDeletedAll(nsIMsgDBHdr *aHdrDeleted, nsMsgKey parentKey, PRInt32 flags,
|
||||
nsIDBChangeListener *instigator)
|
||||
{
|
||||
if (m_ChangeListeners == nsnull)
|
||||
@ -638,14 +638,14 @@ NS_IMETHODIMP nsMsgDatabase::NotifyKeyDeletedAll(nsMsgKey keyDeleted, nsMsgKey p
|
||||
{
|
||||
nsCOMPtr<nsIDBChangeListener> changeListener;
|
||||
m_ChangeListeners->QueryElementAt(i, NS_GET_IID(nsIDBChangeListener), (void **) getter_AddRefs(changeListener));
|
||||
nsresult rv = changeListener->OnKeyDeleted(keyDeleted, parentKey, flags, instigator);
|
||||
nsresult rv = changeListener->OnHdrDeleted(aHdrDeleted, parentKey, flags, instigator);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyKeyAddedAll(nsMsgKey keyAdded, nsMsgKey parentKey, PRInt32 flags,
|
||||
NS_IMETHODIMP nsMsgDatabase::NotifyHdrAddedAll(nsIMsgDBHdr *aHdrAdded, nsMsgKey parentKey, PRInt32 flags,
|
||||
nsIDBChangeListener *instigator)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu1
|
||||
@ -660,7 +660,7 @@ NS_IMETHODIMP nsMsgDatabase::NotifyKeyAddedAll(nsMsgKey keyAdded, nsMsgKey paren
|
||||
nsCOMPtr<nsIDBChangeListener> changeListener;
|
||||
m_ChangeListeners->QueryElementAt(i, NS_GET_IID(nsIDBChangeListener), (void **) getter_AddRefs(changeListener));
|
||||
|
||||
nsresult rv = changeListener->OnKeyAdded(keyAdded, parentKey, flags, instigator);
|
||||
nsresult rv = changeListener->OnHdrAdded(aHdrAdded, parentKey, flags, instigator);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
@ -1827,7 +1827,7 @@ NS_IMETHODIMP nsMsgDatabase::DeleteHeader(nsIMsgDBHdr *msg, nsIDBChangeListener
|
||||
if (notify /* && NS_SUCCEEDED(ret)*/)
|
||||
{
|
||||
|
||||
NotifyKeyDeletedAll(key, threadParent, flags, instigator); // tell listeners
|
||||
NotifyHdrDeletedAll(msg, threadParent, flags, instigator); // tell listeners
|
||||
}
|
||||
// if (!onlyRemoveFromThread) // to speed up expiration, try this. But really need to do this in RemoveHeaderFromDB
|
||||
nsresult ret = RemoveHeaderFromDB(msgHdr);
|
||||
@ -2016,7 +2016,7 @@ nsresult nsMsgDatabase::MarkHdrReadInDB(nsIMsgDBHdr *msgHdr, PRBool bRead,
|
||||
if (oldFlags == flags)
|
||||
return NS_OK;
|
||||
|
||||
return NotifyKeyChangeAll(key, oldFlags, flags, instigator);
|
||||
return NotifyHdrChangeAll(msgHdr, oldFlags, flags, instigator);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::MarkRead(nsMsgKey key, PRBool bRead,
|
||||
@ -2102,8 +2102,10 @@ nsMsgDatabase::MarkThreadIgnored(nsIMsgThread *thread, nsMsgKey threadKey, PRBoo
|
||||
threadFlags &= ~MSG_FLAG_IGNORED;
|
||||
thread->SetFlags(threadFlags);
|
||||
|
||||
NotifyKeyChangeAll(threadKey, oldThreadFlags, threadFlags, instigator);
|
||||
return NS_OK;
|
||||
nsCOMPtr <nsIMsgDBHdr> msg;
|
||||
nsresult rv = GetMsgHdrForKey(threadKey, getter_AddRefs(msg));
|
||||
|
||||
return NotifyHdrChangeAll(msg, oldThreadFlags, threadFlags, instigator);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2122,9 +2124,12 @@ nsMsgDatabase::MarkThreadWatched(nsIMsgThread *thread, nsMsgKey threadKey, PRBoo
|
||||
else
|
||||
threadFlags &= ~MSG_FLAG_WATCHED;
|
||||
|
||||
NotifyKeyChangeAll(threadKey, oldThreadFlags, threadFlags, instigator);
|
||||
nsCOMPtr <nsIMsgDBHdr> msg;
|
||||
GetMsgHdrForKey(threadKey, getter_AddRefs(msg));
|
||||
|
||||
nsresult rv = NotifyHdrChangeAll(msg, oldThreadFlags, threadFlags, instigator);
|
||||
thread->SetFlags(threadFlags);
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::MarkMarked(nsMsgKey key, PRBool mark,
|
||||
@ -2165,8 +2170,7 @@ NS_IMETHODIMP nsMsgDatabase::SetStringProperty(nsMsgKey aKey, const char *aPrope
|
||||
PRUint32 flags;
|
||||
(void)msgHdr->GetFlags(&flags);
|
||||
|
||||
NotifyKeyChangeAll(aKey, flags, flags, nsnull);
|
||||
return rv;
|
||||
return NotifyHdrChangeAll(msgHdr, flags, flags, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::SetLabel(nsMsgKey key, nsMsgLabelValue label)
|
||||
@ -2262,13 +2266,11 @@ nsresult nsMsgDatabase::SetKeyFlag(nsMsgKey key, PRBool set, PRUint32 flag,
|
||||
if (oldFlags == flags)
|
||||
return NS_OK;
|
||||
|
||||
NotifyKeyChangeAll(key, oldFlags, flags, instigator);
|
||||
return rv;
|
||||
return NotifyHdrChangeAll(msgHdr, oldFlags, flags, instigator);
|
||||
}
|
||||
|
||||
nsresult nsMsgDatabase::SetMsgHdrFlag(nsIMsgDBHdr *msgHdr, PRBool set, PRUint32 flag, nsIDBChangeListener *instigator)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 oldFlags;
|
||||
msgHdr->GetFlags(&oldFlags);
|
||||
|
||||
@ -2280,12 +2282,7 @@ nsresult nsMsgDatabase::SetMsgHdrFlag(nsIMsgDBHdr *msgHdr, PRBool set, PRUint32
|
||||
if (oldFlags == flags)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 key;
|
||||
rv = msgHdr->GetMessageKey(&key);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
NotifyKeyChangeAll(key, oldFlags, flags, instigator);
|
||||
return rv;
|
||||
return NotifyHdrChangeAll(msgHdr, oldFlags, flags, instigator);
|
||||
}
|
||||
|
||||
// Helper routine - lowest level of flag setting - returns PR_TRUE if flags change,
|
||||
@ -2477,13 +2474,11 @@ NS_IMETHODIMP nsMsgDatabase::ClearNewList(PRBool notify /* = FALSE */)
|
||||
err = GetMsgHdrForKey(lastNewKey, getter_AddRefs(msgHdr));
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
nsMsgKey key;
|
||||
(void)msgHdr->GetMessageKey(&key);
|
||||
PRUint32 flags;
|
||||
(void)msgHdr->GetFlags(&flags);
|
||||
|
||||
if ((flags | MSG_FLAG_NEW) != flags)
|
||||
NotifyKeyChangeAll(key, flags | MSG_FLAG_NEW, flags, nsnull);
|
||||
NotifyHdrChangeAll(msgHdr, flags | MSG_FLAG_NEW, flags, nsnull);
|
||||
}
|
||||
if (elementIndex == 0)
|
||||
break;
|
||||
@ -2977,7 +2972,7 @@ NS_IMETHODIMP nsMsgDatabase::AddNewHdrToDB(nsIMsgDBHdr *newHdr, PRBool notify)
|
||||
nsMsgKey threadParent;
|
||||
|
||||
newHdr->GetThreadParent(&threadParent);
|
||||
NotifyKeyAddedAll(key, threadParent, flags, NULL);
|
||||
NotifyHdrAddedAll(newHdr, threadParent, flags, NULL);
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(err), "error creating thread");
|
||||
|
@ -320,14 +320,61 @@ nsShouldIgnoreFile(nsString& name)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// this is only called for virtual folders, currently.
|
||||
NS_IMETHODIMP nsImapMailFolder::AddSubfolder(const nsAString& aName,
|
||||
nsIMsgFolder** aChild)
|
||||
{
|
||||
nsresult rv = nsMsgDBFolder::AddSubfolder(aName, aChild);
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
PRInt32 flags = 0;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFService> rdf = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCAutoString uri(mURI);
|
||||
uri.Append('/');
|
||||
|
||||
// convert name to imap modified utf7, like an imap server would
|
||||
nsCAutoString utfFolderName;
|
||||
rv = CopyUTF16toMUTF7(PromiseFlatString(aName), utfFolderName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uri += utfFolderName.get();
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> msgFolder;
|
||||
rv = GetChildWithURI(uri.get(), PR_FALSE/*deep*/, PR_TRUE /*case Insensitive*/, getter_AddRefs(msgFolder));
|
||||
if (NS_SUCCEEDED(rv) && msgFolder)
|
||||
return NS_MSG_FOLDER_EXISTS;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> res;
|
||||
rv = rdf->GetResource(uri, getter_AddRefs(res));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(res, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
folder->GetFlags((PRUint32 *)&flags);
|
||||
|
||||
flags |= MSG_FOLDER_FLAG_MAIL;
|
||||
|
||||
folder->SetParent(this);
|
||||
|
||||
folder->SetFlags(flags);
|
||||
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(folder);
|
||||
if(folder)
|
||||
mSubFolders->AppendElement(supports);
|
||||
NS_ADDREF(*aChild = folder);
|
||||
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapChild = do_QueryInterface(*aChild);
|
||||
if (imapChild)
|
||||
{
|
||||
NS_LossyConvertUTF16toASCII folderCName(aName);
|
||||
imapChild->SetOnlineName(folderCName.get());
|
||||
imapChild->SetHierarchyDelimiter(m_hierarchyDelimiter);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -172,20 +172,17 @@ NS_IMETHODIMP nsMsgMailboxParser::OnStopRequest(nsIRequest *request, nsISupports
|
||||
|
||||
|
||||
|
||||
/* void OnKeyChange (in nsMsgKey aKeyChanged, in unsigned long aOldFlags, in unsigned long aNewFlags, in nsIDBChangeListener aInstigator); */
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlags, PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags, PRUint32 aNewFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void OnKeyDeleted (in nsMsgKey aKeyChanged, in nsMsgKey aParentKey, in long aFlags, in nsIDBChangeListener aInstigator); */
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnKeyDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnHdrDeleted(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void OnKeyAdded (in nsMsgKey aKeyChanged, in nsMsgKey aParentKey, in long aFlags, in nsIDBChangeListener aInstigator); */
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnKeyAdded(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
NS_IMETHODIMP nsMsgMailboxParser::OnHdrAdded(nsIMsgDBHdr *aHdrAdded, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user