From 2fb856e0aab92dad950ffc7747279966beb49d9f Mon Sep 17 00:00:00 2001
From: Emmanuel Milou <emilou@emilou-desktop.(none)>
Date: Fri, 29 May 2009 16:30:07 -0400
Subject: [PATCH] [#1312] Implement getCallList D-BUS method

---
 sflphone-client-gnome/src/actions.c           | 25 ++++++++++++++++++
 sflphone-client-gnome/src/actions.h           |  2 ++
 sflphone-client-gnome/src/call.c              | 20 ++++++++++++--
 sflphone-client-gnome/src/contacts/calllist.h |  6 +++++
 sflphone-client-gnome/src/contacts/calltree.c | 12 +++++++++
 .../src/dbus/callmanager-introspec.xml        |  4 +++
 sflphone-client-gnome/src/dbus/dbus.c         | 14 ++++++++++
 sflphone-client-gnome/src/dbus/dbus.h         |  2 ++
 sflphone-client-gnome/src/main.c              |  9 ++++---
 sflphone-common/src/call.cpp                  | 26 +++++++++++++++++++
 sflphone-common/src/call.h                    |  2 ++
 .../src/dbus/callmanager-introspec.xml        |  4 +++
 sflphone-common/src/dbus/callmanager.cpp      |  6 +++++
 sflphone-common/src/dbus/callmanager.h        |  3 +++
 sflphone-common/src/managerimpl.cpp           | 18 +++++++++++++
 sflphone-common/src/managerimpl.h             |  6 +++++
 16 files changed, 154 insertions(+), 5 deletions(-)

diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c
index 120024a7c3..664867ff43 100644
--- a/sflphone-client-gnome/src/actions.c
+++ b/sflphone-client-gnome/src/actions.c
@@ -884,6 +884,31 @@ sflphone_fill_codec_list()
     }
 }
 
+void sflphone_fill_call_list (void)
+{
+    
+    gchar** calls = (gchar**)dbus_get_call_list();
+    gchar** pl;
+    GHashTable *call_details;
+    call_t *c;
+    gchar *callID;
+
+    for(pl=calls; *calls; calls++)
+    {
+        c = g_new0(call_t, 1);
+        callID = (gchar*)(*calls);
+        call_details = dbus_get_call_details(callID);
+        create_new_call_from_details (callID, call_details, &c);
+        c->callID = g_strdup(callID);
+
+        // Add it to the list
+        DEBUG ("Add call retrieved from server side: %s\n", c->callID);
+        calllist_add (current_calls, c);
+        // Update the GUI
+        calltree_add_call (current_calls, c);
+    }
+}
+
 void format_phone_number (gchar **number) {
 
     gchar *_number;
diff --git a/sflphone-client-gnome/src/actions.h b/sflphone-client-gnome/src/actions.h
index 19a22694d6..36b40fc791 100644
--- a/sflphone-client-gnome/src/actions.h
+++ b/sflphone-client-gnome/src/actions.h
@@ -152,6 +152,8 @@ void sflphone_place_call ( call_t * c );
  */
 void sflphone_fill_account_list(gboolean toolbarInitialized);
 
+void sflphone_fill_call_list (void);
+
 /**
  * Set an account as current. The current account is to one used to place calls with by default
  * The current account is the first in the account list ( index 0 )
diff --git a/sflphone-client-gnome/src/call.c b/sflphone-client-gnome/src/call.c
index 5ab52ee258..535089ce50 100644
--- a/sflphone-client-gnome/src/call.c
+++ b/sflphone-client-gnome/src/call.c
@@ -89,6 +89,8 @@ void create_new_call (gchar *to, gchar *from, call_state_t state, gchar *account
     call->_start = 0;
     call->_stop = 0;
 
+    DEBUG ()
+
     call_id = g_new0(gchar, 30);
     g_sprintf(call_id, "%d", rand());
     call->callID = g_strdup (call_id);
@@ -98,15 +100,29 @@ void create_new_call (gchar *to, gchar *from, call_state_t state, gchar *account
 
 void create_new_call_from_details (const gchar *call_id, GHashTable *details, call_t **call)
 {
-    gchar *from, *to, *accountID;
+    gchar *from, *to, *accountID, *state_str;
     call_t *new_call;
+    call_state_t state;
     // GHashTable *call_details;
 
     accountID = g_hash_table_lookup (details, "ACCOUNTID");
     to = g_hash_table_lookup (details, "PEER_NUMBER");
     from = g_markup_printf_escaped("\"\" <%s>",  to);
+    state_str = g_hash_table_lookup (details, "CALL_STATE");
+
+    if (g_strcasecmp (state_str, "CURRENT") == 0)
+        state = CALL_STATE_CURRENT;
+
+    else if (g_strcasecmp (state_str, "HOLD") == 0)
+        state = CALL_STATE_HOLD;
+
+    else if (g_strcasecmp (state_str, "BUSY") == 0)
+        state = CALL_STATE_BUSY;
+
+    else
+        state = CALL_STATE_FAILURE;
 
-    create_new_call (from, from, CALL_STATE_DIALING, accountID, &new_call);
+    create_new_call (from, from, state, accountID, &new_call);
     *call = new_call;
 }
 
diff --git a/sflphone-client-gnome/src/contacts/calllist.h b/sflphone-client-gnome/src/contacts/calllist.h
index d1e308eca3..afdf5e4b04 100644
--- a/sflphone-client-gnome/src/contacts/calllist.h
+++ b/sflphone-client-gnome/src/contacts/calllist.h
@@ -110,4 +110,10 @@ calllist_clean_history();
 void
 calllist_remove_from_history( call_t* c);
 
+/**
+ * Initialize a non-empty call list
+ */
+void
+calllist_set_list (calltab_t* tab, gchar **call_list);
+
 #endif
diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c
index 6c6e771dc3..34b9dbe689 100644
--- a/sflphone-client-gnome/src/contacts/calltree.c
+++ b/sflphone-client-gnome/src/contacts/calltree.c
@@ -479,6 +479,18 @@ calltree_add_call (calltab_t* tab, call_t * c)
             case CALL_STATE_RINGING:
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL);
                 break;
