diff --git a/gnome/src/accountlist.c b/gnome/src/accountlist.c index 62df3498b277f1d1210867df58fc7487b34a05b9..dce63a60f4e563197465add4d5bac161eabaf488 100644 --- a/gnome/src/accountlist.c +++ b/gnome/src/accountlist.c @@ -100,6 +100,7 @@ account_list_get_by_state(account_state_t state) account_t * account_list_get_by_id(const gchar * const accountID) { + g_assert(accountID); GList * c = g_queue_find_custom(accountQueue, accountID, is_accountID_struct); if (c) @@ -301,7 +302,7 @@ gboolean current_account_has_new_message(void) gboolean account_is_IP2IP(const account_t *account) { g_assert(account); - return g_strcmp0(account->accountID, IP2IP_PROFILE); + return g_strcmp0(account->accountID, IP2IP_PROFILE) == 0; } static gboolean is_type(const account_t *account, const gchar *type) @@ -323,9 +324,17 @@ gboolean account_is_IAX(const account_t *account) account_t *create_default_account() { account_t *account = g_new0(account_t, 1); - account->properties = dbus_get_account_details(NULL); + account->properties = dbus_get_account_details(""); account->accountID = g_strdup("new"); // FIXME: maybe replace with NULL? - account->credential_information = NULL; + sflphone_fill_codec_list_per_account(account); + return account; +} + +account_t *create_account_with_ID(const gchar *ID) +{ + account_t *account = g_new0(account_t, 1); + account->accountID = g_strdup(ID); + account->properties = dbus_get_account_details(ID); sflphone_fill_codec_list_per_account(account); return account; } diff --git a/gnome/src/accountlist.h b/gnome/src/accountlist.h index 8665e570b1ddfab4519de8157fc01cb33897c897..2bddde48b12f0df35c9787cec4ebe199fe2986e7 100644 --- a/gnome/src/accountlist.h +++ b/gnome/src/accountlist.h @@ -29,8 +29,8 @@ * as that of the covered work. */ -#ifndef __ACCOUNTLIST_H__ -#define __ACCOUNTLIST_H__ +#ifndef ACCOUNTLIST_H__ +#define ACCOUNTLIST_H__ #include <gtk/gtk.h> /** @file accountlist.h @@ -188,6 +188,7 @@ gboolean account_is_SIP(const account_t *account); gboolean account_is_IAX(const account_t *account); account_t *create_default_account(); +account_t *create_account_with_ID(const gchar *ID); void initialize_credential_information(account_t *account); diff --git a/gnome/src/actions.c b/gnome/src/actions.c index f0dd5a0218964c0551425696a5c4e77d53836f4d..147b16bf7e53b67e18969ca7b8bcd327c1232d26 100644 --- a/gnome/src/actions.c +++ b/gnome/src/actions.c @@ -132,8 +132,8 @@ status_bar_display_account() if (acc) { msg = g_markup_printf_escaped("%s %s (%s)" , _("Using account"), - (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_ALIAS), - (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_TYPE)); + (gchar*) account_lookup(acc, ACCOUNT_ALIAS), + (gchar*) account_lookup(acc, ACCOUNT_TYPE)); } else { msg = g_markup_printf_escaped(_("No registered accounts")); } @@ -206,78 +206,53 @@ sflphone_hung_up(callable_obj_t * c) void sflphone_fill_account_list(void) { account_list_init(); - gchar **array = dbus_account_list(); - if (array) { - for (gchar **accountID = array; accountID && *accountID; accountID++) { - account_t * a = g_new0(account_t, 1); - a->accountID = g_strdup(*accountID); - a->credential_information = NULL; - account_list_add(a); - } - - g_strfreev(array); - } - - for (unsigned i = 0; i < account_list_get_size(); i++) { - account_t *a = account_list_get_nth(i); - - if (a == NULL) { - ERROR("SFLphone: Error: Could not find account %d in list", i); + for (gchar **accountID = array; accountID && *accountID; ++accountID) { + account_t *acc = create_account_with_ID(*accountID); + if (acc->properties == NULL) { + ERROR("SFLphone: Error: Could not fetch details for account %s", + accountID); break; } - - GHashTable * details = (GHashTable *) dbus_get_account_details(a->accountID); - - if (details == NULL) { - ERROR("SFLphone: Error: Could not fetch detais for account %s", a->accountID); - break; - } - - a->properties = details; - + account_list_add(acc); /* Fill the actual array of credentials */ - dbus_get_credentials(a); - - gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS); + dbus_get_credentials(acc); + gchar * status = account_lookup(acc, REGISTRATION_STATUS); if (g_strcmp0(status, "REGISTERED") == 0) - a->state = ACCOUNT_STATE_REGISTERED; + acc->state = ACCOUNT_STATE_REGISTERED; else if (g_strcmp0(status, "UNREGISTERED") == 0) - a->state = ACCOUNT_STATE_UNREGISTERED; + acc->state = ACCOUNT_STATE_UNREGISTERED; else if (g_strcmp0(status, "TRYING") == 0) - a->state = ACCOUNT_STATE_TRYING; + acc->state = ACCOUNT_STATE_TRYING; else if (g_strcmp0(status, "ERROR") == 0) - a->state = ACCOUNT_STATE_ERROR; + acc->state = ACCOUNT_STATE_ERROR; else if (g_strcmp0(status , "ERROR_AUTH") == 0) - a->state = ACCOUNT_STATE_ERROR_AUTH; + acc->state = ACCOUNT_STATE_ERROR_AUTH; else if (g_strcmp0(status , "ERROR_NETWORK") == 0) - a->state = ACCOUNT_STATE_ERROR_NETWORK; + acc->state = ACCOUNT_STATE_ERROR_NETWORK; else if (g_strcmp0(status , "ERROR_HOST") == 0) - a->state = ACCOUNT_STATE_ERROR_HOST; + acc->state = ACCOUNT_STATE_ERROR_HOST; else if (g_strcmp0(status , "ERROR_CONF_STUN") == 0) - a->state = ACCOUNT_STATE_ERROR_CONF_STUN; + acc->state = ACCOUNT_STATE_ERROR_CONF_STUN; else if (g_strcmp0(status , "ERROR_EXIST_STUN") == 0) - a->state = ACCOUNT_STATE_ERROR_EXIST_STUN; + acc->state = ACCOUNT_STATE_ERROR_EXIST_STUN; else if (g_strcmp0(status, "READY") == 0) - a->state = IP2IP_PROFILE_STATUS; + acc->state = IP2IP_PROFILE_STATUS; else - a->state = ACCOUNT_STATE_INVALID; - - gchar * code = g_hash_table_lookup(details, REGISTRATION_STATE_CODE); + acc->state = ACCOUNT_STATE_INVALID; + gchar * code = account_lookup(acc, REGISTRATION_STATE_CODE); if (code != NULL) - a->protocol_state_code = atoi(code); - - g_free(a->protocol_state_description); - a->protocol_state_description = g_hash_table_lookup(details, REGISTRATION_STATE_DESCRIPTION); + acc->protocol_state_code = atoi(code); + acc->protocol_state_description = account_lookup(acc, REGISTRATION_STATE_DESCRIPTION); } + g_strfreev(array); + // Set the current account message number current_account_set_message_number(current_account_get_message_number()); - - sflphone_fill_codec_list(); account_store_fill(); } @@ -962,22 +937,9 @@ sflphone_mute_call() toggle_slider_mute_microphone(); } -void sflphone_fill_codec_list() -{ - guint account_list_size = account_list_get_size(); - - for (guint i = 0; i < account_list_size; i++) { - account_t *current = account_list_get_nth(i); - - if (current) - sflphone_fill_codec_list_per_account(current); - } -} - void sflphone_fill_codec_list_per_account(account_t *account) { GArray *order = dbus_get_active_audio_codec_list(account->accountID); - GQueue *codeclist = account->codecs; // First clean the list diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c index 703d24f9fe39cba9bca256c79243c1638c0698cc..33c046786558e8a5dbadd821126daa32f4cbbbd0 100644 --- a/gnome/src/config/accountconfigdialog.c +++ b/gnome/src/config/accountconfigdialog.c @@ -661,7 +661,7 @@ static GtkWidget* create_credential_widget(const account_t *account) G_TYPE_STRING, // Username G_TYPE_STRING, // Password G_TYPE_POINTER // Pointer to the Objectc - ); + ); treeview_credential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credential_store)); GtkTreeSelection * tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_credential)); @@ -828,7 +828,7 @@ static GtkWidget* create_registration_expire(const account_t *account) &orig_key, (gpointer) &account_expire)) ERROR("Could not retrieve %s from account properties", ACCOUNT_REGISTRATION_EXPIRE); - + GtkWidget *table, *frame; gnome_main_section_new_with_table(_("Registration"), &frame, &table, 2, 3); gtk_container_set_border_width(GTK_CONTAINER(table), 10); @@ -1254,9 +1254,10 @@ void show_account_window(account_t *account) gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook, TRUE, TRUE, 0); gtk_container_set_border_width(GTK_CONTAINER(notebook), 10); gtk_widget_show(notebook); + const gboolean IS_IP2IP = account_is_IP2IP(account); // We do not need the global settings for the IP2IP account - if (!account_is_IP2IP(account)) { + if (!IS_IP2IP) { /* General Settings */ GtkWidget *basic_tab = create_basic_tab(account); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), basic_tab, gtk_label_new(_("Basic"))); @@ -1276,7 +1277,7 @@ void show_account_window(account_t *account) current_protocol = g_strdup("SIP"); // Do not need advanced or security one for the IP2IP account - if (!account_is_IP2IP(account)) { + if (!IS_IP2IP) { /* Advanced */ advanced_tab = create_advanced_tab(account); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced_tab, gtk_label_new(_("Advanced"))); @@ -1300,29 +1301,26 @@ void show_account_window(account_t *account) gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0); - /* Run dialog */ + /* Run dialog, this blocks */ gint response = gtk_dialog_run(GTK_DIALOG(dialog)); - // If cancel button is pressed - if (response == GTK_RESPONSE_CANCEL) { + // If anything but "Apply" button is pressed + if (response != GTK_RESPONSE_ACCEPT) { gtk_widget_destroy(dialog); return; } - if (!account_is_IP2IP(account)) + if (!IS_IP2IP) update_account_from_basic_tab(account); /** @todo Verify if it's the best condition to check */ - if (g_strcmp0(account->accountID, "new")) + if (g_strcmp0(account->accountID, "new") == 0) dbus_add_account(account); else dbus_set_account_details(account); if (g_strcmp0(current_protocol, "SIP") == 0) { - /* Set new credentials if any */ - DEBUG("Config: Setting credentials"); - - if (!account_is_IP2IP(account)) { + if (!IS_IP2IP) { DEBUG("Config: Get new credentials"); account->credential_information = get_new_credential(); @@ -1334,7 +1332,7 @@ void show_account_window(account_t *account) // propagate changes to the daemon codec_list_update_to_daemon(account); - gtk_widget_destroy(dialog); g_free(current_protocol); + gtk_widget_destroy(dialog); } diff --git a/gnome/src/config/accountlistconfigdialog.c b/gnome/src/config/accountlistconfigdialog.c index 0953b51feed4b6b3bd002e9d309a7d2cefd21e97..8b42d2d7791c972a598c2d7d49e30b9674baa0d6 100644 --- a/gnome/src/config/accountlistconfigdialog.c +++ b/gnome/src/config/accountlistconfigdialog.c @@ -52,7 +52,6 @@ static GtkWidget *move_up_button; static GtkWidget *status_bar; static GtkListStore *account_store; static GtkDialog *account_list_dialog; -static gchar *selected_accountID; // Account properties enum { @@ -64,34 +63,60 @@ enum { COLUMN_ACCOUNT_COUNT }; -static void delete_account_cb(void) +/* Get selected account ID from treeview + * @return copied selected_accountID, must be freed by caller */ +static gchar * +get_selected_accountID(GtkTreeView *tree_view) { + GtkTreeModel *model = gtk_tree_view_get_model(tree_view); + GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); + + // Find selected iteration and create a copy + GtkTreeIter iter; + gtk_tree_selection_get_selected(selection, &model, &iter); + // The Gvalue will be initialized in the following function + GValue val; + memset(&val, 0, sizeof(val)); + gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val); + + gchar *selected_accountID = g_strdup(g_value_get_string(&val)); + g_value_unset(&val); + return selected_accountID; +} + +static void delete_account_cb(gpointer data) +{ + gchar *selected_accountID = get_selected_accountID(data); RETURN_IF_NULL(selected_accountID, "No selected account in delete action"); dbus_remove_account(selected_accountID); g_free(selected_accountID); - selected_accountID = NULL; } -static void row_activated_cb(GtkTreeView *view UNUSED, +static void row_activated_cb(GtkTreeView *view, GtkTreePath *path UNUSED, GtkTreeViewColumn *col UNUSED, gpointer user_data UNUSED) { + gchar *selected_accountID = get_selected_accountID(view); RETURN_IF_NULL(selected_accountID, "No selected account in edit action"); DEBUG("%s: Selected accountID=%s\n", __PRETTY_FUNCTION__, selected_accountID); show_account_window(account_list_get_by_id(selected_accountID)); + g_free(selected_accountID); } -static void edit_account_cb(GtkButton *button UNUSED, gpointer data UNUSED) +static void edit_account_cb(GtkButton *button UNUSED, gpointer data) { + gchar *selected_accountID = get_selected_accountID(data); RETURN_IF_NULL(selected_accountID, "No selected account in edit action"); DEBUG("%s: Selected accountID=%s\n", __PRETTY_FUNCTION__, selected_accountID); show_account_window(account_list_get_by_id(selected_accountID)); + g_free(selected_accountID); } static void add_account_cb(void) { account_t *new_account = create_default_account(); + account_list_add(new_account); show_account_window(new_account); } @@ -109,21 +134,12 @@ static void account_store_add(GtkTreeIter *iter, account_t *account) COLUMN_ACCOUNT_ID, account->accountID, -1); } -static void -invalidate_selected_accountID() -{ - if (selected_accountID) { - g_free(selected_accountID); - selected_accountID = NULL; - } -} /** * Fills the treelist with accounts */ void account_store_fill() { - invalidate_selected_accountID(); RETURN_IF_NULL(account_list_dialog, "No account dialog"); gtk_list_store_clear(account_store); @@ -156,7 +172,6 @@ select_account_cb(GtkTreeSelection *selection, GtkTreeModel *model) { GtkTreeIter iter; if (!gtk_tree_selection_get_selected(selection, &model, &iter)) { - invalidate_selected_accountID(); gtk_widget_set_sensitive(move_up_button, FALSE); gtk_widget_set_sensitive(move_down_button, FALSE); gtk_widget_set_sensitive(edit_button, FALSE); @@ -169,7 +184,7 @@ select_account_cb(GtkTreeSelection *selection, GtkTreeModel *model) memset(&val, 0, sizeof(val)); gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val); - selected_accountID = g_strdup(g_value_get_string(&val)); + gchar *selected_accountID = g_strdup(g_value_get_string(&val)); g_value_unset(&val); DEBUG("Selected account has accountID %s", selected_accountID); @@ -210,7 +225,7 @@ select_account_cb(GtkTreeSelection *selection, GtkTreeModel *model) gtk_widget_set_sensitive(move_down_button, FALSE); gtk_widget_set_sensitive(delete_button, FALSE); } - DEBUG("Selecting account in account window"); + g_free(selected_accountID); } static void @@ -253,7 +268,7 @@ enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path, static void account_move(gboolean move_up, gpointer data) { - // Get view, model and selection of codec store + // Get view, model and selection of account GtkTreeView *tree_view = GTK_TREE_VIEW(data); GtkTreeModel *model = gtk_tree_view_get_model(tree_view); GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); @@ -416,6 +431,8 @@ create_account_list() gtk_table_attach(GTK_TABLE(table), scrolled_window, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + if (account_store) + gtk_list_store_clear(account_store); account_store = gtk_list_store_new(COLUMN_ACCOUNT_COUNT, G_TYPE_STRING, // Name G_TYPE_STRING, // Protocol @@ -437,7 +454,7 @@ create_account_list() gtk_tree_view_column_new_with_attributes("Enabled", renderer, "active", COLUMN_ACCOUNT_ACTIVE , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column); - g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(enable_account_cb), (gpointer) tree_view); + g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(enable_account_cb), tree_view); renderer = gtk_cell_renderer_text_new(); tree_view_column = gtk_tree_view_column_new_with_attributes("Alias", @@ -506,13 +523,13 @@ create_account_list() edit_button = gtk_button_new_from_stock(GTK_STOCK_EDIT); gtk_widget_set_sensitive(edit_button, FALSE); - g_signal_connect(G_OBJECT(edit_button), "clicked", G_CALLBACK(edit_account_cb), NULL); + g_signal_connect(G_OBJECT(edit_button), "clicked", G_CALLBACK(edit_account_cb), tree_view); gtk_box_pack_start(GTK_BOX(button_box), edit_button, FALSE, FALSE, 0); delete_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); gtk_widget_set_sensitive(delete_button, FALSE); g_signal_connect_swapped(G_OBJECT(delete_button), "clicked", - G_CALLBACK(delete_account_cb), NULL); + G_CALLBACK(delete_account_cb), tree_view); gtk_box_pack_start(GTK_BOX(button_box), delete_button, FALSE, FALSE, 0); /* help and close buttons */