From 4df4737cd387671743abbacd9f121a15a489aaa7 Mon Sep 17 00:00:00 2001 From: "naving%netscape.com" Date: Wed, 12 Dec 2001 01:19:57 +0000 Subject: [PATCH] 110205 r=nhotta sr=bienvenu. Add support for sorting folders in folder-pane based on collation key (order+name) git-svn-id: svn://10.0.0.236/trunk@110327 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/base/public/nsIMsgFolder.idl | 7 +- .../base/src/nsMsgFolderDataSource.cpp | 19 +--- mozilla/mailnews/base/util/nsMsgFolder.cpp | 103 +++++++++++++++--- mozilla/mailnews/base/util/nsMsgFolder.h | 11 +- 4 files changed, 103 insertions(+), 37 deletions(-) diff --git a/mozilla/mailnews/base/public/nsIMsgFolder.idl b/mozilla/mailnews/base/public/nsIMsgFolder.idl index 0c243fb67f7..8fc5592ce92 100644 --- a/mozilla/mailnews/base/public/nsIMsgFolder.idl +++ b/mozilla/mailnews/base/public/nsIMsgFolder.idl @@ -246,8 +246,9 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne */ readonly attribute boolean manyHeadersToDownload; - readonly attribute boolean requiresCleanup; - void clearRequiresCleanup(); + readonly attribute boolean requiresCleanup; + void clearRequiresCleanup(); + /** * this should go into a news-specific interface @@ -397,6 +398,8 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne */ attribute long sortOrder; + readonly attribute wstring sortKey; + /** * used to determine if we persist the close / open state of this folder or not */ diff --git a/mozilla/mailnews/base/src/nsMsgFolderDataSource.cpp b/mozilla/mailnews/base/src/nsMsgFolderDataSource.cpp index 57dbc343641..4f15258d5be 100644 --- a/mozilla/mailnews/base/src/nsMsgFolderDataSource.cpp +++ b/mozilla/mailnews/base/src/nsMsgFolderDataSource.cpp @@ -1056,22 +1056,9 @@ nsMsgFolderDataSource::createFolderNameNode(nsIMsgFolder *folder, if (NS_FAILED(rv)) return rv; if (sort) { - // to create the sort string, we get the sort order - // append the name, and make the whole thing lower case - // because we want AAA to be next to aaa. - PRInt32 order; - rv = folder->GetSortOrder(&order); - NS_ENSURE_SUCCESS(rv,rv); - - nsAutoString orderString; - orderString.AppendInt(order); - - orderString.Append(name.get()); - - // make sort insensitive to case - orderString.ToLowerCase(); - - createNode(orderString.get(), target, getRDFService()); + nsXPIDLString sortKey; + folder->GetSortKey(getter_Copies(sortKey)); + createNode(sortKey.get(), target, getRDFService()); } else { createNode(name.get(), target, getRDFService()); diff --git a/mozilla/mailnews/base/util/nsMsgFolder.cpp b/mozilla/mailnews/base/util/nsMsgFolder.cpp index eae26ce7366..d0cf10f5b42 100644 --- a/mozilla/mailnews/base/util/nsMsgFolder.cpp +++ b/mozilla/mailnews/base/util/nsMsgFolder.cpp @@ -75,6 +75,9 @@ #include "nsIPrompt.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" +#include "nsILocale.h" +#include "nsILocaleService.h" +#include "nsCollationCID.h" #define PREF_MAIL_WARN_FILTER_CHANGED "mail.warn_filter_changed" @@ -83,6 +86,7 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kMsgFolderListenerManagerCID, NS_MSGMAILSESSION_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); +static NS_DEFINE_CID(kCollationFactoryCID, NS_COLLATIONFACTORY_CID); nsrefcnt nsMsgFolder::gInstanceCount = 0; @@ -103,6 +107,7 @@ nsIAtom * nsMsgFolder::kStatusAtom = nsnull; nsIAtom * nsMsgFolder::kNameAtom = nsnull; nsIAtom * nsMsgFolder::kSynchronizeAtom = nsnull; nsIAtom * nsMsgFolder::kOpenAtom = nsnull; +nsICollation * nsMsgFolder::kCollationKeyGenerator = nsnull; #ifdef MSG_FASTER_URI_PARSING nsCOMPtr nsMsgFolder::mParsingURL; @@ -149,7 +154,7 @@ nsMsgFolder::nsMsgFolder(void) kOpenAtom = NS_NewAtom("open"); initializeStrings(); - + createCollationKeyGenerator(); #ifdef MSG_FASTER_URI_PARSING mParsingURL = do_CreateInstance(kStandardUrlCID); #endif @@ -189,14 +194,13 @@ nsMsgFolder::~nsMsgFolder(void) NS_IF_RELEASE(kNameAtom); NS_IF_RELEASE(kSynchronizeAtom); NS_IF_RELEASE(kOpenAtom); - + NS_IF_RELEASE(kCollationKeyGenerator); CRTFREEIF(kInboxName); CRTFREEIF(kTrashName); CRTFREEIF(kSentName); CRTFREEIF(kDraftsName); CRTFREEIF(kTemplatesName); CRTFREEIF(kUnsentName); - #ifdef MSG_FASTER_URI_PARSING mParsingURL = nsnull; #endif @@ -235,7 +239,26 @@ nsMsgFolder::initializeStrings() &kUnsentName); return NS_OK; } - + +nsresult +nsMsgFolder::createCollationKeyGenerator() +{ + nsresult rv = NS_OK; + + nsCOMPtr localeSvc = do_GetService(NS_LOCALESERVICE_CONTRACTID,&rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr locale; + rv = localeSvc->GetApplicationLocale(getter_AddRefs(locale)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr factory = do_CreateInstance(kCollationFactoryCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = factory->CreateCollation(locale, &kCollationKeyGenerator); + return NS_OK; + +} NS_IMETHODIMP nsMsgFolder::Init(const char* aURI) { @@ -1596,9 +1619,9 @@ NS_IMETHODIMP nsMsgFolder::OnFlagChange(PRUint32 flag) if (NS_SUCCEEDED(rv) && folderInfo) { #ifdef DEBUG_bienvenu - nsXPIDLString name; - rv = GetName(getter_Copies(name)); - NS_ASSERTION(Compare(name, NS_LITERAL_STRING("Trash")) || (mFlags & MSG_FOLDER_FLAG_TRASH), "lost trash flag"); + nsXPIDLString name; + rv = GetName(getter_Copies(name)); + NS_ASSERTION(Compare(name, NS_LITERAL_STRING("Trash")) || (mFlags & MSG_FOLDER_FLAG_TRASH), "lost trash flag"); #endif folderInfo->SetFlags((PRInt32) mFlags); if (db) @@ -1624,7 +1647,7 @@ NS_IMETHODIMP nsMsgFolder::SetFlags(PRUint32 aFlags) if (mFlags != aFlags) { mFlags = aFlags; - OnFlagChange(mFlags); + OnFlagChange(mFlags); } return NS_OK; } @@ -1713,7 +1736,6 @@ NS_IMETHODIMP nsMsgFolder::GetExpansionArray(nsISupportsArray *expansionArray) return NS_OK; } - #ifdef HAVE_PANE NS_IMETHODIMP nsMsgFolder::SetFlagInAllFolderPanes(PRUInt32 which) { @@ -1750,16 +1772,15 @@ NS_IMETHODIMP nsMsgFolder::GetDeletable(PRBool *deletable) NS_IMETHODIMP nsMsgFolder::GetRequiresCleanup(PRBool *requiredCleanup) { - if(!requiredCleanup) - return NS_ERROR_NULL_POINTER; - - *requiredCleanup = PR_FALSE; - return NS_OK; + if(!requiredCleanup) + return NS_ERROR_NULL_POINTER; + *requiredCleanup = PR_FALSE; + return NS_OK; } NS_IMETHODIMP nsMsgFolder::ClearRequiresCleanup() { - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsMsgFolder::GetManyHeadersToDownload(PRBool *_retval) @@ -2808,9 +2829,61 @@ NS_IMETHODIMP nsMsgFolder::GetSortOrder(PRInt32 *order) return NS_OK; } +NS_IMETHODIMP nsMsgFolder::GetSortKey(PRUnichar **aSortKey) +{ + nsresult rv=NS_OK; + NS_ENSURE_ARG(aSortKey); + nsAutoString orderString; + PRInt32 order; + rv = GetSortOrder(&order); + NS_ENSURE_SUCCESS(rv,rv); + orderString.AppendInt(order); + + nsXPIDLString folderName; + rv = GetName(getter_Copies(folderName)); + NS_ENSURE_SUCCESS(rv,rv); + orderString.Append(folderName); + rv = CreateCollationKey(orderString.get(), aSortKey); + return rv; +} + NS_IMETHODIMP nsMsgFolder::GetPersistElided(PRBool *aPersistElided) { // by default, we should always persist the open / closed state of folders & servers *aPersistElided = PR_TRUE; return NS_OK; } + +nsresult +nsMsgFolder::CreateCollationKey(const PRUnichar *aSource, PRUnichar **aSortKey) +{ + nsresult rv =NS_OK; + if (kCollationKeyGenerator) + { + nsAutoString sourceString(aSource); + PRUint8 *key=nsnull; + PRUint32 length; + + rv = kCollationKeyGenerator->GetSortKeyLen(kCollationCaseInSensitive, sourceString, &length); + NS_ENSURE_SUCCESS(rv, rv); + + key = (PRUint8 *) PR_Malloc(length+3); + if (!key) return NS_ERROR_OUT_OF_MEMORY; + + rv = kCollationKeyGenerator->CreateRawSortKey(kCollationCaseInSensitive, sourceString, key, &length); + + if (NS_SUCCEEDED(rv)) + { + key[length] = 0; + key[length+1] = 0; + key[length+2] = 0; + *aSortKey =(PRUnichar *) key; + } + else + PR_Free(key); + } + return rv; +} + + + diff --git a/mozilla/mailnews/base/util/nsMsgFolder.h b/mozilla/mailnews/base/util/nsMsgFolder.h index dd190718f07..252a9c741db 100644 --- a/mozilla/mailnews/base/util/nsMsgFolder.h +++ b/mozilla/mailnews/base/util/nsMsgFolder.h @@ -56,7 +56,9 @@ #include "nsIMsgFilterList.h" #include "nsIUrlListener.h" #include "nsIFileSpec.h" + class nsIStringBundle; +class nsICollation; /* * MsgFolder @@ -197,7 +199,7 @@ public: NS_IMETHOD ThrowAlertMsg(const char* msgName, nsIMsgWindow *msgWindow); NS_IMETHOD GetStringWithFolderNameFromBundle(const char* msgName, PRUnichar **aResult); NS_IMETHOD GetPersistElided(PRBool *aPersistElided); - + NS_IMETHOD GetSortKey(PRUnichar **aSortKey); // end NS_DECL_NSIMSGFOLDER // nsRDFResource overrides @@ -218,7 +220,7 @@ public: void ChangeNumPendingUnread(PRInt32 delta); void ChangeNumPendingTotalMessages(PRInt32 delta); - + #ifdef HAVE_ADMINURL @@ -244,7 +246,6 @@ public: NS_IMETHOD GetSortOrder(PRInt32 *order); NS_IMETHOD SetSortOrder(PRInt32 order); - protected: // this is a little helper function that is not part of the public interface. @@ -263,6 +264,7 @@ protected: nsresult ThrowConfirmationPrompt(nsIMsgWindow *msgWindow, const PRUnichar *confirmString, PRBool *confirmed); nsresult GetWarnFilterChanged(PRBool *aVal); nsresult SetWarnFilterChanged(PRBool aVal); + nsresult CreateCollationKey(const PRUnichar *aSource, PRUnichar **aSortKey); protected: PRUint32 mFlags; nsWeakPtr mParent; //This won't be refcounted for ownership reasons. @@ -289,7 +291,6 @@ protected: PRInt32 mNumPendingTotalMessages; PRInt32 mNumNewBiffMessages; - PRBool mIsCachable; // // stuff from the uri @@ -306,6 +307,7 @@ protected: static nsrefcnt gInstanceCount; static nsresult initializeStrings(); + static nsresult createCollationKeyGenerator(); static PRUnichar *kInboxName; static PRUnichar *kTrashName; @@ -324,6 +326,7 @@ protected: static nsIAtom* kNameAtom; static nsIAtom* kSynchronizeAtom; static nsIAtom* kOpenAtom; + static nsICollation* kCollationKeyGenerator; #ifdef MSG_FASTER_URI_PARSING // cached parsing URL object