diff --git a/mozilla/mailnews/base/resources/content/msgHdrViewOverlay.js b/mozilla/mailnews/base/resources/content/msgHdrViewOverlay.js index 9cbf7ab2ef2..516b68fdcec 100644 --- a/mozilla/mailnews/base/resources/content/msgHdrViewOverlay.js +++ b/mozilla/mailnews/base/resources/content/msgHdrViewOverlay.js @@ -255,7 +255,7 @@ function OnUnloadMsgHeaderPane() var messageHeaderSink = { onStartHeaders: function() { - + mSaveHdr = null; // clear out any pending collected address timers... if (gCollectAddressTimer) { @@ -374,6 +374,20 @@ var messageHeaderSink = { handleAttachment: function(contentType, url, displayName, uri, notDownloaded) { + // presentation level change....don't show vcards as external attachments in the UI. + // libmime already renders them inline. + + if (contentType == "text/x-vcard") + { + var inlineAttachments = pref.getBoolPref("mail.inline_attachments"); + var displayHtmlAs = pref.getIntPref("mailnews.display.html_as"); + if (inlineAttachments && !displayHtmlAs) + { + mSaveHdr = messenger.messageServiceFromURI(uri).messageURIToMsgHdr(uri); + return; + } + } + currentAttachments.push (new createNewAttachmentInfo(contentType, url, displayName, uri, notDownloaded)); // if we have an attachment, set the MSG_FLAG_ATTACH flag on the hdr // this will cause the "message with attachment" icon to show up @@ -399,6 +413,11 @@ var messageHeaderSink = { onEndAllAttachments: function() { + // if we only got a v-card, turn off the attachments flag + if (!currentAttachments.length && mSaveHdr) + mSaveHdr.markHasAttachments(false); + mSaveHdr = null; + displayAttachmentsForExpandedView(); // AddSaveAllAttachmentsMenu(); if (gCollapsedHeaderViewMode) displayAttachmentsForCollapsedView(); @@ -420,6 +439,7 @@ var messageHeaderSink = { }, mSecurityInfo : null, + mSaveHdr: null, getSecurityInfo: function() { return this.mSecurityInfo; diff --git a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp index e91814fd1da..71d3782409a 100644 --- a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -115,7 +115,7 @@ nsMsgDBService::~nsMsgDBService() { } -NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder, PRBool aCreate, PRBool aUpgrading, nsIMsgDatabase **_retval) +NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder, PRBool aCreate, PRBool aLeaveInvalidDB, nsIMsgDatabase **_retval) { NS_ENSURE_ARG(aFolder); *_retval = nsMsgDatabase::FindInCache(aFolder); @@ -134,7 +134,7 @@ NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder, PRBool aCreate nsCOMPtr folderPath; rv = aFolder->GetPath(getter_AddRefs(folderPath)); NS_ENSURE_SUCCESS(rv, rv); - rv = msgDB->Open(folderPath, aCreate, aUpgrading); + rv = msgDB->Open(folderPath, aCreate, aLeaveInvalidDB); if (NS_FAILED(rv) && (rv != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING && rv != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE || !aCreate)) return rv; @@ -167,7 +167,7 @@ NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder, PRBool aCreate return rv; } -NS_IMETHODIMP nsMsgDBService::OpenMailDBFromFileSpec(nsIFileSpec *aFolderName, PRBool aCreate, PRBool aUpgrading, nsIMsgDatabase** pMessageDB) +NS_IMETHODIMP nsMsgDBService::OpenMailDBFromFileSpec(nsIFileSpec *aFolderName, PRBool aCreate, PRBool aLeaveInvalidDB, nsIMsgDatabase** pMessageDB) { nsFileSpec folderName; @@ -184,7 +184,7 @@ NS_IMETHODIMP nsMsgDBService::OpenMailDBFromFileSpec(nsIFileSpec *aFolderName, P nsresult rv; nsCOMPtr msgDB = do_CreateInstance(NS_MAILBOXDB_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - rv = msgDB->Open(aFolderName, aCreate, aUpgrading); + rv = msgDB->Open(aFolderName, aCreate, aLeaveInvalidDB); NS_IF_ADDREF(*pMessageDB = msgDB); if (aCreate && msgDB && rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING) rv = NS_OK; @@ -1055,10 +1055,10 @@ void nsMsgDatabase::UnixToNative(char*& ioPath) #endif /* XP_MAC */ -// caller passes in upgrading==PR_TRUE if they want back a db even if the db is out of date. +// caller passes in leaveInvalidDB==PR_TRUE if they want back a db even if the db is out of date. // If so, they'll extract out the interesting info from the db, close it, delete it, and // then try to open the db again, prior to reparsing. -NS_IMETHODIMP nsMsgDatabase::Open(nsIFileSpec *aFolderName, PRBool aCreate, PRBool aUpgrading) +NS_IMETHODIMP nsMsgDatabase::Open(nsIFileSpec *aFolderName, PRBool aCreate, PRBool aLeaveInvalidDB) { PRBool summaryFileExists; PRBool newFile = PR_FALSE; @@ -1075,7 +1075,7 @@ NS_IMETHODIMP nsMsgDatabase::Open(nsIFileSpec *aFolderName, PRBool aCreate, PRBo #if defined(DEBUG_bienvenu) printf("really opening db in nsImapMailDatabase::Open(%s, %s, %p, %s) -> %s\n", (const char*)folderName, aCreate ? "TRUE":"FALSE", - this, aUpgrading ? "TRUE":"FALSE", (const char*)folderName); + this, aLeaveInvalidDB ? "TRUE":"FALSE", (const char*)folderName); #endif // if the old summary doesn't exist, we're creating a new one. if ((!summarySpec.Exists() || !summarySpec.GetFileSize()) && aCreate) @@ -1113,7 +1113,7 @@ NS_IMETHODIMP nsMsgDatabase::Open(nsIFileSpec *aFolderName, PRBool aCreate, PRBo err = NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE; NS_RELEASE(folderInfo); } - if (NS_FAILED(err) && !aUpgrading) + if (NS_FAILED(err) && !aLeaveInvalidDB) deleteInvalidDB = PR_TRUE; } else @@ -1134,11 +1134,11 @@ NS_IMETHODIMP nsMsgDatabase::Open(nsIFileSpec *aFolderName, PRBool aCreate, PRBo { // if we couldn't open file, or we have a blank one, and we're supposed // to upgrade, updgrade it. - if (newFile && !aUpgrading) // caller is upgrading, and we have empty summary file, + if (newFile && !aLeaveInvalidDB) // caller is upgrading, and we have empty summary file, { // leave db around and open so caller can upgrade it. err = NS_MSG_ERROR_FOLDER_SUMMARY_MISSING; } - else if (err != NS_OK) + else if (err != NS_OK && err != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE) { Close(PR_FALSE); summarySpec.Delete(PR_FALSE); // blow away the db if it's corrupt. diff --git a/mozilla/mailnews/local/public/nsIMsgLocalMailFolder.idl b/mozilla/mailnews/local/public/nsIMsgLocalMailFolder.idl index e5a62f3c639..ac8caaefb92 100644 --- a/mozilla/mailnews/local/public/nsIMsgLocalMailFolder.idl +++ b/mozilla/mailnews/local/public/nsIMsgLocalMailFolder.idl @@ -57,7 +57,7 @@ struct nsLocalFolderScanState; %} -[scriptable, uuid(b8e26003-f2bb-4239-ba47-d597ab6e3671)] +[scriptable, uuid(94bf4be7-4af2-462b-a7cc-c4298c335829)] interface nsIMsgLocalMailFolder : nsISupports { /** * set the default flags on the subfolders of this folder, such as @@ -67,7 +67,17 @@ interface nsIMsgLocalMailFolder : nsISupports { * like MSG_FOLDER_FLAG_INBOX | MSG_FOLDER_FLAG_DRAFTS | etc */ void setFlagsOnDefaultMailboxes(in unsigned long flags); + + /* + * This will return null if the db is out of date + */ nsIMsgDatabase getDatabaseWOReparse(); + + /* + * This will kick off a url to reparse the db if it's out of date. + * If aReparseUrlListener isn ull, folder will use itself as the listener + */ + nsIMsgDatabase getDatabaseWithReparse(in nsIUrlListener aReparseUrlListener, in nsIMsgWindow aMsgWindow); void parseFolder(in nsIMsgWindow aMsgWindow, in nsIUrlListener listener); void copyFolderLocal(in nsIMsgFolder srcFolder, in boolean isMove, in nsIMsgWindow msgWindow, in nsIMsgCopyServiceListener listener ); void copyAllSubFolders(in nsIMsgFolder srcFolder, in nsIMsgWindow msgWindow, in nsIMsgCopyServiceListener listener ); diff --git a/mozilla/mailnews/local/src/nsLocalMailFolder.cpp b/mozilla/mailnews/local/src/nsLocalMailFolder.cpp index 1d90b56995c..d209e4bffe7 100644 --- a/mozilla/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mozilla/mailnews/local/src/nsLocalMailFolder.cpp @@ -338,31 +338,15 @@ NS_IMETHODIMP nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsIUrl return rv; } -//we treat failure as null db returned -NS_IMETHODIMP nsMsgLocalMailFolder::GetDatabaseWOReparse(nsIMsgDatabase **aDatabase) +// this won't force a reparse of the folder if the db is invalid. +NS_IMETHODIMP +nsMsgLocalMailFolder::GetMsgDatabase(nsIMsgWindow *aMsgWindow, + nsIMsgDatabase** aMsgDatabase) { - nsresult rv=NS_OK; - NS_ENSURE_ARG(aDatabase); - if (!mDatabase) - { - nsCOMPtr destIFolderSpec; - rv = GetPath(getter_AddRefs(destIFolderSpec)); - - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv) && msgDBService) - { - rv = msgDBService->OpenFolderDB(this, PR_FALSE, PR_FALSE, (nsIMsgDatabase **) getter_AddRefs(mDatabase)); - if (mDatabase && NS_SUCCEEDED(rv)) - mDatabase->AddListener(this); - } - } - *aDatabase = mDatabase; - NS_IF_ADDREF(*aDatabase); - return rv; + return GetDatabaseWOReparse(aMsgDatabase); } + NS_IMETHODIMP nsMsgLocalMailFolder::Enumerate(nsIEnumerator* *result) { @@ -477,12 +461,55 @@ nsMsgLocalMailFolder::GetSubFolders(nsIEnumerator* *result) return rv; } - -//Makes sure the database is open and exists. If the database is valid then -//returns NS_OK. Otherwise returns a failure error value. nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow) +{ + return GetDatabaseWOReparse(getter_AddRefs(mDatabase)); +} + +//we treat failure as null db returned +NS_IMETHODIMP nsMsgLocalMailFolder::GetDatabaseWOReparse(nsIMsgDatabase **aDatabase) +{ + nsresult rv=NS_OK; + if (m_parsingFolder) + return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE; + + NS_ENSURE_ARG(aDatabase); + if (!mDatabase) + { + nsCOMPtr destIFolderSpec; + rv = GetPath(getter_AddRefs(destIFolderSpec)); + + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && msgDBService) + { + rv = msgDBService->OpenFolderDB(this, PR_FALSE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(mDatabase)); + if (mDatabase && NS_SUCCEEDED(rv)) + mDatabase->AddListener(this); + } + } + *aDatabase = mDatabase; + NS_IF_ADDREF(*aDatabase); + return rv; +} + + +// Makes sure the database is open and exists. If the database is out of date, +// then this call will run an async url to reparse the folder. The passed in +// url listener will get called when the url is done. +NS_IMETHODIMP nsMsgLocalMailFolder::GetDatabaseWithReparse(nsIUrlListener *aReparseUrlListener, nsIMsgWindow *aMsgWindow, + nsIMsgDatabase **aMsgDatabase) { nsresult rv = NS_OK; + // if we're already reparsing, just remember the listener so we can notify it + // when we've finished. + if (m_parsingFolder) + { + NS_ASSERTION(!mReparseListener, "can't have an existing listener"); + mReparseListener = aReparseUrlListener; + return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE; + } if (!mDatabase) { nsCOMPtr pathSpec; @@ -548,7 +575,7 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow) if(folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING || folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE) { - if(NS_FAILED(rv = ParseFolder(aMsgWindow, this))) + if(NS_FAILED(rv = ParseFolder(aMsgWindow, (aReparseUrlListener) ? aReparseUrlListener : this))) { if (rv == NS_MSG_FOLDER_BUSY) { @@ -568,6 +595,7 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow) } } } + NS_IF_ADDREF(*aMsgDatabase = mDatabase); return rv; } @@ -616,7 +644,7 @@ nsMsgLocalMailFolder::UpdateFolder(nsIMsgWindow *aWindow) //If we don't currently have a database, get it. Otherwise, the folder has been updated (presumably this //changes when we download headers when opening inbox). If it's updated, send NotifyFolderLoaded. if(!mDatabase) - rv = GetDatabase(aWindow); // this will cause a reparse, if needed. + rv = GetDatabaseWithReparse(this, aWindow, getter_AddRefs(mDatabase)); else { PRBool valid; @@ -644,7 +672,7 @@ nsMsgLocalMailFolder::UpdateFolder(nsIMsgWindow *aWindow) NS_IMETHODIMP nsMsgLocalMailFolder::GetMessages(nsIMsgWindow *aMsgWindow, nsISimpleEnumerator* *result) { - nsresult rv = GetDatabase(aMsgWindow); + nsresult rv = GetDatabaseWOReparse(getter_AddRefs(mDatabase)); if(NS_SUCCEEDED(rv)) return mDatabase->EnumerateMessages(result); @@ -1450,7 +1478,7 @@ nsMsgLocalMailFolder::DeleteMessages(nsISupportsArray *messages, } else { - rv = GetDatabase(msgWindow); + rv = GetDatabaseWOReparse(getter_AddRefs(mDatabase)); if(NS_SUCCEEDED(rv)) { nsCOMPtr msgSupport; @@ -1497,7 +1525,7 @@ nsMsgLocalMailFolder::InitCopyState(nsISupports* aSupport, return NS_ERROR_FAILURE; // already has a copy in progress // get mDatabase set, so we can use it to add new hdrs to this db. - // calling GetDatabaseWOReparse will set mDatabase - we use the comptr + // calling GetDatabase will set mDatabase - we use the comptr // here to avoid doubling the refcnt on mDatabase. We don't care if this // fails - we just want to give it a chance. It will definitely fail in // nsLocalMailFolder::EndCopy because we will have written data to the folder @@ -1888,6 +1916,12 @@ nsMsgLocalMailFolder::CopyFolderLocal(nsIMsgFolder *srcFolder, PRBool isMoveFold srcFolder->GetName(getter_Copies(folderName)); nsAutoString safeFolderName(folderName); NS_MsgHashIfNecessary(safeFolderName); + nsCOMPtr localFolder = do_QueryInterface(srcFolder); + nsCOMPtr srcDB; + if (localFolder) + localFolder->GetDatabaseWOReparse(getter_AddRefs(srcDB)); + PRBool summaryValid = (srcDB != nsnull); + srcDB = nsnull; srcFolder->ForceDBClosed(); nsCOMPtr oldPathSpec; @@ -1926,6 +1960,25 @@ nsMsgLocalMailFolder::CopyFolderLocal(nsIMsgFolder *srcFolder, PRBool isMoveFold rv = summarySpec.CopyToDir(newPath); NS_ENSURE_SUCCESS(rv, rv); + // linux and mac are not good about maintaining the file stamp when copying folders + // around. So if the source folder db is good, set the dest db as good too. + nsCOMPtr destDB; + if (summaryValid) + { + nsCAutoString folderLeafName; + folderLeafName.Adopt(path.GetLeafName()); + newPath += folderLeafName.get(); + nsCOMPtr msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && msgDBService) + { + nsCOMPtr dbFileSpec; + NS_NewFileSpecWithSpec(newPath, getter_AddRefs(dbFileSpec)); + rv = msgDBService->OpenMailDBFromFileSpec(dbFileSpec, PR_FALSE, PR_TRUE, getter_AddRefs(destDB)); + if ((NS_SUCCEEDED(rv) || rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE) && destDB) + destDB->SetSummaryValid(PR_TRUE); +// destDB->Close(PR_TRUE); + } + } rv = AddSubfolder(safeFolderName, getter_AddRefs(newMsgFolder)); NS_ENSURE_SUCCESS(rv, rv); @@ -2103,7 +2156,8 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetNewMessages(nsIMsgWindow *aWindow, nsIUrl { PRBool valid = PR_FALSE; nsCOMPtr db; - rv = inbox->GetMsgDatabase(aWindow, getter_AddRefs(db)); + // this will kick off a reparse if the db is out of date. + rv = localInbox->GetDatabaseWithReparse(nsnull, aWindow, getter_AddRefs(db)); if (NS_SUCCEEDED(rv) && db) { rv = db->GetSummaryValid(&valid); @@ -3191,6 +3245,11 @@ nsMsgLocalMailFolder::OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode) } } + if (m_parsingFolder && mReparseListener) + { + mReparseListener->OnStopRunningUrl(aUrl, aExitCode); + mReparseListener = nsnull; + } m_parsingFolder = PR_FALSE; return nsMsgDBFolder::OnStopRunningUrl(aUrl, aExitCode); } diff --git a/mozilla/mailnews/local/src/nsLocalMailFolder.h b/mozilla/mailnews/local/src/nsLocalMailFolder.h index 149bd15fad2..1419e9a1357 100644 --- a/mozilla/mailnews/local/src/nsLocalMailFolder.h +++ b/mozilla/mailnews/local/src/nsLocalMailFolder.h @@ -138,6 +138,8 @@ public: // nsIMsgFolder methods: NS_IMETHOD GetSubFolders(nsIEnumerator* *result); + NS_IMETHODIMP GetMsgDatabase(nsIMsgWindow *aMsgWindow, + nsIMsgDatabase** aMsgDatabase); NS_IMETHOD GetMessages(nsIMsgWindow *aMsgWindow, nsISimpleEnumerator* *result); NS_IMETHOD UpdateFolder(nsIMsgWindow *aWindow); @@ -199,7 +201,6 @@ protected: nsresult CopyFolderAcrossServer(nsIMsgFolder *srcFolder, nsIMsgWindow *msgWindow,nsIMsgCopyServiceListener* listener); nsresult CreateSubFolders(nsFileSpec &path); - nsresult GetDatabase(nsIMsgWindow *aMsgWindow); nsresult GetTrashFolder(nsIMsgFolder** trashFolder); nsresult WriteStartOfNewMessage(); nsresult IsChildOfTrash(PRBool *result); @@ -208,6 +209,7 @@ protected: nsresult DeleteMessage(nsISupports *message, nsIMsgWindow *msgWindow, PRBool deleteStorage, PRBool commit); + nsresult GetDatabase(nsIMsgWindow *msgWindow); // copy message helper nsresult DisplayMoveCopyStatusMsg(); @@ -235,6 +237,7 @@ protected: PRPackedBool mCheckForNewMessagesAfterParsing; PRPackedBool m_parsingFolder; nsCOMPtr mMsgStringService; + nsCOMPtr mReparseListener; PRInt32 mNumFilterClassifyRequests; nsMsgKeyArray mSpamKeysToMove; nsCString mSpamFolderURI; diff --git a/mozilla/mailnews/local/src/nsPop3IncomingServer.cpp b/mozilla/mailnews/local/src/nsPop3IncomingServer.cpp index c542d6dc1fa..03747cf398e 100644 --- a/mozilla/mailnews/local/src/nsPop3IncomingServer.cpp +++ b/mozilla/mailnews/local/src/nsPop3IncomingServer.cpp @@ -302,19 +302,15 @@ nsresult nsPop3IncomingServer::GetInbox(nsIMsgWindow *msgWindow, nsIMsgFolder ** nsCOMPtr localInbox = do_QueryInterface(*inbox, &rv); if (NS_SUCCEEDED(rv) && localInbox) { - PRBool valid = PR_FALSE; nsCOMPtr db; rv = (*inbox)->GetMsgDatabase(msgWindow, getter_AddRefs(db)); - if (NS_SUCCEEDED(rv) && db) + if (NS_FAILED(rv)) { - rv = db->GetSummaryValid(&valid); - if (!valid) - { - (*inbox)->SetMsgDatabase(nsnull); - (void) localInbox->SetCheckForNewMessagesAfterParsing(PR_TRUE); - (*inbox)->GetMsgDatabase(msgWindow, getter_AddRefs(db)); - return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE; - } + (*inbox)->SetMsgDatabase(nsnull); + (void) localInbox->SetCheckForNewMessagesAfterParsing(PR_TRUE); + // this will cause a reparse of the mail folder. + localInbox->GetDatabaseWithReparse(nsnull, msgWindow, getter_AddRefs(db)); + return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE; } } return rv; @@ -631,6 +627,18 @@ nsresult nsPop3GetMailChainer::GetNewMailForServers(nsISupportsArray *servers, n m_folderToDownloadTo = folderToDownloadTo; m_downloadingMsgWindow = msgWindow; m_listener = listener; + nsCOMPtr destFolderDB; + + nsresult rv = folderToDownloadTo->GetMsgDatabase(msgWindow, getter_AddRefs(destFolderDB)); + if (NS_FAILED(rv) || !destFolderDB) + { + nsCOMPtr localFolder = do_QueryInterface(folderToDownloadTo); + if (localFolder) + { + localFolder->GetDatabaseWithReparse(this, msgWindow, getter_AddRefs(destFolderDB)); + return NS_OK; + } + } return RunNextGetNewMail(); }