+            case CALL_STATE_CURRENT:
+                // If the call has been initiated by a another client and, when we start, it is already current
+                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
+                break;
+            case CALL_STATE_HOLD:
+                // If the call has been initiated by a another client and, when we start, it is already current
+                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/hold.svg", NULL);
+                break;
+            case CALL_STATE_FAILURE:
+                // If the call has been initiated by a another client and, when we start, it is already current
+                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/fail.svg", NULL);
+                break;
             default:
                 WARN("Update calltree add - Should not happen!");
         }
diff --git a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
index dbc84d3542..d72dddd28f 100644
--- a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
+++ b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
@@ -67,6 +67,10 @@
       <arg type="a{ss}" name="infos" direction="out"/>
     </method>
     
+    <method name="getCallList">
+        <arg type="as" name="list" direction="out"/>
+    </method>
+
     <method name="getCurrentCallID">
       <arg type="s" name="callID" direction="out"/>
     </method>
diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c
index 4a82762639..9c2cc20463 100644
--- a/sflphone-client-gnome/src/dbus/dbus.c
+++ b/sflphone-client-gnome/src/dbus/dbus.c
@@ -1623,6 +1623,20 @@ GHashTable* dbus_get_call_details (const gchar *callID)
     return details;
 }
 
+gchar** dbus_get_call_list (void)
+{
+    GError *error = NULL;
+    gchar **list = NULL;
+
+    org_sflphone_SFLphone_CallManager_get_call_list (callManagerProxy, &list, &error);
+    if (error){
+        ERROR ("Error calling org_sflphone_SFLphone_CallManager_get_call_list");
+        g_error_free (error);
+    }
+
+    return list;
+}
+
 void dbus_set_accounts_order (const gchar* order) {
 
     GError *error = NULL;
diff --git a/sflphone-client-gnome/src/dbus/dbus.h b/sflphone-client-gnome/src/dbus/dbus.h
index c16ec70726..7d6c02686d 100644
--- a/sflphone-client-gnome/src/dbus/dbus.h
+++ b/sflphone-client-gnome/src/dbus/dbus.h
@@ -481,6 +481,8 @@ gboolean dbus_get_is_recording(const call_t *);
 
 GHashTable* dbus_get_call_details (const gchar* callID);
 
+gchar** dbus_get_call_list (void);
+
 void dbus_set_accounts_order (const gchar* order);
 
 #endif
diff --git a/sflphone-client-gnome/src/main.c b/sflphone-client-gnome/src/main.c
index bedccadc0e..23eccbd1b6 100644
--- a/sflphone-client-gnome/src/main.c
+++ b/sflphone-client-gnome/src/main.c
@@ -100,10 +100,13 @@ There is NO WARRANTY, to the extent permitted by law.\n\n");
         }
 #endif
 
-      status_bar_display_account();
+    status_bar_display_account();
 
-      /* start the main loop */
-      gtk_main();
+    // Get the active calls at startup    
+    sflphone_fill_call_list ();
+
+    /* start the main loop */
+    gtk_main();
     }
 
   // Cleanly stop logging
diff --git a/sflphone-common/src/call.cpp b/sflphone-common/src/call.cpp
index 45ee195eee..49fde4fc0c 100644
--- a/sflphone-common/src/call.cpp
+++ b/sflphone-common/src/call.cpp
@@ -82,6 +82,32 @@ Call::getState()
   return _callState;
 }
 
