Bug 749200 - Add sortOrder property to nsIMsgIncomingServer. r=mbanner
authorNeil Rashbrook <neil@parkwaycc.co.uk>
Wed, 24 Oct 2012 21:53:11 -0400
changeset 14099 0e156c9327d296bbebcc34a9b05ea3a47edcd673
parent 14098 2606440ab8500f7a317c74c053f4ebcd6bf2ce4a
child 14100 eb8f507508d7daaf77de3a44a1d449135d595297
push id804
push userbugzilla@standard8.plus.com
push dateMon, 07 Jan 2013 21:31:35 +0000
treeherdercomm-beta@9fdc5c67cdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbanner
bugs749200
Bug 749200 - Add sortOrder property to nsIMsgIncomingServer. r=mbanner
mail/components/im/imIncomingServer.js
mailnews/base/public/nsIMsgAccountManager.idl
mailnews/base/public/nsIMsgIncomingServer.idl
mailnews/base/src/nsMsgAccountManager.cpp
mailnews/base/src/nsMsgAccountManagerDS.cpp
mailnews/base/util/nsMsgIncomingServer.cpp
mailnews/local/src/nsNoIncomingServer.cpp
mailnews/local/src/nsNoIncomingServer.h
mailnews/local/src/nsRssIncomingServer.cpp
mailnews/local/src/nsRssIncomingServer.h
mailnews/news/src/nsNntpIncomingServer.cpp
mailnews/news/src/nsNntpIncomingServer.h
--- a/mail/components/im/imIncomingServer.js
+++ b/mail/components/im/imIncomingServer.js
@@ -242,15 +242,17 @@ imIncomingServer.prototype = {
       get subFolders() EmptyEnumerator,
       getStringProperty: function(aPropertyName) "",
       getNumUnread: function(aDeep) 0,
       Shutdown: function() {},
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIMsgFolder])
     });
   },
 
+  get sortOrder() 300000000,
+
   classDescription: "IM Msg Incoming Server implementation",
   classID: Components.ID("{9dd7f36b-5960-4f0a-8789-f5f516bd083d}"),
   contractID: "@mozilla.org/messenger/server;1?type=im",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIMsgIncomingServer])
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([imIncomingServer]);
--- a/mailnews/base/public/nsIMsgAccountManager.idl
+++ b/mailnews/base/public/nsIMsgAccountManager.idl
@@ -9,17 +9,17 @@
 #include "nsIMsgIncomingServer.idl"
 #include "nsIIncomingServerListener.idl"
 #include "nsIMsgFolder.idl"
 
 interface nsISupportsArray;
 interface nsIMsgFolderCache;
 interface nsIFolderListener;
 
-[scriptable, uuid(5cd9a7cc-3bd1-4553-95d8-b1b48f19ed1e)]
+[scriptable, uuid(ae2fc99f-0d94-4e68-bc0e-7feb645b110f)]
 interface nsIMsgAccountManager : nsISupports {
 
   nsIMsgAccount createAccount();
   /*
    * Return the account with the provided key, or null if none found.
    */
   nsIMsgAccount getAccount(in ACString key);
     
@@ -208,16 +208,19 @@ interface nsIMsgAccountManager : nsISupp
    * Iterates over all folders looking for one with the passed in path,
    * and returns the uri for the matching folder. In the future,
    * the folder lookup service will provide this functionality.
    *
    * @param aLocalPath path of the folder whose uri we want.
    * @return the URI of the folder that corresponds to aLocalPath
    */
   ACString folderUriForPath(in nsIFile aLocalPath);
+
+  // Used to sort servers (accounts) for e.g. the folder pane
+  long getSortOrder(in nsIMsgIncomingServer server);
 };
 
 %{C++
 #define MAILNEWS_ACCOUNTMANAGER_EXTENSIONS "mailnews-accountmanager-extensions"
 %}
 
 [scriptable, uuid(70032DE0-CD59-41ba-839D-FC1B65367EE7)]
 interface nsIMsgAccountManagerExtension : nsISupports
--- a/mailnews/base/public/nsIMsgIncomingServer.idl
+++ b/mailnews/base/public/nsIMsgIncomingServer.idl
@@ -21,17 +21,17 @@ interface nsIURI;
 interface nsIMsgPluggableStore;
 
 /*
  * Interface for incoming mail/news host
  * this is the base interface for all mail server types (imap, pop, nntp, etc)
  * often you will want to add extra interfaces that give you server-specific
  * attributes and methods.
  */
