From 4da8f83072b0a08d892a093bfab836bda29e1266 Mon Sep 17 00:00:00 2001 From: Jonny Lamb Date: Fri, 28 Jan 2011 16:29:31 +0000 Subject: chat: try to use a room password from the keyring or offer to save the password Signed-off-by: Jonny Lamb --- libempathy-gtk/empathy-chat.c | 167 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 159 insertions(+), 8 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 489a0a69a..455fb0e8e 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -2967,12 +2968,104 @@ typedef struct { EmpathyChat *self; GtkWidget *info_bar; + gulong response_id; GtkWidget *button; GtkWidget *label; GtkWidget *entry; GtkWidget *spinner; } PasswordData; +static void +passwd_remember_button_cb (GtkButton *button, + PasswordData *data) +{ + gtk_info_bar_response (GTK_INFO_BAR (data->info_bar), GTK_RESPONSE_OK); +} + +static void +passwd_not_now_button_cb (GtkButton *button, + PasswordData *data) +{ + gtk_info_bar_response (GTK_INFO_BAR (data->info_bar), GTK_RESPONSE_NO); +} + +static void +remember_password_infobar_response_cb (GtkWidget *info_bar, + gint response_id, + PasswordData *data) +{ + if (response_id == GTK_RESPONSE_OK) { + DEBUG ("Saving room password"); + /* TODO: implement this */ + } + + gtk_widget_destroy (info_bar); + g_slice_free (PasswordData, data); +} + +static void +chat_prompt_to_save_password (EmpathyChat *self, + PasswordData *data) +{ + GtkWidget *content_area; + GtkWidget *hbox; + GtkWidget *image; + GtkWidget *label; + GtkWidget *alig; + GtkWidget *button; + + /* Remove all previous widgets */ + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (data->info_bar)); + gtk_container_forall (GTK_CONTAINER (content_area), + (GtkCallback) gtk_widget_destroy, NULL); + data->button = NULL; + data->label = NULL; + data->entry = NULL; + data->spinner = NULL; + + gtk_info_bar_set_message_type (GTK_INFO_BAR (data->info_bar), + GTK_MESSAGE_QUESTION); + + hbox = gtk_hbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0); + + /* Add image */ + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, + GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + /* Add message */ + label = gtk_label_new (_("Would you like to store this password?")); + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + + /* Add 'Remember' button */ + alig = gtk_alignment_new (0, 0.5, 1, 0); + + button = gtk_button_new_with_label (_("Remember")); + gtk_container_add (GTK_CONTAINER (alig), button); + gtk_box_pack_start (GTK_BOX (hbox), alig, FALSE, FALSE, 0); + + g_signal_connect (button, "clicked", G_CALLBACK (passwd_remember_button_cb), + data); + + /* Add 'Not now' button */ + alig = gtk_alignment_new (0, 0.5, 1, 0); + + button = gtk_button_new_with_label (_("Not now")); + gtk_container_add (GTK_CONTAINER (alig), button); + gtk_box_pack_start (GTK_BOX (hbox), alig, FALSE, FALSE, 0); + + g_signal_connect (button, "clicked", G_CALLBACK (passwd_not_now_button_cb), + data); + + /* go! */ + g_signal_handler_disconnect (data->info_bar, data->response_id); + g_signal_connect (data->info_bar, "response", + G_CALLBACK (remember_password_infobar_response_cb), data); + + gtk_widget_show_all (data->info_bar); +} + static void provide_password_cb (GObject *tp_chat, GAsyncResult *res, @@ -3016,10 +3109,14 @@ provide_password_cb (GObject *tp_chat, return; } - /* Get rid of the password info bar finally */ - gtk_widget_destroy (data->info_bar); - - g_slice_free (PasswordData, data); + if (empathy_keyring_is_available ()) { + /* ask whether they want to save the password */ + chat_prompt_to_save_password (self, data); + } else { + /* Get rid of the password info bar finally */ + gtk_widget_destroy (data->info_bar); + g_slice_free (PasswordData, data); + } /* Room joined */ gtk_widget_set_sensitive (priv->hpaned, TRUE); @@ -3169,8 +3266,8 @@ display_password_info_bar (EmpathyChat *self) TRUE, TRUE, 3); gtk_widget_show_all (hbox); - g_signal_connect (info_bar, "response", - G_CALLBACK (password_infobar_response_cb), data); + data->response_id = g_signal_connect (info_bar, "response", + G_CALLBACK (password_infobar_response_cb), data); gtk_widget_show_all (info_bar); /* ... but hide the spinner */ @@ -3178,13 +3275,67 @@ display_password_info_bar (EmpathyChat *self) } static void -chat_password_needed_changed_cb (EmpathyChat *self) +provide_saved_password_cb (GObject *tp_chat, + GAsyncResult *res, + gpointer user_data) { + EmpathyChat *self = user_data; EmpathyChatPriv *priv = GET_PRIV (self); + GError *error = NULL; + + if (!empathy_tp_chat_provide_password_finish (EMPATHY_TP_CHAT (tp_chat), res, + &error)) { + DEBUG ("error: %s", error->message); + /* FIXME: what should we do if that's another error? Close the channel? + * Display the raw D-Bus error to the user isn't very useful */ + if (g_error_matches (error, TP_ERRORS, TP_ERROR_AUTHENTICATION_FAILED)) { + display_password_info_bar (self); + gtk_widget_set_sensitive (priv->hpaned, FALSE); + } + g_error_free (error); + return; + } + + /* Room joined */ + gtk_widget_set_sensitive (priv->hpaned, TRUE); + gtk_widget_grab_focus (self->input_text_view); +} + +static void +chat_room_got_password_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyChat *self = user_data; + EmpathyChatPriv *priv = GET_PRIV (self); + const gchar *password; + GError *error = NULL; + + password = empathy_keyring_get_room_password_finish (priv->account, + result, &error); + + if (error != NULL) { + DEBUG ("Couldn't get room password: %s\n", error->message); + g_clear_error (&error); - if (empathy_tp_chat_password_needed (priv->tp_chat)) { display_password_info_bar (self); gtk_widget_set_sensitive (priv->hpaned, FALSE); + return; + } + + empathy_tp_chat_provide_password_async (priv->tp_chat, password, + provide_saved_password_cb, self); +} + +static void +chat_password_needed_changed_cb (EmpathyChat *self) +{ + EmpathyChatPriv *priv = GET_PRIV (self); + + if (empathy_tp_chat_password_needed (priv->tp_chat)) { + empathy_keyring_get_room_password_async (priv->account, + empathy_tp_chat_get_id (priv->tp_chat), + chat_room_got_password_cb, self); } } -- cgit v1.2.3