+std::string
+Call::getStateStr (CallState state)
+{
+    std::string state_str;
+        
+    switch (state) {
+        case Active:
+            state_str = "CURRENT";
+            break;
+        case Hold:
+            state_str = "HOLD";
+            break;
+        case Busy:
+            state_str = "BUSY";
+            break;
+        case Refused:
+        case Error:
+        case Inactive:
+        default:
+            state_str = "FAILURE";
+            break;
+    }
+    return state_str;
+}
+
+
 const std::string& 
 Call::getLocalIp()
 {
diff --git a/sflphone-common/src/call.h b/sflphone-common/src/call.h
index 1480ca9432..6a397a685b 100644
--- a/sflphone-common/src/call.h
+++ b/sflphone-common/src/call.h
@@ -139,6 +139,8 @@ class Call{
          * @return CallState  The call state
          */
         CallState getState();
+        
+        std::string getStateStr (CallState state);
 
         void setCallConfiguration (Call::CallConfiguration callConfig) { _callConfig = callConfig; }
         
diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml
index dbc84d3542..d72dddd28f 100644
--- a/sflphone-common/src/dbus/callmanager-introspec.xml
+++ b/sflphone-common/src/dbus/callmanager-introspec.xml
@@ -67,6 +67,10 @@
       <arg type="a{ss}" name="infos" direction="out"/>
     </method>
     
+    <method name="getCallList">
+        <arg type="as" name="list" direction="out"/>
+    </method>
+
     <method name="getCurrentCallID">
       <arg type="s" name="callID" direction="out"/>
     </method>
diff --git a/sflphone-common/src/dbus/callmanager.cpp b/sflphone-common/src/dbus/callmanager.cpp
index e013410ad5..cfd73bd704 100644
--- a/sflphone-common/src/dbus/callmanager.cpp
+++ b/sflphone-common/src/dbus/callmanager.cpp
@@ -146,6 +146,12 @@ CallManager::getCallDetails( const std::string& callID )
     return Manager::instance().getCallDetails (callID);
 }
 
+std::vector< std::string >
+CallManager::getCallList (void)
+{
+    return Manager::instance().getCallList();
+}
+        
 std::string 
 CallManager::getCurrentCallID(  )
 {
diff --git a/sflphone-common/src/dbus/callmanager.h b/sflphone-common/src/dbus/callmanager.h
index e1fc6de8fa..0d8a93a9a3 100644
--- a/sflphone-common/src/dbus/callmanager.h
+++ b/sflphone-common/src/dbus/callmanager.h
@@ -51,7 +51,10 @@ public:
     void setRecording( const std::string& callID );
     bool getIsRecording(const std::string& callID);
     std::string getCurrentCodecName(const std::string& callID);
+    
     std::map< std::string, std::string > getCallDetails( const std::string& callID );
+    std::vector< std::string > getCallList (void);
+
     std::string getCurrentCallID(  );
     void playDTMF( const std::string& key );
     void startTone( const int32_t& start, const int32_t& type );
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 1e9f84e97d..f41c99427e 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -2840,6 +2840,7 @@ std::map< std::string, std::string > ManagerImpl::getCallDetails(const CallID& c
         call_details.insert (std::pair<std::string, std::string> ("ACCOUNTID", accountid));
         call_details.insert (std::pair<std::string, std::string> ("PEER_NUMBER", call->getPeerNumber ()));
         call_details.insert (std::pair<std::string, std::string> ("PEER_NAME", call->getPeerName ()));
+        call_details.insert (std::pair<std::string, std::string> ("CALL_STATE", call->getStateStr (call->getState())));
     }
     else 
     {
@@ -2847,7 +2848,24 @@ std::map< std::string, std::string > ManagerImpl::getCallDetails(const CallID& c
         call_details.insert (std::pair<std::string, std::string> ("ACCOUNTID", AccountNULL));
         call_details.insert (std::pair<std::string, std::string> ("PEER_NUMBER", "Unknown"));
         call_details.insert (std::pair<std::string, std::string> ("PEER_NAME", "Unknown"));
+        call_details.insert (std::pair<std::string, std::string> ("CALL_STATE", "FAILURE"));
     }
 
     return call_details;
 }
+
+  std::vector< std::string >
+ManagerImpl::getCallList (void)
+{
+    std::vector< std::string > v;
+    int i;
+
+    CallAccountMap::iterator iter = _callAccountMap.begin ();
+
+    while (iter != _callAccountMap.end ()) {
+        v.push_back(iter->first.data());
+        iter++;
+    }   
+   
+    return v;
+}
diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h
index 10caf62b48..bb181657fc 100644
--- a/sflphone-common/src/managerimpl.h
+++ b/sflphone-common/src/managerimpl.h
@@ -301,6 +301,12 @@ class ManagerImpl {
      */
     std::map< std::string, std::string > getCallDetails(const CallID& callID);
 
+    /**
+     * Get call list
+     * @return std::vector<std::string> A list of call IDs
+     */
+    std::vector< std::string >  getCallList (void);
+
     /**
      * Save the details of an existing account, given the account ID
      * This will load the configuration map with the given data.
-- 
GitLab