From cb46f83e946b44eb3c7afcc939474a47f478dc5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?=
 <rafael.carre@savoirfairelinux.com>
Date: Fri, 26 Aug 2011 10:54:40 -0400
Subject: [PATCH] * #6738 : make history loading faster

general client cleanup / refactor
thread-safe clock updater thread stopping
fix double free on client exit
---
 gnome/src/actions.c                  | 119 ++++-----
 gnome/src/actions.h                  |   4 +-
 gnome/src/callable_obj.c             | 380 +++++++++------------------
 gnome/src/callable_obj.h             |  18 +-
 gnome/src/conference_obj.c           |   8 +-
 gnome/src/contacts/addrbookfactory.c | 106 +++-----
 gnome/src/contacts/calllist.c        |  54 ++--
 gnome/src/contacts/calltree.c        |  75 ++----
 gnome/src/contacts/history.c         | 112 ++++----
 gnome/src/contacts/history.h         |   7 +-
 gnome/src/contacts/searchbar.c       |  39 +--
 gnome/src/contacts/searchbar.h       |   5 -
 gnome/src/dbus/dbus.c                |  27 +-
 gnome/src/imwindow.c                 |   2 +-
 gnome/src/main.c                     |   6 +-
 gnome/src/mainwindow.c               |   6 +-
 gnome/src/uimanager.c                |   8 +-
 17 files changed, 345 insertions(+), 631 deletions(-)

diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 55a17aff3a..ecf1062343 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -250,6 +250,7 @@ sflphone_hung_up (callable_obj_t * c)
 #if GTK_CHECK_VERSION(2,10,0)
     status_tray_icon_blink (FALSE);
 #endif
+
     stop_call_clock(c);
     calltree_update_clock();
 }
@@ -385,9 +386,9 @@ void sflphone_fill_ip2ip_profile (void)
     ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
 }
 
-void sflphone_get_ip2ip_properties (GHashTable **properties)
+GHashTable *sflphone_get_ip2ip_properties(void)
 {
-    *properties	= ip2ip_profile;
+    return ip2ip_profile;
 }
 
 void
@@ -416,7 +417,7 @@ sflphone_hang_up()
                 dbus_hang_up (selectedCall);
                 call_remove_all_errors (selectedCall);
                 selectedCall->_state = CALL_STATE_DIALING;
-                set_timestamp (&selectedCall->_time_stop);
+                time (&selectedCall->_time_stop);
 
                 //if ( (im_window_get_nb_tabs() > 1) && selectedCall->_im_widget &&
                 //        ! (IM_WIDGET (selectedCall->_im_widget)->containText))
@@ -440,7 +441,7 @@ sflphone_hang_up()
             case CALL_STATE_TRANSFERT:
                 dbus_hang_up (selectedCall);
                 call_remove_all_errors (selectedCall);
-                set_timestamp (&selectedCall->_time_stop);
+                time (&selectedCall->_time_stop);
                 break;
             default:
                 WARN ("Should not happen in sflphone_hang_up()!");
@@ -453,78 +454,57 @@ sflphone_hang_up()
 
     calltree_update_call (history, selectedCall, NULL);
 
-    if (selectedCall)
-        stop_call_clock (selectedCall);
-
     calltree_update_clock();
 }
 
