From 7eda414dc6b3313b457d684c55e321dcf1d9c464 Mon Sep 17 00:00:00 2001
From: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
Date: Wed, 15 Apr 2009 22:42:36 -0400
Subject: [PATCH] Add a way to save account order

---
 sflphone-gtk/src/accountlist.c                |  12 ++
 sflphone-gtk/src/accountlist.h                |   1 +
 sflphone-gtk/src/config/configwindow.c        |   4 +
 .../src/dbus/configurationmanager-glue.h      |  37 +++++
 sflphone-gtk/src/dbus/dbus.c                  |  12 ++
 sflphone-gtk/src/dbus/dbus.h                  |   2 +
 src/dbus/configurationmanager-glue.h          |  17 +++
 src/dbus/configurationmanager-introspec.xml   |   4 +
 src/dbus/configurationmanager.cpp             |   7 +-
 src/dbus/configurationmanager.h               |   2 +
 src/managerimpl.cpp                           | 132 ++++++++++++------
 src/managerimpl.h                             |  12 ++
 12 files changed, 197 insertions(+), 45 deletions(-)

diff --git a/sflphone-gtk/src/accountlist.c b/sflphone-gtk/src/accountlist.c
index 455b68bd08..0ef19c0965 100644
--- a/sflphone-gtk/src/accountlist.c
+++ b/sflphone-gtk/src/accountlist.c
@@ -271,3 +271,15 @@ int account_list_get_iax_account_number( void ){
 
     return n;
 }
+
+gchar * account_list_get_ordered_list (void) {
+
+    gchar *order="";
+    guint i;
+
+    for( i=0; i<account_list_get_size(); i++ )
+    {
+        order = g_strconcat (account_list_get_nth (i)->accountID, "/", NULL);
+    }
+    return order;
+}
diff --git a/sflphone-gtk/src/accountlist.h b/sflphone-gtk/src/accountlist.h
index 1887ea974e..6456e521d0 100644
--- a/sflphone-gtk/src/accountlist.h
+++ b/sflphone-gtk/src/accountlist.h
@@ -182,6 +182,7 @@ int account_list_get_sip_account_number( void );
  */
 int account_list_get_iax_account_number( void );
 
+gchar * account_list_get_ordered_list (void);
 
 
 #endif 
diff --git a/sflphone-gtk/src/config/configwindow.c b/sflphone-gtk/src/config/configwindow.c
index 11cc6a27ef..fc8cd2c1ca 100644
--- a/sflphone-gtk/src/config/configwindow.c
+++ b/sflphone-gtk/src/config/configwindow.c
@@ -300,6 +300,10 @@ account_move(gboolean moveUp, gpointer data)
         account_list_move_up(indice);
     else
         account_list_move_down(indice);