-[scriptable, uuid(cf46d3ce-bf1e-40b5-8749-53d1424638b3)]
+[scriptable, uuid(92f4ee31-a14d-48dc-8676-22417caefa83)]
 interface nsIMsgIncomingServer : nsISupports {
 
   /**
    * internal pref key - guaranteed to be unique across all servers
    */
   attribute ACString key;
 
   /**
@@ -492,16 +492,28 @@ interface nsIMsgIncomingServer : nsISupp
    * Get a boolean to force an inherited propertyName to return empty instead
    * of inheriting from a parent folder, server, or the global
    *
    * @param propertyName      The name of the property
    *
    * @return                  true if an empty inherited property should be returned
    */
   boolean getForcePropertyEmpty(in string propertyName);
+
+  /**
+   * Return the order in which this server type should appear in the folder pane.
+   * This sort order is a number between 100000000 and 900000000 so that RDF can
+   * use it as a string.
+   * The current return values are these:
+   * 0 = default account,       100000000 = mail accounts (POP3/IMAP4),
+   * 200000000 = Local Folders, 300000000 = IM accounts,
+   * 400000000 = RSS,           500000000 = News
+   * If a new server type is created a TB UI reviewer must decide its sort order.
+   */
+  readonly attribute long sortOrder;
 };
 
 %{C++
 /*
  * Following values for offline support have been used by
  * various files. If you are modifying any of the values
  * below, please do take care of the following files.
  * - mozilla/mailnews/base/src/nsMsgAccountManagerDS.cpp
--- a/mailnews/base/src/nsMsgAccountManager.cpp
+++ b/mailnews/base/src/nsMsgAccountManager.cpp
@@ -1806,20 +1806,21 @@ nsMsgAccountManager::GetAccount(const ns
   // not found, create on demand
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMsgAccountManager::FindServerIndex(nsIMsgIncomingServer* server, int32_t* result)
 {
   NS_ENSURE_ARG_POINTER(server);
-  nsresult rv;
+  NS_ENSURE_ARG_POINTER(result);
 
   nsCString key;
-  rv = server->GetKey(key);
+  nsresult rv = server->GetKey(key);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   findServerByKeyEntry findEntry;
   findEntry.key = key;
   findEntry.index = -1;
 
   // do this by account because the account list is in order
   m_accounts->EnumerateForwards(findServerIndexByServer, (void *)&findEntry);
 
@@ -3881,8 +3882,51 @@ nsMsgAccountManager::FolderUriForPath(ns
       rv = folder->GetURI(aMailboxUri);
       m_lastFolderURIForPath = aMailboxUri;
       aLocalPath->Clone(getter_AddRefs(m_lastPathLookedUp));
       return rv;
     }
   }
   return NS_ERROR_FAILURE;
 }
+
+NS_IMETHODIMP
+nsMsgAccountManager::GetSortOrder(nsIMsgIncomingServer* aServer, int32_t* aSortOrder)
+{
+  NS_ENSURE_ARG_POINTER(aServer);
+  NS_ENSURE_ARG_POINTER(aSortOrder);
+
+  // If the passed in server is the default, return its sort order as 0 regardless
+  // of its server sort order.
+
+  nsCOMPtr<nsIMsgAccount> defaultAccount;
+  nsresult rv = GetDefaultAccount(getter_AddRefs(defaultAccount));
+  if (NS_SUCCEEDED(rv) && defaultAccount) {
+    nsCOMPtr<nsIMsgIncomingServer> defaultServer;
+    rv = m_defaultAccount->GetIncomingServer(getter_AddRefs(defaultServer));
+    if (NS_SUCCEEDED(rv) && defaultServer && (aServer == defaultServer)) {
+      *aSortOrder = 0;
+      return NS_OK;
+    }
+    // It is OK if there is no default account.
+  }
+
+  // This function returns the sort order by querying the server object for its
+  // sort order value and then incrementing it by the position of the server in
+  // the accounts list. This ensures that even when several accounts have the
+  // same sort order value, the returned value is not the same and keeps
+  // their relative order in the account list when and unstable sort is run
+  // on the returned sort order values.
+  int32_t sortOrder;
+  int32_t serverIndex;
+
+  rv = aServer->GetSortOrder(&sortOrder);
+  if (NS_SUCCEEDED(rv))
+    rv = FindServerIndex(aServer, &serverIndex);
+
+  if (NS_FAILED(rv)) {
+    *aSortOrder = 999999999;
+  } else {
+    *aSortOrder = sortOrder + serverIndex;
+  }
+
+  return NS_OK;
+}
--- a/mailnews/base/src/nsMsgAccountManagerDS.cpp
+++ b/mailnews/base/src/nsMsgAccountManagerDS.cpp
@@ -423,32 +423,20 @@ nsMsgAccountManagerDataSource::GetTarget
     nsCOMPtr<nsIMsgIncomingServer> server;
     rv = getServerForFolderNode(source, getter_AddRefs(server));
 
     if (NS_SUCCEEDED(rv) && server) {
       int32_t accountNum;
       nsCOMPtr<nsIMsgAccountManager> am = do_QueryReferent(mAccountManager);
 
       if (isDefaultServer(server))
-        str.AssignLiteral("0000");
+        str.AssignLiteral("000000000");
       else {
-        rv = am->FindServerIndex(server, &accountNum);
-        if (NS_FAILED(rv)) return rv;
-
-        // this is a hack for now - hardcode server order by type
-        nsCString serverType;
-        server->GetType(serverType);
-
-        if (MsgLowerCaseEqualsLiteral(serverType, "none"))
-          accountNum += 2000;
-        else if (MsgLowerCaseEqualsLiteral(serverType, "nntp"))
-          accountNum += 3000;
-        else
-          accountNum += 1000;     // default is to appear at the top
-
+        rv = am->GetSortOrder(server, &accountNum);
+        NS_ENSURE_SUCCESS(rv, rv);
         str.AppendInt(accountNum);
       }
     }
     else {
       const char *sourceValue;
       rv = source->GetValueConst(&sourceValue);
       NS_ENSURE_SUCCESS(rv, NS_RDF_NO_VALUE);
 
@@ -456,17 +444,17 @@ nsMsgAccountManagerDataSource::GetTarget
       // we want to generate a sort value
       // so that we can sort the categories in the account manager tree
       // (or the folder pane)
       //
       // otherwise, return NS_RDF_NO_VALUE
       // so that the folder data source will take care of it.
       if (sourceValue && (strncmp(sourceValue, NC_RDF_PAGETITLE_PREFIX, strlen(NC_RDF_PAGETITLE_PREFIX)) == 0)) {
         if (source == kNC_PageTitleSMTP)
-          str.AssignLiteral("4000");
+          str.AssignLiteral("900000000");
         else if (source == kNC_PageTitleServer)
           str.AssignLiteral("1");
         else if (source == kNC_PageTitleCopies)
           str.AssignLiteral("2");
         else if (source == kNC_PageTitleAddressing)
           str.AssignLiteral("3");
         else if (source == kNC_PageTitleSynchronization)
           str.AssignLiteral("4");
--- a/mailnews/base/util/nsMsgIncomingServer.cpp
+++ b/mailnews/base/util/nsMsgIncomingServer.cpp
@@ -2267,8 +2267,16 @@ nsMsgIncomingServer::GetForcePropertyEmp
 NS_IMETHODIMP
 nsMsgIncomingServer::SetForcePropertyEmpty(const char *aPropertyName, bool aValue)
 {
  nsAutoCString nameEmpty(aPropertyName);
  nameEmpty.Append(NS_LITERAL_CSTRING(".empty"));
  return SetCharValue(nameEmpty.get(),
    aValue ? NS_LITERAL_CSTRING("true") : NS_LITERAL_CSTRING(""));
 }
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSortOrder(int32_t* aSortOrder)
+{
+  NS_ENSURE_ARG_POINTER(aSortOrder);
+  *aSortOrder = 100000000;
+  return NS_OK;
+}
--- a/mailnews/local/src/nsNoIncomingServer.cpp
+++ b/mailnews/local/src/nsNoIncomingServer.cpp
@@ -199,9 +199,16 @@ nsNoIncomingServer::GetCanSearchMessages
 NS_IMETHODIMP
 nsNoIncomingServer::GetServerRequiresPasswordForBiff(bool *aServerRequiresPasswordForBiff)
 {
   NS_ENSURE_ARG_POINTER(aServerRequiresPasswordForBiff);
   *aServerRequiresPasswordForBiff = false;  // for local folders, we don't require a password
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNoIncomingServer::GetSortOrder(int32_t* aSortOrder)
+{
+  NS_ENSURE_ARG_POINTER(aSortOrder);
+  *aSortOrder = 200000000;
+  return NS_OK;
+}
 
--- a/mailnews/local/src/nsNoIncomingServer.h
+++ b/mailnews/local/src/nsNoIncomingServer.h
@@ -25,12 +25,13 @@ public:
 
   nsNoIncomingServer();
   virtual ~nsNoIncomingServer();
 
   NS_IMETHOD GetLocalStoreType(nsACString& type);
   NS_IMETHOD GetCanSearchMessages(bool *canSearchMessages);
   NS_IMETHOD GetServerRequiresPasswordForBiff(bool *aServerRequiresPasswordForBiff);
   NS_IMETHOD GetAccountManagerChrome(nsAString& aResult);
+  NS_IMETHOD GetSortOrder(int32_t* aSortOrder);
 };
 
 
 #endif
--- a/mailnews/local/src/nsRssIncomingServer.cpp
+++ b/mailnews/local/src/nsRssIncomingServer.cpp
@@ -265,8 +265,16 @@ nsresult nsRssIncomingServer::FolderChan
         rssFolder = do_QueryElementAt(allDescendents, index, &rv);
         if (rssFolder)
           rssDownloader->UpdateSubscriptionsDS(rssFolder, aUnsubscribe);
       }
     }
   }
   return rv;
 }
+
+NS_IMETHODIMP
+nsRssIncomingServer::GetSortOrder(int32_t* aSortOrder)
+{
+  NS_ENSURE_ARG_POINTER(aSortOrder);
+  *aSortOrder = 400000000;
+  return NS_OK;
+}
--- a/mailnews/local/src/nsRssIncomingServer.h
+++ b/mailnews/local/src/nsRssIncomingServer.h
@@ -24,16 +24,17 @@ public:
     NS_DECL_NSIMSGFOLDERLISTENER
 
     NS_IMETHOD GetOfflineSupportLevel(int32_t *aSupportLevel);
     NS_IMETHOD GetSupportsDiskSpace(bool *aSupportsDiskSpace);
     NS_IMETHOD GetAccountManagerChrome(nsAString& aResult);
     NS_IMETHOD PerformBiff(nsIMsgWindow *aMsgWindow);
     NS_IMETHOD GetServerRequiresPasswordForBiff(bool *aServerRequiresPasswordForBiff);
     NS_IMETHOD GetCanSearchMessages(bool *canSearchMessages);
+    NS_IMETHOD GetSortOrder(int32_t* aSortOrder);
 
     nsRssIncomingServer();
     virtual ~nsRssIncomingServer();
 protected:
     nsresult FolderChanged(nsIMsgFolder *aFolder, bool aUnsubscribe);
     nsresult FillInDataSourcePath(const nsAString& aDataSourceName, nsIFile ** aLocation);
     static nsrefcnt gInstanceCount;
 };
--- a/mailnews/news/src/nsNntpIncomingServer.cpp
+++ b/mailnews/news/src/nsNntpIncomingServer.cpp
@@ -2131,8 +2131,16 @@ nsNntpIncomingServer::OnUserOrHostNameCh
     // subscribe.
     rv = SubscribeToNewsgroup(NS_ConvertUTF16toUTF8(groupList[i]));
     NS_ENSURE_SUCCESS(rv,rv);
   }
 
   // Force updating the rc file.
   return CommitSubscribeChanges();
 }
+
+NS_IMETHODIMP
+nsNntpIncomingServer::GetSortOrder(int32_t* aSortOrder)
+{
+  NS_ENSURE_ARG_POINTER(aSortOrder);
+  *aSortOrder = 500000000;
+  return NS_OK;
+}
--- a/mailnews/news/src/nsNntpIncomingServer.h
+++ b/mailnews/news/src/nsNntpIncomingServer.h
@@ -67,16 +67,17 @@ public:
     NS_IMETHOD GetDefaultCopiesAndFoldersPrefsToServer(bool *aCopiesAndFoldersOnServer);
     NS_IMETHOD GetCanCreateFoldersOnServer(bool *aCanCreateFoldersOnServer);
     NS_IMETHOD GetCanFileMessagesOnServer(bool *aCanFileMessagesOnServer);
     NS_IMETHOD GetFilterScope(nsMsgSearchScopeValue *filterScope);
     NS_IMETHOD GetSearchScope(nsMsgSearchScopeValue *searchScope);
 
     NS_IMETHOD GetSocketType(int32_t *aSocketType); // override nsMsgIncomingServer impl
     NS_IMETHOD SetSocketType(int32_t aSocketType); // override nsMsgIncomingServer impl
+    NS_IMETHOD GetSortOrder(int32_t* aSortOrder);
 
 protected:
    virtual nsresult CreateRootFolderFromUri(const nsCString &serverUri,
                                             nsIMsgFolder **rootFolder);
     nsresult GetNntpConnection(nsIURI *url, nsIMsgWindow *window,
                                nsINNTPProtocol **aNntpConnection);
     nsresult CreateProtocolInstance(nsINNTPProtocol **aNntpConnection,
                                     nsIURI *url, nsIMsgWindow *window);