-
-void
-sflphone_conference_hang_up()
-{
-    conference_obj_t * selectedConf = calltab_get_selected_conf(current_calls);
-
-    if (selectedConf) {
-        dbus_hang_up_conference (selectedConf);
-    }
-}
-
-
 void
 sflphone_pick_up()
 {
-    callable_obj_t * selectedCall = NULL;
-    selectedCall = calltab_get_selected_call (active_calltree);
+    callable_obj_t *selectedCall = calltab_get_selected_call (active_calltree);
 
     DEBUG("SFLphone: Pick up");
 
-    if (selectedCall) {
-        switch (selectedCall->_state) {
-            case CALL_STATE_DIALING:
-                sflphone_place_call (selectedCall);
+    if (!selectedCall) {
+        sflphone_new_call();
+        return;
+    }
+    switch (selectedCall->_state) {
+        case CALL_STATE_DIALING:
+            sflphone_place_call (selectedCall);
 
-                // if instant messaging window is visible, create new tab (deleted automatically if not used)
-                if (im_window_is_visible())
-                    im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
+            // if instant messaging window is visible, create new tab (deleted automatically if not used)
+            if (im_window_is_visible())
+                im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
 
-                break;
-            case CALL_STATE_INCOMING:
-                selectedCall->_history_state = INCOMING;
-                calltree_update_call (history, selectedCall, NULL);
+            break;
+        case CALL_STATE_INCOMING:
+            selectedCall->_history_state = INCOMING;
+            calltree_update_call (history, selectedCall, NULL);
 
-                // if instant messaging window is visible, create new tab (deleted automatically if not used)
-                if (selectedCall->_im_widget && im_window_is_visible()) {
-                    im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
-	        }
+            // if instant messaging window is visible, create new tab (deleted automatically if not used)
+            if (selectedCall->_im_widget && im_window_is_visible()) {
+                im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
+            }
 
-                dbus_accept (selectedCall);
-                stop_notification();
-                break;
-            case CALL_STATE_HOLD:
-                sflphone_new_call();
-                break;
-            case CALL_STATE_TRANSFERT:
-                dbus_transfert (selectedCall);
-                set_timestamp (&selectedCall->_time_stop);
-                calltree_remove_call(current_calls, selectedCall, NULL);
-                calllist_remove_call(current_calls, selectedCall->_callID);
-		break;
-            case CALL_STATE_CURRENT:
-            case CALL_STATE_RECORD:
-                sflphone_new_call();
-                break;
-            case CALL_STATE_RINGING:
-                sflphone_new_call();
-                break;
-            default:
-                WARN ("Should not happen in sflphone_pick_up()!");
-                break;
-        }
-    } else {
-        sflphone_new_call();
+            dbus_accept (selectedCall);
+            stop_notification();
+            break;
+        case CALL_STATE_TRANSFERT:
+            dbus_transfert (selectedCall);
+            time (&selectedCall->_time_stop);
+            calltree_remove_call(current_calls, selectedCall, NULL);
+            calllist_remove_call(current_calls, selectedCall->_callID);
+            break;
+        case CALL_STATE_CURRENT:
+        case CALL_STATE_HOLD:
+        case CALL_STATE_RECORD:
+        case CALL_STATE_RINGING:
+            sflphone_new_call();
+            break;
+        default:
+            WARN ("Should not happen in sflphone_pick_up()!");
+            break;
     }
-
 }
 
 void
@@ -597,7 +577,7 @@ sflphone_current (callable_obj_t * c)
 {
 
     if (c->_state != CALL_STATE_HOLD)
-        set_timestamp (&c->_time_start);
+        time (&c->_time_start);
 
     c->_state = CALL_STATE_CURRENT;
     calltree_update_call (current_calls, c, NULL);
@@ -608,7 +588,7 @@ void
 sflphone_record (callable_obj_t * c)
 {
     if (c->_state != CALL_STATE_HOLD)
-        set_timestamp (&c->_time_start);
+        time (&c->_time_start);
 
     c->_state = CALL_STATE_RECORD;
     calltree_update_call (current_calls, c, NULL);
@@ -804,7 +784,7 @@ sflphone_keypad (guint keyval, gchar * key)
                 switch (keyval) {
                     case 65307: /* ESCAPE */
                         dbus_hang_up (c);
-                        set_timestamp (&c->_time_stop);
+                        time (&c->_time_stop);
                         calltree_update_call (history, c, NULL);
                         break;
                     default:
@@ -839,7 +819,7 @@ sflphone_keypad (guint keyval, gchar * key)
                     case 65293: /* ENTER */
                     case 65421: /* ENTER numpad */
                         dbus_transfert (c);
-                        set_timestamp (&c->_time_stop);
+                        time (&c->_time_stop);
                         calltree_remove_call(current_calls, c, NULL);
 			calllist_remove_call(current_calls, c->_callID);
                         break;
@@ -1066,7 +1046,7 @@ sflphone_add_participant (const gchar* callID, const gchar* confID)
         return;
     }
 
-    set_timestamp(&call->_time_added);
+    time(&call->_time_added);
 
     iter = calltree_get_gtkiter_from_id(history, (gchar *)confID);
 
@@ -1397,7 +1377,7 @@ void sflphone_save_history (void)
             ERROR("SFLphone: Error: Unknown type for serialization");
             break;
         }
-        gchar *key = convert_timestamp_to_gchar (current->elem.call->_time_start);
+        gchar *key = g_strdup_printf ("%i", (int) current->elem.call->_time_start);
 
         g_hash_table_replace (result, (gpointer) key,
                 g_slist_append(g_hash_table_lookup(result, key),(gpointer) value));
@@ -1412,7 +1392,7 @@ void sflphone_save_history (void)
         }
 
         gchar *value = serialize_history_conference_entry(conf);
-        gchar *key = convert_timestamp_to_gchar(conf->_time_start);
+        gchar *key = g_strdup_printf ("%i", (int) conf->_time_start);
 
         g_hash_table_replace(result, (gpointer) key,
                 g_slist_append(g_hash_table_lookup(result, key), (gpointer) value));
@@ -1427,7 +1407,6 @@ void sflphone_save_history (void)
 void
 sflphone_srtp_sdes_on (callable_obj_t * c)
 {
-
     c->_srtp_state = SRTP_STATE_SDES_SUCCESS;
 
     calltree_update_call (current_calls, c, NULL);
diff --git a/gnome/src/actions.h b/gnome/src/actions.h
index d37241d54c..8415cdba06 100644
--- a/gnome/src/actions.h
+++ b/gnome/src/actions.h
@@ -172,7 +172,7 @@ void sflphone_fill_ip2ip_profile (void);
  * @return The internal hash table representing
  * the settings for the ip2ip profile.
  */
-void sflphone_get_ip2ip_properties (GHashTable **properties);
+GHashTable *sflphone_get_ip2ip_properties(void);
 
 /**
  * Initialize the accounts data structure
@@ -314,6 +314,4 @@ void sflphone_fill_conference_list (void);
 
 void sflphone_conference_on_hold (const conference_obj_t * c);
 
-void sflphone_conference_hang_up();
-
 #endif
diff --git a/gnome/src/callable_obj.c b/gnome/src/callable_obj.c
index 262b93bcc0..8367823524 100644
--- a/gnome/src/callable_obj.c
+++ b/gnome/src/callable_obj.c
@@ -33,67 +33,61 @@
 #include <sflphone_const.h>
 #include <time.h>
 #include "contacts/calltree.h"
-#include  <unistd.h>
+#include <unistd.h>
+#include <assert.h>
 
 
 gint get_state_callstruct (gconstpointer a, gconstpointer b)
 {
     callable_obj_t * c = (callable_obj_t*) a;
+    call_state_t state = *((call_state_t*)b);
 
-    if (c->_state == * ( (call_state_t*) b)) {
-        return 0;
-    } else {
-        return 1;
-    }
+    return c->_state == state ? 0 : 1;
 }
 
 gchar* call_get_peer_name (const gchar *format)
 {
-    const gchar *end, *name;
-
-    DEBUG ("    callable_obj: %s", format);
-
-    end = g_strrstr (format, "<");
-
-    if (!end) {
-        return g_strndup (format, 0);
-    } else {
-        name = format;
-        return g_strndup (name, end - name);
-    }
+    const gchar *end = g_strrstr (format, "<");
+    return g_strndup (format, end ? end - format : 0);
 }
 
 gchar* call_get_peer_number (const gchar *format)
 {
-    DEBUG ("    callable_obj: %s", format);
-
-    gchar * number = g_strrstr (format, "<") + 1;
-    gchar * end = g_strrstr (format, ">");
+    gchar *number = g_strrstr (format, "<") + 1;
+    gchar *end = g_strrstr (format, ">");
 
     if (end && number)
-        number = g_strndup (number, end - number);
+        return g_strndup (number, end - number);
     else
-        number = g_strdup (format);
-
-    return number;
+        return g_strdup (format);
 }
 
 gchar* call_get_audio_codec (callable_obj_t *obj)
 {
-    if (obj) {
-        gchar * const audio_codec = dbus_get_current_audio_codec_name (obj);
-        account_t *acc = account_list_get_by_id(obj->_accountID);
-        if (acc) {
-            const codec_t * const codec = codec_list_get_by_name (audio_codec, acc->codecs);
-            if (codec) {
-                gchar *result = g_markup_printf_escaped ("%s/%i", audio_codec, codec->sample_rate);
-                g_free (audio_codec);
-                return result;
-            }
-        }
-    }
-
-    return g_strdup("");
+    gchar *ret = NULL;
+    gchar *audio_codec = NULL;
+    if (!obj)
+        goto out;
+
+    audio_codec = dbus_get_current_audio_codec_name (obj);
+    if (!audio_codec)
+        goto out;
+
+    account_t *acc = account_list_get_by_id(obj->_accountID);
+    if (!acc)
+        goto out;
+
+    const codec_t *const codec = codec_list_get_by_name (audio_codec, acc->codecs);
+    if (!codec)
+        goto out;
+
+    ret = g_strdup_printf("%s/%i", audio_codec, codec->sample_rate);
+
+out:
+    g_free(audio_codec);
+    if (ret == NULL)
+        return g_strdup("");
+    return ret;
 }
 
 void call_add_error (callable_obj_t * call, gpointer dialog)
@@ -111,44 +105,16 @@ void call_remove_all_errors (callable_obj_t * call)
     g_ptr_array_foreach (call->_error_dialogs, (GFunc) gtk_widget_destroy, NULL);
 }
 
-void threaded_clock_incrementer (void *pc)
+static void threaded_clock_incrementer (void *pc)
 {
-
     callable_obj_t *call = (callable_obj_t *) pc;
 
-
-    while (call->clockStarted) {
-
-        int duration;
-        time_t start, current;
-
+    for(;;) {
         gdk_threads_enter ();
 
-        set_timestamp (& (call->_time_current));
-
-        start = call->_time_start;
-        current = call->_time_current;
-
-        if (current == start) {
-            g_snprintf (call->_timestr, 20, "00:00");
-
-        }
+        int duration = difftime (time(NULL), call->_time_start);
 
-        duration = (int) difftime (current, start);
-
-        if (duration / 60 == 0) {
-            if (duration < 10) {
-                g_snprintf (call->_timestr, 20, "00:0%d", duration);
-            } else {
-                g_snprintf (call->_timestr, 20, "00:%d", duration);
-            }
-        } else {
-            if (duration%60 < 10) {
-                g_snprintf (call->_timestr, 20, "0%d:0%d", duration/60, duration%60);
-            } else {
-                g_snprintf (call->_timestr, 20, "%d:%d", duration/60, duration%60);
-            }
-        }
+        g_snprintf (call->_timestr, 20, "%.2d:%.2d", duration % 60, duration / 60);
 
         // Update clock only if call is active (current, hold, recording transfer)
         if ( (call->_state != CALL_STATE_INVALID) &&
@@ -160,23 +126,37 @@ void threaded_clock_incrementer (void *pc)
             calltree_update_clock();
         }
 
-        // gdk_flush();
         gdk_threads_leave ();
 
+        GTimeVal abs_time;
+        g_get_current_time(&abs_time);
+        g_time_val_add(&abs_time, 1000000);
+        g_mutex_lock(call->mutex);
+        g_cond_timed_wait(call->cond, call->mutex, &abs_time);
+        gboolean ret = call->exitClockThread;
+        g_mutex_unlock(call->mutex);
 
-        usleep (1000000);
+        if (ret == TRUE)
+            break;
     }
 
-    DEBUG ("CallableObj: Stopping Thread");
-
     g_thread_exit (NULL);
-
 }
 
 void stop_call_clock (callable_obj_t *c)
 {
-    if (c->_type == CALL && c->clockStarted)
-        c->clockStarted = 0;
+    assert(c->_type == CALL);
+
+    g_mutex_lock(c->mutex);
+    c->exitClockThread = TRUE;
+    g_cond_signal(c->cond);
+    g_mutex_unlock(c->mutex);
+
+    g_thread_join(c->clock_thread);
+    g_mutex_free(c->mutex);
+    g_cond_free(c->cond);
+
+    c->clock_thread = NULL;
 }
 
 callable_obj_t *create_new_call (callable_type_t type, call_state_t state,
@@ -187,41 +167,26 @@ callable_obj_t *create_new_call (callable_type_t type, call_state_t state,
 {
     DEBUG ("CallableObj: Create new call (Account: %s)", accountID);
 
-    // Allocate memory
     callable_obj_t *obj = g_new0 (callable_obj_t, 1);
 
     obj->_error_dialogs = g_ptr_array_new();
-
-    // Set fields
     obj->_type = type;
     obj->_state = state;
-
-    if (g_strcasecmp (callID, "") == 0)
-    {
-        obj->_callID = g_new0 (gchar, 30);
-        if (obj->_callID)
-            g_sprintf (obj->_callID, "%d", rand());
-    }
-    else
-        obj->_callID = g_strdup (callID);
-
+    obj->_callID = *callID ? g_strdup (callID) : g_strdup_printf("%d", rand());
     obj->_accountID = g_strdup (accountID);
 
-    set_timestamp (& (obj->_time_start));
-    set_timestamp (& (obj->_time_current));
-    set_timestamp (& (obj->_time_stop));
+    time (&obj->_time_start);
+    time (&obj->_time_stop);
 
     obj->_peer_name = g_strdup (peer_name);
     obj->_peer_number = g_strdup (peer_number);
     obj->_peer_info = get_peer_info (peer_name, peer_number);
-    obj->clockStarted = 1;
 
     if (obj->_type == CALL) {
-        GError *err1 = NULL ;
-        if (!g_thread_create ( (GThreadFunc) threaded_clock_incrementer, (void *) obj, TRUE, &err1)) {
-            DEBUG ("Thread creation failed!");
-            g_error_free (err1) ;
-        }
+        obj->mutex = g_mutex_new();
+        obj->cond = g_cond_new();
+        obj->exitClockThread = FALSE;
+        obj->clock_thread = g_thread_create((GThreadFunc) threaded_clock_incrementer, (void *) obj, TRUE, NULL);
     }
 
     return obj;
@@ -238,23 +203,21 @@ callable_obj_t *create_new_call_from_details (const gchar *call_id, GHashTable *
 
     if (g_strcasecmp (state_str, "CURRENT") == 0)
         state = CALL_STATE_CURRENT;
-
     else if (g_strcasecmp (state_str, "RINGING") == 0)
         state = CALL_STATE_RINGING;
-
     else if (g_strcasecmp (state_str, "INCOMING") == 0)
         state = CALL_STATE_INCOMING;
-
     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;
 
-    return create_new_call (CALL, state, call_id, accountID, peer_name, call_get_peer_number (peer_number));
+    gchar *number = call_get_peer_number (peer_number);
+    callable_obj_t *c = create_new_call (CALL, state, call_id, accountID, peer_name, number);
+    g_free(number);
+    return c;
 }
 
 callable_obj_t *create_history_entry_from_serialized_form (const gchar *entry)
@@ -268,66 +231,37 @@ callable_obj_t *create_history_entry_from_serialized_form (const gchar *entry)
     const gchar *recordfile = "";
     const gchar *confID = "";
     const gchar *time_added = "";
-    callable_obj_t *new_call;
     history_state_t history_state = MISSED;
-    gint token = 0;
-    gchar ** ptr;
-    gchar ** ptr_orig;
-    static const gchar * const delim = "|";
-
-    ptr = g_strsplit(entry, delim, 10);
-    ptr_orig = ptr;
-    while (ptr != NULL && token < 10) {
+
+    gchar **ptr_orig = g_strsplit(entry, "|", 10);
+    gchar **ptr;
+    gint token;
+    for (ptr = ptr_orig, token = 0; ptr && token < 10; token++, ptr++)
         switch (token) {
-            case 0:
-                history_state = get_history_state_from_id (*ptr);
-                break;
-            case 1:
-                peer_number = *ptr;
-                break;
-            case 2:
-                peer_name = *ptr;
-                break;
-            case 3:
-		time_start = *ptr;
-		break;
-	    case 4:
-                time_stop = *ptr;
-                break;
-	    case 5:
-		callID = *ptr;
-		break;
-            case 6:
-                accountID = *ptr;
-                break;
-            case 7:
-		recordfile = *ptr;
-		break;
-	    case 8:
-		confID = *ptr;
-		break;
-	    case 9:
-		time_added = *ptr;
-		break;
-            default:
-                break;
+            case 0:     history_state = get_history_state_from_id (*ptr); break;
+            case 1:     peer_number = *ptr;     break;
+            case 2:     peer_name = *ptr;       break;
+            case 3:     time_start = *ptr;      break;
+	    case 4:     time_stop = *ptr;       break;
+	    case 5:     callID = *ptr;          break;
+            case 6:     accountID = *ptr;       break;
+            case 7:     recordfile = *ptr;      break;
+	    case 8:     confID = *ptr;          break;
+	    case 9:     time_added = *ptr;      break;
+            default:                            break;
         }
 
-        token++;
-        ptr++;
-    }
-
     if (g_strcasecmp (peer_name, "empty") == 0)
         peer_name = "";
 
-    new_call = create_new_call (HISTORY_ENTRY, CALL_STATE_DIALING, callID, accountID, peer_name, peer_number);
+    callable_obj_t *new_call = create_new_call (HISTORY_ENTRY, CALL_STATE_DIALING, callID, accountID, peer_name, peer_number);
     new_call->_history_state = history_state;
-    new_call->_time_start = convert_gchar_to_timestamp (time_start);
-    new_call->_time_stop = convert_gchar_to_timestamp (time_stop);
+    new_call->_time_start = atoi(time_start);
+    new_call->_time_stop = atoi(time_stop);
     new_call->_recordfile = g_strdup(recordfile);
     new_call->_confID = g_strdup(confID);
     new_call->_historyConfID = g_strdup(confID);
-    new_call->_time_added = convert_gchar_to_timestamp(time_start);
+    new_call->_time_added = atoi(time_start);
     new_call->_record_is_playing = FALSE;
 
     g_strfreev(ptr_orig);
@@ -336,10 +270,6 @@ callable_obj_t *create_history_entry_from_serialized_form (const gchar *entry)
 
 void free_callable_obj_t (callable_obj_t *c)
 {
-    DEBUG ("CallableObj: Free callable object");
-
-    stop_call_clock (c);
-
     g_free (c->_callID);
     g_free (c->_confID);
     g_free (c->_historyConfID);
@@ -357,11 +287,6 @@ void free_callable_obj_t (callable_obj_t *c)
     calltree_update_clock();
 }
 
-void attach_thumbnail (callable_obj_t *call, GdkPixbuf *pixbuf)
-{
-    call->_contact_thumbnail = pixbuf;
-}
-
 gchar* get_peer_info (const gchar* const number, const gchar* const name)
 {
     return g_strconcat ("\"", name, "\" <", number, ">", NULL);
@@ -369,16 +294,9 @@ gchar* get_peer_info (const gchar* const number, const gchar* const name)
 
 history_state_t get_history_state_from_id (gchar *indice)
 {
+    history_state_t state = atoi(indice);
 
-    history_state_t state;
-
-    if (g_strcasecmp (indice, "0") ==0)
-        state = MISSED;
-    else if (g_strcasecmp (indice, "1") ==0)
-        state = INCOMING;
-    else if (g_strcasecmp (indice, "2") ==0)
-        state = OUTGOING;
-    else
+    if (state > LAST)
         state = MISSED;
 
     return state;
@@ -386,34 +304,10 @@ history_state_t get_history_state_from_id (gchar *indice)
 
 gchar* get_call_duration (callable_obj_t *obj)
 {
-    int duration;
-    time_t start, end;
-
-    start = obj->_time_start;
-    end = obj->_time_stop;
-
-    if (start == end)
-        return g_markup_printf_escaped ("<small>Duration:</small> 0:00");
-
-    duration = (int) difftime (end, start);
-    gchar *result;
-
-    if (duration / 60 == 0) {
-        if (duration < 10)
-            result = g_markup_printf_escaped ("00:0%i", duration);
-        else
-            result = g_markup_printf_escaped ("00:%i", duration);
-    } else {
-        if (duration%60 < 10)
-            result = g_markup_printf_escaped ("%i:0%i" , duration/60 , duration%60);
-        else
-            result = g_markup_printf_escaped ("%i:%i" , duration/60 , duration%60);
-    }
-
-    gchar *old_result = result;
-    result = g_markup_printf_escaped ("<small>Duration:</small> %s", old_result);
-    g_free(old_result);
-    return result;
+    long duration = difftime (obj->_time_stop, obj->_time_start);
+    if (duration < 0)
+        duration = 0;
+    return g_strdup_printf("<small>Duration:</small> %.2ld:%.2ld" , duration/60 , duration%60);
 }
 
 static const gchar* get_history_id_from_state (history_state_t state)
@@ -436,16 +330,15 @@ gchar* serialize_history_call_entry (callable_obj_t *entry)
     // Need the string form for the history state
     const gchar *history_state = get_history_id_from_state (entry->_history_state);
     // and the timestamps
-    time_start = convert_timestamp_to_gchar (entry->_time_start);
-    time_stop = convert_timestamp_to_gchar (entry->_time_stop);
-    time_added = convert_timestamp_to_gchar (entry->_time_added);
+    time_start = g_strdup_printf ("%i", (int) entry->_time_start);
+    time_stop = g_strdup_printf ("%i", (int) entry->_time_stop);
+    time_added = g_strdup_printf ("%i", (int) entry->_time_added);
 
     peer_number = entry->_peer_number ? entry->_peer_number : "";
     peer_name = (entry->_peer_name && *entry->_peer_name) ? entry->_peer_name : "empty";
     account_id = (entry->_accountID && *entry->_accountID) ? entry->_accountID : "empty";
 
     confID = entry->_historyConfID ? entry->_historyConfID : "";
-
     record_file = entry->_recordfile ? entry->_recordfile : "";
 
     gchar *result = g_strconcat (history_state, separator,
@@ -464,63 +357,32 @@ gchar* serialize_history_call_entry (callable_obj_t *entry)
     return result;
 }
 
-gchar *get_formatted_start_timestamp (time_t time_start)
+gchar *get_formatted_start_timestamp (time_t start)
 {
-    enum { UNIX_DAY = 86400,
-           UNIX_WEEK = UNIX_DAY * 6,
-           UNIX_TWO_DAYS = UNIX_DAY * 2};
-
-    struct tm* ptr;
-    time_t lt, now;
-    unsigned char str[100];
-
-    // Fetch the current timestamp
-    (void) time (&now);
-    lt = time_start;
-
-    ptr = localtime (&lt);
-
-    if (now - lt < UNIX_WEEK) {
-        if (now-lt < UNIX_DAY) {
-            strftime ( (char *) str, 100, N_ ("today at %R"), (const struct tm *) ptr);
+    time_t now = time (NULL);
+    struct tm start_tm;
+
+    localtime_r (&start, &start_tm);
+    time_t diff = now - start;
+    if (diff < 0)
+        diff = 0;
+    const char *fmt;
+
+    if (diff < 60 * 60 * 24 * 7) { // less than 1 week
+        if (diff < 60 * 60 * 24) { // less than 1 day
+            fmt = N_("today at %R");
         } else {
-            if (now - lt < UNIX_TWO_DAYS) {
-                strftime ( (char *) str, 100, N_ ("yesterday at %R"), (const struct tm *) ptr);
-            } else {
-                strftime ( (char *) str, 100, N_ ("%A at %R"), (const struct tm *) ptr);
+            if (diff < 60 * 60 * 24 * 2) { // less than 2 days
+                fmt = N_("yesterday at %R");
+            } else { // between 2 days and 1 week
+                fmt = N_("%A at %R");
             }
         }
-    } else {
-        strftime ( (char *) str, 100, N_ ("%x at %R"), (const struct tm *) ptr);
+    } else { // more than 1 week
+        fmt = N_("%x at %R");
     }
 
-    // result function of the current locale
-    return g_markup_printf_escaped ("\n%s\n" , str);
-}
-
-void set_timestamp (time_t *timestamp)
-{
-    time_t tmp;
-
-    // Set to the current value
-    (void) time (&tmp);
-    *timestamp=tmp;
-}
-
-gchar* convert_timestamp_to_gchar (const time_t timestamp)
-{
-    return g_markup_printf_escaped ("%i", (int) timestamp);
+    char str[100];
+    strftime(str, sizeof str, fmt, &start_tm);
+    return g_markup_printf_escaped ("%s\n", str);
 }
-
-time_t convert_gchar_to_timestamp (const gchar *timestamp)
-{
-    return (time_t) atoi (timestamp);
-}
-
-gchar*
-get_peer_information (callable_obj_t *c)
-{
-    return *c->_peer_name ? c->_peer_name : c->_peer_number;
-}
-
-
diff --git a/gnome/src/callable_obj.h b/gnome/src/callable_obj.h
index e0eb7ccdf5..e430e65961 100644
--- a/gnome/src/callable_obj.h
+++ b/gnome/src/callable_obj.h
@@ -109,7 +109,6 @@ typedef struct  {
     gchar* _historyConfID;	    // Persistent conf id to be stored in history
     gchar* _accountID;              // The account the call is made with
     time_t _time_start;             // The timestamp the call was initiating
-    time_t _time_current;           // Clock increment to display call's elapsed time
     time_t _time_stop;              // The timestamp the call was over
     gchar _timestr[20];             // The timestamp as a string format for disply in statusbar
     history_state_t _history_state; // The history state if necessary
@@ -164,10 +163,12 @@ typedef struct  {
     /* Associated IM widget */
     GtkWidget *_im_widget;
 
-    int clockStarted;
-
     time_t _time_added;
 
+    GThread *clock_thread;
+    GCond *cond;
+    GMutex *mutex;
+    gboolean exitClockThread;
 } callable_obj_t;
 
 callable_obj_t *create_new_call (callable_type_t, call_state_t, const gchar* const, const gchar* const, const gchar* const, const gchar* const);
@@ -206,9 +207,6 @@ gchar* call_get_peer_name (const gchar*);
  */
 gchar* call_get_peer_number (const gchar*);
 
-void
-attach_thumbnail (callable_obj_t *, GdkPixbuf *);
-
 void
 free_callable_obj_t (callable_obj_t *c);
 
@@ -225,14 +223,6 @@ gchar* serialize_history_call_entry(callable_obj_t *entry);
 
 gchar* get_formatted_start_timestamp (time_t);
 
-void set_timestamp (time_t*);
-
-gchar* convert_timestamp_to_gchar (time_t);
-
-time_t convert_gchar_to_timestamp (const gchar*);
-
 gchar* call_get_audio_codec (callable_obj_t *obj);
 
-gchar* get_peer_information (callable_obj_t *c);
-
 #endif
diff --git a/gnome/src/conference_obj.c b/gnome/src/conference_obj.c
index 6cfc10cd46..f2b2dc3d1d 100644
--- a/gnome/src/conference_obj.c
+++ b/gnome/src/conference_obj.c
@@ -227,8 +227,8 @@ gchar *serialize_history_conference_entry(conference_obj_t *entry)
 
     confID = entry->_confID;
 
-    time_start = convert_timestamp_to_gchar(entry->_time_start);
-    time_stop = convert_timestamp_to_gchar(entry->_time_stop);
+    time_start = g_strdup_printf ("%i", (int) entry->_time_start);
+    time_stop = g_strdup_printf ("%i", (int) entry->_time_stop);
 
     peer_name = (entry->_confID == NULL || g_strcasecmp(entry->_confID, "") == 0) ? "empty": entry->_confID;
 
@@ -314,8 +314,8 @@ conference_obj_t *create_conference_history_entry_from_serialized(gchar *entry)
     // create a new empty conference
     conference_obj_t *conf = create_new_conference(state, confID);
 
-    conf->_time_start = convert_gchar_to_timestamp(time_start);
-    conf->_time_stop = convert_gchar_to_timestamp(time_stop);
+    conf->_time_start = atoi(time_start);
+    conf->_time_stop = atoi(time_stop);
     conf->_recordfile = g_strdup(recordfile);
 
     return conf;
diff --git a/gnome/src/contacts/addrbookfactory.c b/gnome/src/contacts/addrbookfactory.c
index c1882fb082..08a9319ce1 100644
--- a/gnome/src/contacts/addrbookfactory.c
+++ b/gnome/src/contacts/addrbookfactory.c
@@ -55,69 +55,57 @@ void abookfactory_scan_directory(AddrBookFactory *factory UNUSED) {
     
 }
 
-void abookfactory_load_module(AddrBookFactory *factory) {
-
-    AddrBookHandle *ab;
-    void *handle;
-
+void abookfactory_load_module(AddrBookFactory *factory)
+{
     gchar *plugindir = PLUGINS_DIR;
     gchar *pluginpath = g_strdup_printf("%s/libevladdrbook.so", plugindir);
 
     DEBUG("AddressbookFactory: Loading addressbook: %s", pluginpath);
 
-    handle = dlopen(pluginpath, RTLD_LAZY);
+    void *handle = dlopen(pluginpath, RTLD_LAZY);
     g_free(pluginpath);
     if(handle == NULL) {
         ERROR("AddressbookFactory: Error: Could not load addressbook");
         return;
     }
 
-    ab = g_malloc(sizeof(AddrBookHandle));
+    AddrBookHandle *ab = g_malloc(sizeof(AddrBookHandle));
 
     ab->init = dlsym(handle, "addressbook_init");
-    if(ab->init == NULL) {
+    if(ab->init == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook_init function");
-    }   
  
     ab->is_ready = dlsym(handle, "addressbook_is_ready");
-    if(ab->is_ready == NULL) {
+    if(ab->is_ready == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_is_ready function");
-    }
 
     ab->is_enabled = dlsym(handle, "addressbook_is_enabled");
-    if(ab->is_enabled == NULL) {
+    if(ab->is_enabled == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_is_enabled function");
-    }
 
     ab->is_active = dlsym(handle, "addressbook_is_active");
-    if(ab->is_active == NULL) {
+    if(ab->is_active == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_is_active function");
-    }
 
     ab->search = dlsym(handle, "addressbook_search");
-    if(ab->search == NULL) {
+    if(ab->search == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_search function");
-    }
 
     ab->get_books_data = dlsym(handle, "addressbook_get_books_data");
-    if(ab->get_books_data == NULL) {
+    if(ab->get_books_data == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_get_books_data function");
-    }
 
     ab->get_book_data_by_uid = dlsym(handle, "addressbook_get_book_data_by_uid");
-    if(ab->get_book_data_by_uid == NULL) {
+    if(ab->get_book_data_by_uid == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_get_books_data_by_uid function");
-    }
 
     ab->set_current_book = dlsym(handle, "addressbook_set_current_book");
-    if(ab->set_current_book == NULL) {
+    if(ab->set_current_book == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_ser_current_book");
-    }
 
     ab->set_search_type = dlsym(handle, "addressbook_set_search_type");
-    if(ab->set_search_type == NULL) {
+    if(ab->set_search_type == NULL)
         ERROR("AddressbookFactory: Error: Could not load addressbook addressbook_set_search_type");
-    }
 
     ab->search_cb = handler_async_search;
 
@@ -141,55 +129,43 @@ free_hit (Hit *h)
 static void
 handler_async_search (GList *hits, gpointer user_data)
 {
-
     GList *i;
-    GdkPixbuf *photo = NULL;
-    AddressBook_Config *addressbook_config;
-    callable_obj_t *j;
-
-    printf("Addressbook: callback async search\n");
-
-    // freeing calls
-    while ( (j = (callable_obj_t *) g_queue_pop_tail (contacts->callQueue)) != NULL) {
-        free_callable_obj_t (j);
-    }
 
     // Retrieve the address book parameters
-    addressbook_config = (AddressBook_Config*) user_data;
+    AddressBook_Config *addressbook_config = user_data;
 
     // reset previous results
     calltree_reset (contacts);
     calllist_reset (contacts);
 
     for (i = hits; i != NULL; i = i->next) {
-
-        Hit *entry;
-        entry = i->data;
-
-        if (entry) {
-            // Get the photo
-            if (addressbook_display (addressbook_config,
-                                     ADDRESSBOOK_DISPLAY_CONTACT_PHOTO))
-                photo = entry->photo;
-
-            // Create entry for business phone information
-            if (addressbook_display (addressbook_config,
-                                     ADDRESSBOOK_DISPLAY_PHONE_BUSINESS))
-                calllist_add_contact (entry->name, entry->phone_business,
-                                      CONTACT_PHONE_BUSINESS, photo);
-
-            // Create entry for home phone information
-            if (addressbook_display (addressbook_config,
-                                     ADDRESSBOOK_DISPLAY_PHONE_HOME))
-                calllist_add_contact (entry->name, entry->phone_home,
-                                      CONTACT_PHONE_HOME, photo);
-
-            // Create entry for mobile phone iddnformation
-            if (addressbook_display (addressbook_config,
-                                     ADDRESSBOOK_DISPLAY_PHONE_MOBILE))
-                calllist_add_contact (entry->name, entry->phone_mobile,
-                                      CONTACT_PHONE_MOBILE, photo);
-        }
+        GdkPixbuf *photo = NULL;
+        Hit *entry = i->data;
+        if (!entry)
+          continue;
+
+        // Get the photo
+        if (addressbook_display (addressbook_config,
+                                 ADDRESSBOOK_DISPLAY_CONTACT_PHOTO))
+            photo = entry->photo;
+
+        // Create entry for business phone information
+        if (addressbook_display (addressbook_config,
+                                 ADDRESSBOOK_DISPLAY_PHONE_BUSINESS))
+            calllist_add_contact (entry->name, entry->phone_business,
+                                  CONTACT_PHONE_BUSINESS, photo);
+
+        // Create entry for home phone information
+        if (addressbook_display (addressbook_config,
+                                 ADDRESSBOOK_DISPLAY_PHONE_HOME))
+            calllist_add_contact (entry->name, entry->phone_home,
+                                  CONTACT_PHONE_HOME, photo);
+
+        // Create entry for mobile phone iddnformation
+        if (addressbook_display (addressbook_config,
+                                 ADDRESSBOOK_DISPLAY_PHONE_MOBILE))
+            calllist_add_contact (entry->name, entry->phone_mobile,
+                                  CONTACT_PHONE_MOBILE, photo);
 
         free_hit (entry);
     }
diff --git a/gnome/src/contacts/calllist.c b/gnome/src/contacts/calllist.c
index 74d93caeae..cb9eb87669 100644
--- a/gnome/src/contacts/calllist.c
+++ b/gnome/src/contacts/calllist.c
@@ -60,39 +60,37 @@ gint is_callID_callstruct(gconstpointer a, gconstpointer b)
 // TODO : sflphoneGTK : try to do this more generic
 void calllist_add_contact (gchar *contact_name, gchar *contact_phone, contact_type_t type, GdkPixbuf *photo)
 {
+    /* Check if the information is valid */
+    if (g_strcasecmp (contact_phone, EMPTY_ENTRY) == 0)
+        return;
 
-    callable_obj_t *new_call;
-    GdkPixbuf *pixbuf;
+    callable_obj_t *new_call = create_new_call (CONTACT, CALL_STATE_DIALING, "", "", contact_name, contact_phone);
 
-    /* Check if the information is valid */
-    if (g_strcasecmp (contact_phone, EMPTY_ENTRY) != 0) {
-        new_call = create_new_call (CONTACT, CALL_STATE_DIALING, "", "", contact_name, contact_phone);
-
-        // Attach a pixbuf to a contact
-        if (photo) {
-            attach_thumbnail (new_call, gdk_pixbuf_copy (photo));
-        } else {
-            switch (type) {
-                case CONTACT_PHONE_BUSINESS:
-                    pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/users.svg", NULL);
-                    break;
-                case CONTACT_PHONE_HOME:
-                    pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/home.svg", NULL);
-                    break;
-                case CONTACT_PHONE_MOBILE:
-                    pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/phone.svg", NULL);
-                    break;
-                default:
-                    pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/contact_default.svg", NULL);
-                    break;
-            }
-
-            attach_thumbnail (new_call, pixbuf);
+    // Attach a pixbuf to a contact
+    if (photo) {
+        new_call->_contact_thumbnail = gdk_pixbuf_copy (photo);
+    } else {
+        GdkPixbuf *pixbuf;
+        switch (type) {
+            case CONTACT_PHONE_BUSINESS:
+                pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/users.svg", NULL);
+                break;
+            case CONTACT_PHONE_HOME:
+                pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/home.svg", NULL);
+                break;
+            case CONTACT_PHONE_MOBILE:
+                pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/phone.svg", NULL);
+                break;
+            default:
+                pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/contact_default.svg", NULL);
+                break;
         }
 
-        calllist_add_call (contacts, new_call);
-        calltree_add_call (contacts, new_call, NULL);
+        new_call->_contact_thumbnail = pixbuf;
     }
+
+    calllist_add_call (contacts, new_call);
+    calltree_add_call (contacts, new_call, NULL);
 }
 
 void
diff --git a/gnome/src/contacts/calltree.c b/gnome/src/contacts/calltree.c
index 2cb65c5beb..3c7f779d69 100644
--- a/gnome/src/contacts/calltree.c
+++ b/gnome/src/contacts/calltree.c
@@ -329,9 +329,7 @@ row_single_click (GtkTreeView *tree_view UNUSED, void * data UNUSED)
                 displaySasOnce = g_hash_table_lookup (account_details->properties, ACCOUNT_DISPLAY_SAS_ONCE);
                 DEBUG ("Display SAS once %s", displaySasOnce);
             } else {
-                GHashTable * properties = NULL;
-                sflphone_get_ip2ip_properties (&properties);
-
+                GHashTable *properties = sflphone_get_ip2ip_properties();
                 if (properties != NULL) {
                     displaySasOnce = g_hash_table_lookup (properties, ACCOUNT_DISPLAY_SAS_ONCE);
                     DEBUG ("IP2IP displaysasonce %s", displaySasOnce);
@@ -377,25 +375,22 @@ row_single_click (GtkTreeView *tree_view UNUSED, void * data UNUSED)
 static gboolean
 button_pressed (GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUSED)
 {
-    if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
-        if (active_calltree == current_calls) {
-            show_popup_menu (widget,  event);
-            return TRUE;
-        } else if (active_calltree == history) {
-            show_popup_menu_history (widget,  event);
-            return TRUE;
-        } else {
-            show_popup_menu_contacts (widget, event);
-            return TRUE;
-        }
-    }
+    if (event->button != 3 || event->type != GDK_BUTTON_PRESS)
+        return FALSE;
+
+    if (active_calltree == current_calls)
+        show_popup_menu (widget,  event);
+    else if (active_calltree == history)
+        show_popup_menu_history (widget,  event);
+    else
+        show_popup_menu_contacts (widget, event);
 
-    return FALSE;
+    return TRUE;
 }
 
 
 static gchar *
-calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, const gchar * const audio_codec)
+calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, const gchar *const audio_codec)
 {
     gchar display_number[strlen(c->_peer_number) + 1];
     strcpy(display_number, c->_peer_number);
@@ -419,7 +414,7 @@ calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, co
         details = "";
     }
 
-    gchar *desc = g_markup_printf_escaped ("<b>%s</b>   <i>%s</i>", name, details);
+    gchar *desc = g_markup_printf_escaped ("<b>%s</b>   <i>%s</i>   ", name, details);
     gchar *suffix = NULL;
 
     switch (display_type) {
@@ -674,8 +669,7 @@ calltree_update_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent)
             if (g_strcasecmp (g_hash_table_lookup (account_details->properties, ACCOUNT_ZRTP_DISPLAY_SAS),"false") == 0)
                 display_sas = FALSE;
         } else {
-            GHashTable * properties = NULL;
-            sflphone_get_ip2ip_properties (&properties);
+            GHashTable * properties = sflphone_get_ip2ip_properties();
 
             if (properties != NULL) {
                 srtp_enabled = g_hash_table_lookup (properties, ACCOUNT_SRTP_ENABLED);
@@ -863,9 +857,7 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent)
 
     if (c) {
         account_details = account_list_get_by_id (c->_accountID);
-        if (account_details == NULL)
-            ERROR("CallTree: Could not find account %s", c->_accountID);
-        else {
+        if (account_details) {
             srtp_enabled = g_hash_table_lookup (account_details->properties, ACCOUNT_SRTP_ENABLED);
             key_exchange = g_hash_table_lookup (account_details->properties, ACCOUNT_KEY_EXCHANGE);
         }
@@ -938,7 +930,7 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent)
 
     gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (tab->view)), &iter);
 
-    history_reinit (history);
+    //history_init();
 }
 
 void calltree_add_history_entry (callable_obj_t *c, GtkTreeIter *parent)
@@ -1019,7 +1011,7 @@ void calltree_add_history_entry (callable_obj_t *c, GtkTreeIter *parent)
 
     gtk_tree_view_set_model (GTK_TREE_VIEW (history->view), GTK_TREE_MODEL (history->store));
 
-    history_reinit (history);
+    history_search();
 }
 
 
@@ -1262,7 +1254,7 @@ void calltree_remove_conference (calltab_t* tab, const conference_obj_t* conf, G
 void calltree_add_history_conference(conference_obj_t *conf) 
 {
     GdkPixbuf *pixbuf = NULL;
-    const gchar *description = "Conference: ";
+    const gchar *description = "Conference: \n";
     GtkTreeIter iter;
     GSList *conference_participant;
 
@@ -1290,7 +1282,7 @@ void calltree_add_history_conference(conference_obj_t *conf)
         if (call)
             calltree_add_history_entry(call, &iter);
         else
-            ERROR("ConferenceList: Error: Could not find call %s", call_id);
+            ERROR("ConferenceList: Error: Could not find call \"%s\"", call_id);
 
         conference_participant = conference_next_participant(conference_participant); 
     }
@@ -1354,13 +1346,7 @@ void calltree_display (calltab_t *tab)
 void calltree_update_clock()
 {
     callable_obj_t *c = calltab_get_selected_call (current_calls);
-
-    if (!c) {
-        statusbar_update_clock ("");
-        return;
-    }
-
-    if (!(c->_timestr)) {
+    if (!c || !c->_timestr) {
         statusbar_update_clock ("");
         return;
     }
@@ -1752,32 +1738,23 @@ static void menuitem_response( gchar *string )
 GtkTreeIter calltree_get_gtkiter_from_id(calltab_t *tab, gchar *id)
 {
     GtkTreeIter iter;
-    GValue val;
-    GtkTreeModel *tree_model;
-    conference_obj_t *conf;
-    callable_obj_t *call;
-
-    tree_model = GTK_TREE_MODEL(tab->store);
+    GtkTreeModel *tree_model = GTK_TREE_MODEL(tab->store);
 
     gtk_tree_model_get_iter_first(tree_model, &iter);
 
     while(gtk_tree_model_iter_next(tree_model, &iter)) {
-        val.g_type = 0;
+        GValue val = { .g_type = 0 };
         gtk_tree_model_get_value (tree_model, &iter, COLUMN_ACCOUNT_PTR, &val);
 
         if(gtk_tree_model_iter_has_child(tree_model, &iter)) {
-            conf = (conference_obj_t *) g_value_get_pointer (&val);
-
-            if(g_strcmp0(conf->_confID, id) == 0) {
+            conference_obj_t *conf = (conference_obj_t *) g_value_get_pointer (&val);
+            if(g_strcmp0(conf->_confID, id) == 0)
                 return iter;
-            }
         }
         else {
-            call = (callable_obj_t *) g_value_get_pointer(&val);
-
-            if(g_strcmp0(call->_callID, id) == 0) {
+            callable_obj_t *call = (callable_obj_t *) g_value_get_pointer(&val);
+            if(g_strcmp0(call->_callID, id) == 0)
                 return iter;
-            }
         }
     }
 
diff --git a/gnome/src/contacts/history.c b/gnome/src/contacts/history.c
index 5aa4ef2880..c7899de90a 100644
--- a/gnome/src/contacts/history.c
+++ b/gnome/src/contacts/history.c
@@ -33,92 +33,68 @@
 #include <searchbar.h>
 #include <calltab.h>
 
-GtkTreeModel* history_filter;
-GtkWidget * history_searchbar_widget;
-
-static GtkTreeModel* history_create_filter (GtkTreeModel*);
-static gboolean history_is_visible (GtkTreeModel*, GtkTreeIter*, gpointer);
-
-void history_search (SearchType search_type UNUSED)
-{
-    if (history_filter != NULL) {
-        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (history_filter));
-    }
-}
-
-void history_init (void)
-{
-    history_filter = history_create_filter (GTK_TREE_MODEL (history->store));
-    gtk_tree_view_set_model (GTK_TREE_VIEW (history->view), GTK_TREE_MODEL (history_filter));
-}
-
-void history_reinit (calltab_t* history)
-{
-    history_filter = history_create_filter (GTK_TREE_MODEL (history->store));
-    gtk_tree_view_set_model (GTK_TREE_VIEW (history->view), GTK_TREE_MODEL (history_filter));
-}
-
-
-void history_set_searchbar_widget (GtkWidget *searchbar)
-{
-    history_searchbar_widget = searchbar;
-}
-
-static GtkTreeModel* history_create_filter (GtkTreeModel* child)
-{
-    GtkTreeModel* ret;
-
-    DEBUG ("Create Filter");
-    ret = gtk_tree_model_filter_new (child, NULL);
-    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (ret), history_is_visible, NULL, NULL);
-    return GTK_TREE_MODEL (ret);
-}
+static GtkTreeModel *history_filter;
+static GtkEntry *history_searchbar_widget;
 
 static gboolean history_is_visible (GtkTreeModel* model, GtkTreeIter* iter, gpointer data UNUSED)
 {
-    GValue val, obj;
-
     callable_obj_t *history_entry = NULL;
     gchar* text = NULL;
 
-    gchar* search = (gchar*) gtk_entry_get_text (GTK_ENTRY (history_searchbar_widget));
-
-    memset (&val, 0, sizeof (val));
-    memset (&obj, 0, sizeof (obj));
-
     // Fetch the call description
+    GValue val;
+    memset(&val, 0, sizeof val);
     gtk_tree_model_get_value (GTK_TREE_MODEL (model), iter, 1, &val);
 
-    if (G_VALUE_HOLDS_STRING (&val)) {
+    if (G_VALUE_HOLDS_STRING (&val))
         text = (gchar *) g_value_get_string (&val);
-    }
 
     // Fetch the call type
+    GValue obj;
+    memset(&obj, 0, sizeof obj);
     gtk_tree_model_get_value (GTK_TREE_MODEL (model), iter, 3, &obj);
 
-    if (G_VALUE_HOLDS_POINTER (&obj)) {
+    if (G_VALUE_HOLDS_POINTER (&obj))
         history_entry = (gpointer) g_value_get_pointer (&obj);
+
+    if (text && history_entry) {
+        // Filter according to the type of call
+        // MISSED, INCOMING, OUTGOING, ALL
+        const gchar* search = gtk_entry_get_text (history_searchbar_widget);
+        if (!search || !*search)
+            return TRUE;
+        SearchType search_type = get_current_history_search_type();
+        gboolean match = g_regex_match_simple(search, text, G_REGEX_CASELESS, 0);
+
+        if (search_type == SEARCH_ALL)
+            return match;
+        else // We need a match on the history_state_t and the current search type
+            return (history_entry->_history_state + 1) == search_type && match;
     }
 
-    gboolean result = TRUE;
+    return TRUE;
+}
 
-    if (text != NULL) {
-        if (history_entry) {
-            // Filter according to the type of call
-            // MISSED, INCOMING, OUTGOING, ALL
-            if ( (int) get_current_history_search_type () == SEARCH_ALL)
-                result = g_regex_match_simple (search, text, G_REGEX_CASELESS, 0);
-            else {
-                // We need a match on the history_state_t and the current search type
-                result = (history_entry->_history_state + 1) == (guint) get_current_history_search_type () &&
-                       g_regex_match_simple (search, text, G_REGEX_CASELESS, 0);
-            }
-        }
-    }
+static GtkTreeModel* history_create_filter (GtkTreeModel* child)
+{
+    GtkTreeModel* ret = gtk_tree_model_filter_new (child, NULL);
+    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (ret), history_is_visible, NULL, NULL);
+    return GTK_TREE_MODEL (ret);
+}
+
+void history_search (void)
+{
+    if (history_filter != NULL)
+        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (history_filter));
+}
 
-    // Clean up
-    g_value_unset (&val);
-    g_value_unset (&obj);
+void history_search_init (void)
+{
+    history_filter = history_create_filter (GTK_TREE_MODEL (history->store));
+    gtk_tree_view_set_model (GTK_TREE_VIEW (history->view), GTK_TREE_MODEL (history_filter));
+}
 
-    return result;
+void history_set_searchbar_widget (GtkWidget *searchbar)
+{
+    history_searchbar_widget = GTK_ENTRY(searchbar);
 }
diff --git a/gnome/src/contacts/history.h b/gnome/src/contacts/history.h
index f21dd3e2ef..2b2dc9290f 100644
--- a/gnome/src/contacts/history.h
+++ b/gnome/src/contacts/history.h
@@ -48,16 +48,13 @@ typedef enum {
 /**
  * Execute a search in history
  */
-void history_search (SearchType search_type);
+void history_search();
 
 /**
  * Initialize history
  */
 void
-history_init();
-
-
-void history_reinit (calltab_t* history);
+history_search_init();
 
 /**
  * Set history search bar widget (needed for is_visible)
diff --git a/gnome/src/contacts/searchbar.c b/gnome/src/contacts/searchbar.c
index 2c8875f95c..e6d1c549ac 100644
--- a/gnome/src/contacts/searchbar.c
+++ b/gnome/src/contacts/searchbar.c
@@ -76,22 +76,16 @@ void searchbar_entry_changed (GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpoint
         // Search made only when text entry is activated
         // addressbook_search (entry);
     } else if (active_calltree == history) {
-        history_search (HistorySearchType);
+        history_search();
     }
 }
 
 static void cbox_changed_cb (GtkWidget *widget, gpointer user_data UNUSED)
 {
-    gchar *name;
-
-    DEBUG ("Searchbar: Addressbook changed callback");
-
-    name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
-
     if(abookfactory_is_addressbook_loaded()) {
         DEBUG("Searchbar: Set new addressbook");
         AddrBookFactory *factory = abookfactory_get_factory();
-        factory->addrbook->set_current_book (name);
+        factory->addrbook->set_current_book (gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget)));
         AddressBook_Config *addressbook_config;
         addressbook_config_load_parameters(&addressbook_config);
         factory->addrbook->search(factory->addrbook, GTK_ENTRY(addressbookentry), addressbook_config);
@@ -105,18 +99,15 @@ void set_focus_on_addressbook_searchbar ()
 
 void update_searchbar_addressbook_list()
 {
-    gint count;
     GtkTreeIter iter, activeIter;
     gchar *activeText;
     GSList *book_list_iterator;
     book_data_t *book_data;
     GSList *books_data = NULL;
-    gchar **book_list;
 
     if(abookfactory_is_addressbook_loaded()) {
         AddrBookFactory *factory = abookfactory_get_factory();
-        book_list = dbus_get_addressbook_list();
-        books_data = factory->addrbook->get_books_data(book_list);
+        books_data = factory->addrbook->get_books_data(dbus_get_addressbook_list());
     }
 
     if(books_data == NULL) {
@@ -138,7 +129,6 @@ void update_searchbar_addressbook_list()
     gtk_list_store_clear (liststore);
 
     // Populate menu
-    count = 0;
     gboolean activeIsSet = FALSE;
 
     for (book_list_iterator = books_data; book_list_iterator != NULL; book_list_iterator
@@ -155,8 +145,6 @@ void update_searchbar_addressbook_list()
                 activeIter = iter;
                 activeIsSet = TRUE;
             }
-
-            count++;
         }
     }
 
@@ -217,7 +205,7 @@ static void search_all (GtkWidget *item UNUSED, GtkEntry  *entry)
                                              _ ("Search all"),
                                              _ ("Click here to change the search type")));
 
-    history_search (HistorySearchType);
+    history_search();
 }
 
 static void search_by_missed (GtkWidget *item UNUSED, GtkEntry  *entry)
@@ -229,7 +217,7 @@ static void search_by_missed (GtkWidget *item UNUSED, GtkEntry  *entry)
                                      g_markup_printf_escaped ("%s\n%s",
                                              _ ("Search by missed call"),
                                              _ ("Click here to change the search type")));
-    history_search (HistorySearchType);
+    history_search();
 }
 
 static void search_by_incoming (GtkWidget *item UNUSED, GtkEntry *entry)
@@ -241,7 +229,7 @@ static void search_by_incoming (GtkWidget *item UNUSED, GtkEntry *entry)
                                      g_markup_printf_escaped ("%s\n%s",
                                              _ ("Search by incoming call"),
                                              _ ("Click here to change the search type")));
-    history_search (HistorySearchType);
+    history_search();
 }
 
 static void search_by_outgoing (GtkWidget *item UNUSED, GtkEntry  *entry)
@@ -253,7 +241,7 @@ static void search_by_outgoing (GtkWidget *item UNUSED, GtkEntry  *entry)
                                      g_markup_printf_escaped ("%s\n%s",
                                              _ ("Search by outgoing call"),
                                              _ ("Click here to change the search type")));
-    history_search (HistorySearchType);
+    history_search();
 }
 
 static void icon_press_cb (GtkEntry *entry, gint position, GdkEventButton *event, gpointer data UNUSED)
@@ -324,18 +312,6 @@ focus_on_searchbar_in()
     focus_is_on_searchbar = TRUE;
 }
 
-void searchbar_init (calltab_t *tab)
-{
-    if (g_strcasecmp (tab->_name, CONTACTS) == 0) {
-    }
-    else if (g_strcasecmp (tab->_name, HISTORY) == 0) {
-        history_init();
-    }
-    else {
-        ERROR ("searchbar.c - searchbar_init should not happen within this widget\n");
-    }
-}
-
 GtkWidget* history_searchbar_new (void)
 {
 
@@ -559,4 +535,3 @@ SearchType get_current_history_search_type (void)
 {
     return HistorySearchType;
 }
-
diff --git a/gnome/src/contacts/searchbar.h b/gnome/src/contacts/searchbar.h
index 4d0431dfcc..eaf29e3e17 100644
--- a/gnome/src/contacts/searchbar.h
+++ b/gnome/src/contacts/searchbar.h
@@ -71,11 +71,6 @@ GtkWidget* contacts_searchbar_new (void);
  */
 SearchType get_current_history_search_type (void);
 
-/**
- * Initialize a specific search bar
- */
-void searchbar_init (calltab_t *);
-
 /**
  * Activate a waiting layer during search
  */
diff --git a/gnome/src/dbus/dbus.c b/gnome/src/dbus/dbus.c
index 766d752410..b1b5f8d301 100644
--- a/gnome/src/dbus/dbus.c
+++ b/gnome/src/dbus/dbus.c
@@ -136,7 +136,7 @@ new_call_created_cb (DBusGProxy *proxy UNUSED, const gchar *accountID,
     callable_obj_t *c = create_new_call(CALL, CALL_STATE_RINGING, callID, accountID,
 			peer_name, peer_number);
 
-    set_timestamp(&c->_time_start);
+    time(&c->_time_start);
 
     calllist_add_call(current_calls, c);
     calllist_add_call(history, c);
@@ -151,26 +151,21 @@ static void
 incoming_call_cb (DBusGProxy *proxy UNUSED, const gchar* accountID,
                   const gchar* callID, const gchar* from, void * foo  UNUSED)
 {
-    callable_obj_t * c;
-    gchar *peer_name, *peer_number;
-    
-    DEBUG ("DBus: Incoming call (%s) from %s", callID, from);
-
     // We receive the from field under a formatted way. We want to extract the number and the name of the caller
-    peer_name = call_get_peer_name (from);
-    peer_number = call_get_peer_number (from);
+    gchar *peer_name = call_get_peer_name (from);
+    gchar *peer_number = call_get_peer_number (from);
+
+    DEBUG ("DBus: Incoming call (%s) from %s (%s : %s)", callID, from, peer_name, peer_number);
+
+    callable_obj_t *c = create_new_call (CALL, CALL_STATE_INCOMING, callID, accountID, peer_name, peer_number);
 
-    DEBUG ("DBus incoming peer name: %s", peer_name);
-    DEBUG ("DBus incoming peer number: %s", peer_number);
+    g_free(peer_number);
 
-    c = create_new_call (CALL, CALL_STATE_INCOMING, callID, accountID, peer_name,
-                     peer_number);
 #if GTK_CHECK_VERSION(2,10,0)
     status_tray_icon_blink (TRUE);
     popup_main_window();
 #endif
 
-    set_timestamp (&c->_time_start);
     notify_incoming_call (c);
     sflphone_incoming_call (c);
 }
@@ -265,7 +260,7 @@ call_state_cb (DBusGProxy *proxy UNUSED, const gchar* callID, const gchar* state
         if (g_strcmp0 (state, "HUNGUP") == 0) {
             if (c->_state == CALL_STATE_CURRENT) {
                 // peer hung up, the conversation was established, so _stop has been initialized with the current time value
-                set_timestamp (&c->_time_stop);
+                time(&c->_time_stop);
                 calltree_update_call (history, c, NULL);
             }
 
@@ -418,7 +413,7 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
         callable_obj_t *call = calllist_get_call (current_calls, call_id);
 
         // set when this call have been added to the conference
-        set_timestamp(&call->_time_added);
+        time(&call->_time_added);
 
         // if a text widget is already created, disable it, use conference widget instead
         if (call->_im_widget)
@@ -432,7 +427,7 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
         call->_historyConfID = g_strdup (confID);
     }
 
-    set_timestamp(&new_conf->_time_start);
+    time(&new_conf->_time_start);
 
     conferencelist_add (current_calls, new_conf);
     conferencelist_add (history, new_conf);
diff --git a/gnome/src/imwindow.c b/gnome/src/imwindow.c
index 6980a46b80..f501e8fe96 100644
--- a/gnome/src/imwindow.c
+++ b/gnome/src/imwindow.c
@@ -211,7 +211,7 @@ im_window_add_tab (GtkWidget *widget)
     im->tab = tab_Container;
 
     if (im_widget_call)
-        tab_Label = gtk_label_new (get_peer_information (im_widget_call));
+        tab_Label = gtk_label_new (*im_widget_call->_peer_name ? im_widget_call->_peer_name : im_widget_call->_peer_number);
     else if (im_widget_conf)
         tab_Label = gtk_label_new ("Conferencing");
     else
diff --git a/gnome/src/main.c b/gnome/src/main.c
index 111b431132..0334a0496f 100644
--- a/gnome/src/main.c
+++ b/gnome/src/main.c
@@ -43,6 +43,7 @@
 #include <stdlib.h>
 
 #include "shortcuts.h"
+#include "history.h"
 
 int
 main (int argc, char *argv[])
@@ -116,19 +117,16 @@ main (int argc, char *argv[])
 
     status_bar_display_account ();
 
-    // Load the history
     sflphone_fill_history ();
-
-    // Get the active calls and conferences at startup
     sflphone_fill_call_list ();
     sflphone_fill_conference_list ();
+    history_search_init();
 
     // Update the GUI
     update_actions ();
 
     shortcuts_initialize_bindings();
 
-    /* start the main loop */
     gtk_main ();
 
     shortcuts_destroy_bindings();
diff --git a/gnome/src/mainwindow.c b/gnome/src/mainwindow.c
index 78187715da..e7f129e608 100644
--- a/gnome/src/mainwindow.c
+++ b/gnome/src/mainwindow.c
@@ -297,8 +297,7 @@ create_main_window ()
     /* dont't show the contact list */
     gtk_widget_hide (contacts->tree);
 
-    searchbar_init (history);
-    searchbar_init (contacts);
+    //history_init(); // init search
 
     /* don't show waiting layer */
     gtk_widget_hide (waitingLayer);
@@ -489,8 +488,7 @@ main_window_zrtp_not_supported (callable_obj_t * c)
         DEBUG ("Warning Enabled %s", warning_enabled);
     } else {
         DEBUG ("Account is null callID %s", c->_callID);
-        GHashTable * properties = NULL;
-        sflphone_get_ip2ip_properties (&properties);
+        GHashTable * properties = sflphone_get_ip2ip_properties();
 
         if (properties != NULL) {
             warning_enabled = g_hash_table_lookup (properties,
diff --git a/gnome/src/uimanager.c b/gnome/src/uimanager.c
index ffddd7830a..0ca3b4fdc8 100644
--- a/gnome/src/uimanager.c
+++ b/gnome/src/uimanager.c
@@ -712,8 +712,9 @@ static void
 conference_hang_up (void)
 {
     DEBUG ("UIManager: Hang up button pressed (conference)");
-
-    sflphone_conference_hang_up();
+    conference_obj_t * selectedConf = calltab_get_selected_conf(current_calls);
+    if (selectedConf)
+        dbus_hang_up_conference (selectedConf);
 }
 
 static void
@@ -952,8 +953,7 @@ edit_paste (void * foo UNUSED)
                     gchar * temp = g_strconcat (selectedCall->_peer_number, oneNo,
                                                 NULL);
                     g_free (selectedCall->_peer_info);
-                    selectedCall->_peer_info = get_peer_info (temp,
-                                               selectedCall->_peer_name);
+                    selectedCall->_peer_info = get_peer_info (temp, selectedCall->_peer_name);
                     g_free (temp);
                     g_free (oneNo);
                     calltree_update_call (current_calls, selectedCall, NULL);
-- 
GitLab