+
+
+    // Set the order in the configuration file
+    dbus_set_accounts_order (account_list_get_ordered_list ());
 }
 
 /**
diff --git a/sflphone-gtk/src/dbus/configurationmanager-glue.h b/sflphone-gtk/src/dbus/configurationmanager-glue.h
index 996fb2d3cd..41addebde9 100644
--- a/sflphone-gtk/src/dbus/configurationmanager-glue.h
+++ b/sflphone-gtk/src/dbus/configurationmanager-glue.h
@@ -125,6 +125,43 @@ static
 inline
 #endif
 gboolean
+org_sflphone_SFLphone_ConfigurationManager_set_accounts_order (DBusGProxy *proxy, const char * IN_order, GError **error)
+
+{
+  return dbus_g_proxy_call (proxy, "setAccountsOrder", error, G_TYPE_STRING, IN_order, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+typedef void (*org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_reply) (DBusGProxy *proxy, GError *error, gpointer userdata);
+
+static void
+org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+{
+  DBusGAsyncData *data = (DBusGAsyncData*) user_data;
+  GError *error = NULL;
+  dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
+  (*(org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_reply)data->cb) (proxy, error, data->userdata);
+  return;
+}
+
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+DBusGProxyCall*
+org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_async (DBusGProxy *proxy, const char * IN_order, org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_reply callback, gpointer userdata)
+
+{
+  DBusGAsyncData *stuff;
+  stuff = g_new (DBusGAsyncData, 1);
+  stuff->cb = G_CALLBACK (callback);
+  stuff->userdata = userdata;
+  return dbus_g_proxy_begin_call (proxy, "setAccountsOrder", org_sflphone_SFLphone_ConfigurationManager_set_accounts_order_async_callback, stuff, g_free, G_TYPE_STRING, IN_order, G_TYPE_INVALID);
+}
+static
+#ifdef G_HAVE_INLINE
+inline
+#endif
+gboolean
 org_sflphone_SFLphone_ConfigurationManager_remove_account (DBusGProxy *proxy, const char * IN_accoundID, GError **error)
 
 {
diff --git a/sflphone-gtk/src/dbus/dbus.c b/sflphone-gtk/src/dbus/dbus.c
index 6cfe2d8156..517673db28 100644
--- a/sflphone-gtk/src/dbus/dbus.c
+++ b/sflphone-gtk/src/dbus/dbus.c
@@ -1571,3 +1571,15 @@ GHashTable* dbus_get_call_details (const gchar *callID)
 
     return details;
 }
+
+void dbus_set_accounts_order (const gchar* order) {
+
+    GError *error = NULL;
+    
+    org_sflphone_SFLphone_ConfigurationManager_set_accounts_order (configurationManagerProxy, order, &error);
+    if (error){
+        g_print ("Error calling org_sflphone_SFLphone_ConfigurationManager_set_accounts_order\n");
+        g_error_free (error);
+    }
+}
+
diff --git a/sflphone-gtk/src/dbus/dbus.h b/sflphone-gtk/src/dbus/dbus.h
index 4e10fba74c..6f64cfe30a 100644
--- a/sflphone-gtk/src/dbus/dbus.h
+++ b/sflphone-gtk/src/dbus/dbus.h
@@ -479,4 +479,6 @@ gboolean dbus_get_is_recording(const call_t *);
 
 GHashTable* dbus_get_call_details (const gchar* callID);
 
+void dbus_set_accounts_order (const gchar* order);
+
 #endif
diff --git a/src/dbus/configurationmanager-glue.h b/src/dbus/configurationmanager-glue.h
index 2e744ae93a..c79de5f0ac 100644
--- a/src/dbus/configurationmanager-glue.h
+++ b/src/dbus/configurationmanager-glue.h
@@ -23,6 +23,7 @@ public:
         register_method(ConfigurationManager_adaptor, getAccountDetails, _getAccountDetails_stub);
         register_method(ConfigurationManager_adaptor, setAccountDetails, _setAccountDetails_stub);
         register_method(ConfigurationManager_adaptor, addAccount, _addAccount_stub);
+        register_method(ConfigurationManager_adaptor, setAccountsOrder, _setAccountsOrder_stub);
         register_method(ConfigurationManager_adaptor, removeAccount, _removeAccount_stub);
         register_method(ConfigurationManager_adaptor, getAccountList, _getAccountList_stub);
         register_method(ConfigurationManager_adaptor, sendRegister, _sendRegister_stub);
@@ -106,6 +107,11 @@ public:
             { "details", "a{ss}", true },
             { 0, 0, 0 }
         };
+        static ::DBus::IntrospectedArgument setAccountsOrder_args[] = 
+        {
+            { "order", "s", true },
+            { 0, 0, 0 }
+        };
         static ::DBus::IntrospectedArgument removeAccount_args[] = 
         {
             { "accoundID", "s", true },
@@ -428,6 +434,7 @@ public:
             { "getAccountDetails", getAccountDetails_args },
             { "setAccountDetails", setAccountDetails_args },
             { "addAccount", addAccount_args },
+            { "setAccountsOrder", setAccountsOrder_args },
             { "removeAccount", removeAccount_args },
             { "getAccountList", getAccountList_args },
             { "sendRegister", sendRegister_args },
@@ -527,6 +534,7 @@ public:
     virtual std::map< std::string, std::string > getAccountDetails(const std::string& accountID) = 0;
     virtual void setAccountDetails(const std::string& accountID, const std::map< std::string, std::string >& details) = 0;
     virtual void addAccount(const std::map< std::string, std::string >& details) = 0;
+    virtual void setAccountsOrder(const std::string& order) = 0;
     virtual void removeAccount(const std::string& accoundID) = 0;
     virtual std::vector< std::string > getAccountList() = 0;
     virtual void sendRegister(const std::string& accountID, const int32_t& expire) = 0;
@@ -648,6 +656,15 @@ private:
         ::DBus::ReturnMessage reply(call);
         return reply;
     }
+    ::DBus::Message _setAccountsOrder_stub(const ::DBus::CallMessage &call)
+    {
+        ::DBus::MessageIter ri = call.reader();
+
+        std::string argin1; ri >> argin1;
+        setAccountsOrder(argin1);
+        ::DBus::ReturnMessage reply(call);
+        return reply;
+    }
     ::DBus::Message _removeAccount_stub(const ::DBus::CallMessage &call)
     {
         ::DBus::MessageIter ri = call.reader();
diff --git a/src/dbus/configurationmanager-introspec.xml b/src/dbus/configurationmanager-introspec.xml
index 3316647310..be283c820a 100644
--- a/src/dbus/configurationmanager-introspec.xml
+++ b/src/dbus/configurationmanager-introspec.xml
@@ -17,6 +17,10 @@
       <arg type="a{ss}" name="details" direction="in"/>
     </method>
     
+    <method name="setAccountsOrder">
+      <arg type="s" name="order" direction="in"/>
+    </method>
+    
     <method name="removeAccount">
       <arg type="s" name="accoundID" direction="in"/>
     </method>
diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp
index a82eaf1d7c..09be9dc26c 100644
--- a/src/dbus/configurationmanager.cpp
+++ b/src/dbus/configurationmanager.cpp
@@ -109,14 +109,12 @@ ConfigurationManager::getRingtoneList(  )
 	std::vector< std::string  >
 ConfigurationManager::getCodecList(  )
 {
-	_debug("ConfigurationManager::getCodecList received\n");
 	return Manager::instance().getCodecList();
 }
 
 	std::vector< std::string >
 ConfigurationManager::getCodecDetails( const int32_t& payload )
 {
-	_debug("ConfigurationManager::getCodecList received\n");
 	return Manager::instance().getCodecDetails( payload );
 }
 
@@ -450,3 +448,8 @@ std::map<std::string,std::string> ConfigurationManager::getHookSettings (void) {
 void ConfigurationManager::setHookSettings (const std::map<std::string, std::string>& settings) {
     Manager::instance().setHookSettings (settings);
 }
+
+void  ConfigurationManager::setAccountsOrder (const std::string& order) {
+    Manager::instance().setAccountsOrder (order);
+}
+
diff --git a/src/dbus/configurationmanager.h b/src/dbus/configurationmanager.h
index 19adba0422..4b05ac76f8 100644
--- a/src/dbus/configurationmanager.h
+++ b/src/dbus/configurationmanager.h
@@ -109,6 +109,8 @@ public:
     std::vector< std::string > getAddressbookList ( void );
     void setAddressbookList( const std::vector< std::string >& list );
 
+    void setAccountsOrder (const std::string& order);
+
     std::map<std::string, std::string> getHookSettings (void);
     void setHookSettings (const std::map<std::string, std::string>& settings);
 
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 0dd7228ec0..b661c209d4 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -1204,6 +1204,7 @@ ManagerImpl::initConfigFile ( bool load_user_value )
   fill_config_int(CONFIG_AUDIO , DFT_AUDIO_MANAGER);
   fill_config_int(CONFIG_PA_VOLUME_CTRL , YES_STR);
   fill_config_int(CONFIG_SIP_PORT, DFT_SIP_PORT);
+  fill_config_str(CONFIG_ACCOUNTS_ORDER, "");
 
   section = ADDRESSBOOK;
   fill_config_int (ADDRESSBOOK_MAX_RESULTS, "25");
@@ -2126,22 +2127,53 @@ ManagerImpl::setConfig(const std::string& section, const std::string& name, int
   return _config.setConfigTreeItem(section, name, valueStream.str());
 }
 
+
+void ManagerImpl::setAccountsOrder (const std::string& order) 
+{
+    // Set the new config
+    setConfig (PREFERENCES, CONFIG_ACCOUNTS_ORDER, order);
+}
+
   std::vector< std::string >
 ManagerImpl::getAccountList()
 {
-  std::vector< std::string > v;
+    std::vector< std::string > v;
+    std::vector< std::string > account_order;
+    int i;
 
-  AccountMap::iterator iter = _accountMap.begin();
-  while ( iter != _accountMap.end() ) {
-    if ( iter->second != 0 ) {
-      _debug("Account List: %s\n", iter->first.data());
-      v.push_back(iter->first.data());
+    account_order = loadAccountOrder ();
+    AccountMap::iterator iter;
 
+    // If no order has been set, load the default one
+    // ie according to the creation date.
+    if (account_order.size () == 0) {
+        iter = _accountMap.begin ();
+        while ( iter != _accountMap.end() ) {
+            if ( iter->second != 0 ) {
+                v.push_back(iter->first.data());
+            }
+            iter++;
+        }   
     }
-    iter++;
-  }
-  _debug("Size: %d\n", v.size());
-  return v;
+
+    // Otherelse, load the custom one
+    // ie according to the saved order
+    else {
+
+        for (i=0; i<account_order.size (); i++) {
+            // This account has not been loaded, so we ignore it
+            if ( (iter=_accountMap.find (account_order[i])) != _accountMap.end() )
+            {
+                // If the account is valid
+                if (iter->second != 0) 
+                {
+                    v.push_back (iter->first.data ());
+                }
+            }
+        }
+    }
+   
+    return v;
 }
 
 std::map< std::string, std::string > ManagerImpl::getAccountDetails(const AccountID& accountID)
@@ -2338,47 +2370,61 @@ ManagerImpl::getNewCallID()
   return random_id.str();
 }
 
-  short
-ManagerImpl::loadAccountMap()
+std::vector <std::string> ManagerImpl::loadAccountOrder (void)
 {
 
-  short nbAccount = 0;
-  TokenList sections = _config.getSections();
-  std::string accountType;
-  Account* tmpAccount;
+    std::string account_list;
+    std::vector <std::string> account_vect;
+
+    account_list = getConfigString (PREFERENCES, CONFIG_ACCOUNTS_ORDER);
+    return unserialize (account_list);
+}
 
 
-  TokenList::iterator iter = sections.begin();
-  while(iter != sections.end()) {
-    // Check if it starts with "Account:" (SIP and IAX pour le moment)
-    if ((int)(iter->find("Account:")) == -1) {
-      iter++;
-      continue;
-    }
+  short
+ManagerImpl::loadAccountMap()
+{
 
-    accountType = getConfigString(*iter, CONFIG_ACCOUNT_TYPE);
-    if (accountType == "SIP") {
-      tmpAccount = AccountCreator::createAccount(AccountCreator::SIP_ACCOUNT, *iter);
-    }
-    else if (accountType == "IAX") {
-      tmpAccount = AccountCreator::createAccount(AccountCreator::IAX_ACCOUNT, *iter);
-    }
-    else {
-      _debug("Unknown %s param in config file (%s)\n", CONFIG_ACCOUNT_TYPE, accountType.c_str());
-    }
+    short nbAccount = 0;
+    TokenList sections = _config.getSections();
+    std::string accountType;
+    Account* tmpAccount;
+    std::vector <std::string> account_order;
+
+    TokenList::iterator iter = sections.begin();
+  
+    while(iter != sections.end()) {
+        // Check if it starts with "Account:" (SIP and IAX pour le moment)
+        if ((int)(iter->find("Account:")) == -1) {
+            iter++;
+            continue;
+        }
 
-    _debug("tmpAccount.getRegistrationState() %i \n ",tmpAccount->getRegistrationState());
-    if (tmpAccount != NULL) {
+        accountType = getConfigString(*iter, CONFIG_ACCOUNT_TYPE);
+        
+        if (accountType == "SIP") {
+            tmpAccount = AccountCreator::createAccount(AccountCreator::SIP_ACCOUNT, *iter);
+        }
+    
+        else if (accountType == "IAX") {
+            tmpAccount = AccountCreator::createAccount(AccountCreator::IAX_ACCOUNT, *iter);
+        }
+    
+        else {
+        _debug("Unknown %s param in config file (%s)\n", CONFIG_ACCOUNT_TYPE, accountType.c_str());
+        }
 
-      _debug(" %s \n", iter->c_str());
-      _accountMap[iter->c_str()] = tmpAccount;
-      nbAccount++;
-    }
+        if (tmpAccount != NULL) {
+            _debug(" %s \n", iter->c_str());
+            _accountMap[iter->c_str()] = tmpAccount;
+            nbAccount++;
+        }
 
-    iter++;
-  }
-  _debug("nbAccount loaded %i \n",nbAccount);
-  return nbAccount;
+        iter++;
+    }
+    
+    _debug("nbAccount loaded %i \n",nbAccount);
+    return nbAccount;
 }
 
   void
diff --git a/src/managerimpl.h b/src/managerimpl.h
index 5a12a3143f..86578e3285 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -282,6 +282,11 @@ class ManagerImpl {
      */
     std::vector< std::string >  getAccountList();
 
+    /**
+     * Set the account order in the config file
+     */
+    void setAccountsOrder (const std::string& order);
+
     /**
      * Retrieve details about a given account
      * @param accountID	  The account identifier
@@ -1063,6 +1068,13 @@ class ManagerImpl {
      */
     short loadAccountMap();
 
+    /**
+     * Load the accounts order set by the user from the sflphonedrc config file
+     * @return std::vector<std::string> A vector containing the account ID's
+     */
+    std::vector<std::string> loadAccountOrder ();
+
+
     /**
      * Unload the account (delete them)
      */
-- 
GitLab