From 2218501731180797c5e29ce677f31fd2b2d3ecea Mon Sep 17 00:00:00 2001 From: Jasmine Hassan Date: Sat, 27 Oct 2012 06:11:08 +0200 Subject: [connect-dialog] handle psswds, display warns/errs in info bar, tweak UI details connect-dialog: integrate password handling Also, use the info bar to display warnings/errors, and tweak the UI details. http://git.gnome.org/browse/nautilus/commit/?id=7d004452f333b7b8b804d87de49c858e8743a115 --- src/caja-connect-server-dialog-main.c | 127 ++---- src/caja-connect-server-dialog-nonmain.c | 76 +++- src/caja-connect-server-dialog.c | 680 +++++++++++++++++++++++++++---- src/caja-connect-server-dialog.h | 47 ++- 4 files changed, 723 insertions(+), 207 deletions(-) diff --git a/src/caja-connect-server-dialog-main.c b/src/caja-connect-server-dialog-main.c index c73b0df4..4c80fc16 100644 --- a/src/caja-connect-server-dialog-main.c +++ b/src/caja-connect-server-dialog-main.c @@ -22,6 +22,7 @@ * * Authors: * Vincent Untz + * Cosimo Cecchi */ #include @@ -38,10 +39,9 @@ #include #include -#include "caja-window.h" #include "caja-connect-server-dialog.h" -static int open_dialogs; +static GSimpleAsyncResult *display_location_res = NULL; static void main_dialog_destroyed (GtkWidget *widget, @@ -53,117 +53,53 @@ main_dialog_destroyed (GtkWidget *widget, gtk_main_quit (); } -static void -error_dialog_destroyed (GtkWidget *widget, - GtkWidget *main_dialog) -{ - if (--open_dialogs <= 0) - gtk_widget_destroy (main_dialog); -} - -static void -display_error_dialog (GError *error, - const char *uri, - GtkWidget *parent) +gboolean +caja_connect_server_dialog_display_location_finish (CajaConnectServerDialog *self, + GAsyncResult *res, + GError **error) { - GtkDialog *error_dialog; - char *error_message; - - error_message = g_strdup_printf (_("Cannot display location \"%s\""), - uri); - error_dialog = eel_show_error_dialog (error_message, - error->message, - NULL); - - open_dialogs++; - - g_signal_connect (error_dialog, "destroy", - G_CALLBACK (error_dialog_destroyed), parent); - - gtk_window_set_screen (GTK_WINDOW (error_dialog), - gtk_widget_get_screen (parent)); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) { + return FALSE; + } - g_free (error_message); + return TRUE; } -static void -show_uri (const char *uri, - GtkWidget *widget) +void +caja_connect_server_dialog_display_location_async (CajaConnectServerDialog *self, + CajaApplication *application, + GFile *location, + GAsyncReadyCallback callback, + gpointer user_data) { - GError *error; + GError *error; GdkAppLaunchContext *launch_context; + gchar *uri; + display_location_res = g_simple_async_result_new (G_OBJECT (self), + callback, user_data, + caja_connect_server_dialog_display_location_async); + + error = NULL; + uri = g_file_get_uri (location); launch_context = gdk_app_launch_context_new (); gdk_app_launch_context_set_screen (launch_context, - gtk_widget_get_screen (widget)); + gtk_widget_get_screen (GTK_WIDGET (self))); - error = NULL; g_app_info_launch_default_for_uri (uri, G_APP_LAUNCH_CONTEXT (launch_context), &error); g_object_unref (launch_context); - if (error) - { - display_error_dialog (error, uri, widget); - g_error_free (error); - } - else - { - /* everything is OK, destroy the main dialog and quit */ - gtk_widget_destroy (widget); - } -} - -static void -mount_enclosing_ready_cb (GFile *location, - GAsyncResult *res, - GtkWidget *widget) -{ - char *uri; - gboolean success; - GError *error = NULL; - - uri = g_file_get_uri (location); - success = g_file_mount_enclosing_volume_finish (location, - res, &error); - - if (success || - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED)) - { - /* volume is mounted, show it */ - show_uri (uri, widget); - } - else - { - display_error_dialog (error, uri, widget); - } - - if (error) - { + if (error != NULL) { + g_simple_async_result_set_from_error (display_location_res, error); g_error_free (error); } + g_simple_async_result_complete_in_idle (display_location_res); - g_object_unref (location); - g_free (uri); -} - -void -caja_connect_server_dialog_present_uri (CajaApplication *application, - GFile *location, - GtkWidget *widget) -{ - GMountOperation *op; - - op = gtk_mount_operation_new (GTK_WINDOW (widget)); - g_mount_operation_set_password_save (op, G_PASSWORD_SAVE_FOR_SESSION); - g_file_mount_enclosing_volume (location, - 0, op, - NULL, - (GAsyncReadyCallback) mount_enclosing_ready_cb, - widget); - g_object_unref (op); + g_object_unref (display_location_res); + display_location_res = NULL; } int @@ -181,8 +117,6 @@ main (int argc, char *argv[]) /* Translators: This is the --help description for the connect to server app, the initial newlines are between the command line arg and the description */ context = g_option_context_new (N_("\n\nAdd connect to server mount")); - g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); - g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); @@ -202,7 +136,6 @@ main (int argc, char *argv[]) dialog = caja_connect_server_dialog_new (NULL); - open_dialogs = 0; g_signal_connect (dialog, "destroy", G_CALLBACK (main_dialog_destroyed), NULL); diff --git a/src/caja-connect-server-dialog-nonmain.c b/src/caja-connect-server-dialog-nonmain.c index 0f196ca0..78015f3e 100644 --- a/src/caja-connect-server-dialog-nonmain.c +++ b/src/caja-connect-server-dialog-nonmain.c @@ -31,29 +31,69 @@ * caja-connect-server-dialog-main.c for the standalone version. */ +static GSimpleAsyncResult *display_location_res = NULL; + +static void +window_go_to_cb (CajaWindow *window, + GError *error, + gpointer user_data) +{ + CajaConnectServerDialog *self; + + self = user_data; + + if (error != NULL) { + g_simple_async_result_set_from_error (display_location_res, error); + } + + g_simple_async_result_complete (display_location_res); + + g_object_unref (display_location_res); + display_location_res = NULL; +} + +gboolean +caja_connect_server_dialog_display_location_finish (CajaConnectServerDialog *self, + GAsyncResult *res, + GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) { + return FALSE; + } + + return TRUE; +} + void -caja_connect_server_dialog_present_uri (CajaApplication *application, - GFile *location, - GtkWidget *widget) +caja_connect_server_dialog_display_location_async (CajaConnectServerDialog *self, + CajaApplication *application, + GFile *location, + GAsyncReadyCallback callback, + gpointer user_data) { CajaWindow *window; + GtkWidget *widget; + + widget = GTK_WIDGET (self); - if (g_settings_get_boolean (caja_preferences, CAJA_PREFERENCES_ALWAYS_USE_BROWSER)) - { + display_location_res = + g_simple_async_result_new (G_OBJECT (self), + callback, user_data, + caja_connect_server_dialog_display_location_async); + + if (g_settings_get_boolean (caja_preferences, CAJA_PREFERENCES_ALWAYS_USE_BROWSER)) { window = caja_application_create_navigation_window (application, - NULL, - gtk_widget_get_screen (widget)); - caja_window_go_to (window, location); - } - else - { - caja_application_present_spatial_window (application, - NULL, - NULL, - location, - gtk_widget_get_screen (widget)); + NULL, + gtk_widget_get_screen (widget)); + } else { + window = caja_application_get_spatial_window (application, + NULL, + NULL, + location, + gtk_widget_get_screen (widget), + NULL); } - gtk_widget_destroy (widget); - g_object_unref (location); + caja_window_go_to_full (window, location, + window_go_to_cb, self); } diff --git a/src/caja-connect-server-dialog.c b/src/caja-connect-server-dialog.c index 38531856..ee5416bf 100644 --- a/src/caja-connect-server-dialog.c +++ b/src/caja-connect-server-dialog.c @@ -4,6 +4,7 @@ * Caja * * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2010 Cosimo Cecchi * * Caja is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +23,7 @@ */ #include + #include "caja-connect-server-dialog.h" #include @@ -29,20 +31,17 @@ #include #include #include -#include "caja-location-entry.h" + +#include "caja-application.h" +#include "caja-bookmark-list.h" +#include "caja-connect-server-operation.h" +#include "caja-window.h" + #include #include /* TODO: - * - dns-sd fill out servers - * - pre-fill user? * - name entry + pre-fill - * - folder browse function - */ - -/* TODO gio port: - * - see FIXME here - * - see FIXME in caja-connect-server-dialog-main.c */ struct _CajaConnectServerDialogDetails @@ -52,7 +51,8 @@ struct _CajaConnectServerDialogDetails GtkWidget *user_details; GtkWidget *port_spinbutton; - GtkWidget *table; + GtkWidget *info_bar; + GtkWidget *info_bar_content; GtkWidget *type_combo; GtkWidget *server_entry; @@ -60,14 +60,29 @@ struct _CajaConnectServerDialogDetails GtkWidget *folder_entry; GtkWidget *domain_entry; GtkWidget *user_entry; + GtkWidget *password_entry; + GtkWidget *remember_checkbox; + GtkWidget *connect_button; - GtkWidget *bookmark_check; - GtkWidget *name_entry; + GList *iconized_entries; + + GSimpleAsyncResult *fill_details_res; + GAskPasswordFlags fill_details_flags; + GMountOperation *fill_operation; + + gboolean last_password_set; + gulong password_sensitive_id; + gboolean should_destroy; }; G_DEFINE_TYPE (CajaConnectServerDialog, caja_connect_server_dialog, GTK_TYPE_DIALOG) +static void sensitive_entry_changed_callback (GtkEditable *editable, + GtkWidget *widget); +static void iconized_entry_changed_cb (GtkEditable *entry, + CajaConnectServerDialog *dialog); + enum { RESPONSE_CONNECT @@ -132,6 +147,341 @@ get_method_description (struct MethodInfo *meth) } } +static void +dialog_restore_info_bar (CajaConnectServerDialog *dialog, + GtkMessageType message_type) +{ + if (dialog->details->info_bar_content != NULL) { + gtk_widget_destroy (dialog->details->info_bar_content); + dialog->details->info_bar_content = NULL; + } + + gtk_info_bar_set_message_type (GTK_INFO_BAR (dialog->details->info_bar), + message_type); +} + +static void +dialog_set_connecting (CajaConnectServerDialog *dialog) +{ + GtkWidget *hbox; + GtkWidget *widget; + GtkWidget *content_area; + gint width, height; + + dialog_restore_info_bar (dialog, GTK_MESSAGE_INFO); + gtk_widget_show (dialog->details->info_bar); + + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar)); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (content_area), hbox); + gtk_widget_show (hbox); + + dialog->details->info_bar_content = hbox; + + widget = gtk_spinner_new (); + gtk_icon_size_lookup (GTK_ICON_SIZE_SMALL_TOOLBAR, &width, &height); + gtk_widget_set_size_request (widget, width, height); + gtk_spinner_start (GTK_SPINNER (widget)); + gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6); + gtk_widget_show (widget); + + widget = gtk_label_new (_("Connecting...")); + gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6); + gtk_widget_show (widget); + + gtk_widget_set_sensitive (dialog->details->connect_button, FALSE); +} + + +static void +iconized_entry_restore (gpointer data, + gpointer user_data) +{ + GtkEntry *entry; + CajaConnectServerDialog *dialog; + + entry = data; + dialog = user_data; + + gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, + NULL); + + g_signal_handlers_disconnect_by_func (entry, + iconized_entry_changed_cb, + dialog); +} + +static void +iconized_entry_changed_cb (GtkEditable *entry, + CajaConnectServerDialog *dialog) +{ + dialog->details->iconized_entries = + g_list_remove (dialog->details->iconized_entries, entry); + + iconized_entry_restore (entry, dialog); +} + +static void +iconize_entry (CajaConnectServerDialog *dialog, + GtkWidget *entry) +{ + dialog->details->iconized_entries = + g_list_prepend (dialog->details->iconized_entries, entry); + + gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_DIALOG_WARNING); + + gtk_widget_grab_focus (entry); + + g_signal_connect (entry, "changed", + G_CALLBACK (iconized_entry_changed_cb), dialog); +} + +static void +set_info_bar_error (CajaConnectServerDialog *dialog, + GError *error) +{ + GtkWidget *content_area, *label, *entry, *hbox, *icon; + gchar *str; + const gchar *folder, *server; + + dialog_restore_info_bar (dialog, GTK_MESSAGE_WARNING); + + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar)); + entry = NULL; + + switch (error->code) { + case G_IO_ERROR_FAILED_HANDLED: + return; + case G_IO_ERROR_NOT_FOUND: + folder = gtk_entry_get_text (GTK_ENTRY (dialog->details->folder_entry)); + server = gtk_entry_get_text (GTK_ENTRY (dialog->details->server_entry)); + str = g_strdup_printf (_("The folder \"%s\" cannot be opened on \"%s\"."), + folder, server); + label = gtk_label_new (str); + entry = dialog->details->folder_entry; + + g_free (str); + + break; + case G_IO_ERROR_HOST_NOT_FOUND: + server = gtk_entry_get_text (GTK_ENTRY (dialog->details->server_entry)); + str = g_strdup_printf (_("The server at \"%s\" cannot be found."), server); + label = gtk_label_new (str); + entry = dialog->details->server_entry; + + g_free (str); + + break; + case G_IO_ERROR_FAILED: + default: + label = gtk_label_new (error->message); + break; + } + + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_widget_show (dialog->details->info_bar); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 6); + gtk_widget_show (hbox); + + icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 6); + gtk_widget_show (icon); + + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); + gtk_widget_show (label); + + if (entry != NULL) { + iconize_entry (dialog, entry); + } + + dialog->details->info_bar_content = hbox; + + gtk_button_set_label (GTK_BUTTON (dialog->details->connect_button), + _("Try Again")); + gtk_widget_set_sensitive (dialog->details->connect_button, TRUE); +} + +static void +dialog_finish_fill (CajaConnectServerDialog *dialog) +{ + GAskPasswordFlags flags; + GMountOperation *op; + + flags = dialog->details->fill_details_flags; + op = G_MOUNT_OPERATION (dialog->details->fill_operation); + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + g_mount_operation_set_password (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->password_entry))); + } + + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + g_mount_operation_set_username (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->user_entry))); + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + g_mount_operation_set_domain (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->domain_entry))); + } + + if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED && + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->details->remember_checkbox))) { + g_mount_operation_set_password_save (op, G_PASSWORD_SAVE_PERMANENTLY); + } + + dialog_set_connecting (dialog); + + g_simple_async_result_set_op_res_gboolean (dialog->details->fill_details_res, TRUE); + g_simple_async_result_complete (dialog->details->fill_details_res); + + g_object_unref (dialog->details->fill_details_res); + dialog->details->fill_details_res = NULL; + + g_object_unref (dialog->details->fill_operation); + dialog->details->fill_operation = NULL; +} + +static void +dialog_request_additional_details (CajaConnectServerDialog *self, + GAskPasswordFlags flags, + const gchar *default_user, + const gchar *default_domain) +{ + GtkWidget *content_area, *label, *entry, *hbox, *icon; + + self->details->fill_details_flags = flags; + + dialog_restore_info_bar (self, GTK_MESSAGE_WARNING); + + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (self->details->info_bar)); + entry = NULL; + + hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 6); + gtk_widget_show (hbox); + + icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 6); + gtk_widget_show (icon); + + label = gtk_label_new (_("Please verify your user details.")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); + gtk_widget_show (label); + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + iconize_entry (self, self->details->password_entry); + } + + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + if (default_user != NULL && g_strcmp0 (default_user, "") != 0) { + gtk_entry_set_text (GTK_ENTRY (self->details->user_entry), + default_user); + } else { + iconize_entry (self, self->details->user_entry); + } + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + if (default_domain != NULL && g_strcmp0 (default_domain, "") != 0) { + gtk_entry_set_text (GTK_ENTRY (self->details->domain_entry), + default_domain); + } else { + iconize_entry (self, self->details->domain_entry); + } + } + + self->details->info_bar_content = hbox; + + gtk_widget_set_sensitive (self->details->connect_button, TRUE); + gtk_button_set_label (GTK_BUTTON (self->details->connect_button), + _("Continue")); + + if (!(flags & G_ASK_PASSWORD_SAVING_SUPPORTED)) { + g_signal_handler_disconnect (self->details->password_entry, + self->details->password_sensitive_id); + self->details->password_sensitive_id = 0; + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->details->remember_checkbox), + FALSE); + gtk_widget_set_sensitive (self->details->remember_checkbox, FALSE); + } +} + +static void +display_location_async_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + CajaConnectServerDialog *dialog; + GError *error; + + dialog = CAJA_CONNECT_SERVER_DIALOG (source); + error = NULL; + + caja_connect_server_dialog_display_location_finish (dialog, + res, &error); + + if (error != NULL) { + set_info_bar_error (dialog, error); + g_error_free (error); + } else { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } +} + +static void +mount_enclosing_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GFile *location; + CajaConnectServerDialog *dialog; + GError *error; + + error = NULL; + location = G_FILE (source); + dialog = user_data; + + g_file_mount_enclosing_volume_finish (location, res, &error); + + if (!error || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED)) { + /* volume is mounted, show it */ + caja_connect_server_dialog_display_location_async (dialog, + dialog->details->application, location, + display_location_async_cb, NULL); + } else { + if (dialog->details->should_destroy) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } else { + set_info_bar_error (dialog, error); + } + } + + if (error != NULL) { + g_error_free (error); + } +} + +static void +dialog_present_uri_async (CajaConnectServerDialog *self, + CajaApplication *application, + GFile *location) +{ + GMountOperation *op; + + op = caja_connect_server_operation_new (self); + g_file_mount_enclosing_volume (location, + 0, op, NULL, + mount_enclosing_ready_cb, self); + g_object_unref (op); +} + static void connect_to_server (CajaConnectServerDialog *dialog) { @@ -153,7 +503,7 @@ connect_to_server (CajaConnectServerDialog *dialog) server = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->server_entry), 0, -1); user = NULL; - initial_path = NULL; + initial_path = g_strdup (""); domain = NULL; folder = NULL; @@ -163,15 +513,14 @@ connect_to_server (CajaConnectServerDialog *dialog) /* SMB special case */ } else if (strcmp (meth->scheme, "smb") == 0) { + g_free (initial_path); + t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->share_entry), 0, -1); initial_path = g_strconcat ("/", t, NULL); g_free (t); } - /* port */ - port = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->details->port_spinbutton)); - /* username */ if (!user) { t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->user_entry), 0, -1); @@ -199,17 +548,17 @@ connect_to_server (CajaConnectServerDialog *dialog) join = ""; } - if (initial_path != NULL) { - t = folder; - folder = g_strconcat (initial_path, join, t, NULL); - g_free (t); - } + t = folder; + folder = g_strconcat (initial_path, join, t, NULL); + g_free (t); t = folder; folder = g_uri_escape_string (t, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE); g_free (t); /* port */ + port = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->details->port_spinbutton)); + if (port != 0 && port != meth->default_port) { port_str = g_strdup_printf ("%d", (int) port); } else { @@ -233,37 +582,56 @@ connect_to_server (CajaConnectServerDialog *dialog) g_free (domain); g_free (port_str); - gtk_widget_hide (GTK_WIDGET (dialog)); - location = g_file_new_for_uri (uri); g_free (uri); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->details->bookmark_check))) - { - char *name; - CajaBookmark *bookmark; - CajaBookmarkList *list; - GIcon *icon; - - name = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->name_entry), 0, -1); - icon = g_themed_icon_new (CAJA_ICON_FOLDER_REMOTE); - bookmark = caja_bookmark_new (location, strlen (name) ? name : NULL, - TRUE, icon); - list = caja_bookmark_list_new (); - if (!caja_bookmark_list_contains (list, bookmark)) - { - caja_bookmark_list_append (list, bookmark); + dialog_set_connecting (dialog); + dialog_present_uri_async (dialog, + dialog->details->application, + location); + + g_object_unref (location); +} + +static void +connect_to_server_or_finish_fill (CajaConnectServerDialog *dialog) +{ + if (dialog->details->fill_details_res != NULL) { + dialog_finish_fill (dialog); + } else { + connect_to_server (dialog); + } +} + +static gboolean +abort_mount_operation (CajaConnectServerDialog *dialog) +{ + if (dialog->details->fill_details_res != NULL) { + g_simple_async_result_set_op_res_gboolean (dialog->details->fill_details_res, FALSE); + g_simple_async_result_complete (dialog->details->fill_details_res); + + g_object_unref (dialog->details->fill_details_res); + dialog->details->fill_details_res = NULL; + + if (dialog->details->fill_operation) { + g_object_unref (dialog->details->fill_operation); + dialog->details->fill_operation = NULL; } - g_object_unref (bookmark); - g_object_unref (list); - g_object_unref (icon); - g_free (name); + return TRUE; } - caja_connect_server_dialog_present_uri (dialog->details->application, - location, - GTK_WIDGET (dialog)); + return FALSE; +} + +static void +destroy_dialog (CajaConnectServerDialog *dialog) +{ + if (abort_mount_operation (dialog)) { + dialog->details->should_destroy = TRUE; + } else { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } } static void @@ -276,12 +644,12 @@ response_callback (CajaConnectServerDialog *dialog, switch (response_id) { case RESPONSE_CONNECT: - connect_to_server (dialog); + connect_to_server_or_finish_fill (dialog); break; case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_CANCEL: - gtk_widget_destroy (GTK_WIDGET (dialog)); + destroy_dialog (dialog); break; case GTK_RESPONSE_HELP : error = NULL; @@ -300,9 +668,63 @@ response_callback (CajaConnectServerDialog *dialog, } } +static void +dialog_cleanup (CajaConnectServerDialog *dialog) +{ + /* hide the infobar */ + gtk_widget_hide (dialog->details->info_bar); + + /* set the connect button label back to 'Connect' */ + gtk_button_set_label (GTK_BUTTON (dialog->details->connect_button), + _("C_onnect")); + + /* if there was a pending mount operation, cancel it. */ + abort_mount_operation (dialog); + + /* restore password checkbox sensitivity */ + if (dialog->details->password_sensitive_id == 0) { + dialog->details->password_sensitive_id = + g_signal_connect (dialog->details->password_entry, "changed", + G_CALLBACK (sensitive_entry_changed_callback), + dialog->details->remember_checkbox); + sensitive_entry_changed_callback (GTK_EDITABLE (dialog->details->password_entry), + dialog->details->remember_checkbox); + } + + /* remove icons on the entries */ + g_list_foreach (dialog->details->iconized_entries, + (GFunc) iconized_entry_restore, dialog); + g_list_free (dialog->details->iconized_entries); + dialog->details->iconized_entries = NULL; + + dialog->details->last_password_set = FALSE; +} + +static void +caja_connect_server_dialog_finalize (GObject *object) +{ + CajaConnectServerDialog *dialog; + + dialog = CAJA_CONNECT_SERVER_DIALOG (object); + + abort_mount_operation (dialog); + + g_list_foreach (dialog->details->iconized_entries, + (GFunc) iconized_entry_restore, dialog); + g_list_free (dialog->details->iconized_entries); + dialog->details->iconized_entries = NULL; + + G_OBJECT_CLASS (caja_connect_server_dialog_parent_class)->finalize (object); +} + static void caja_connect_server_dialog_class_init (CajaConnectServerDialogClass *class) { + GObjectClass *oclass; + + oclass = G_OBJECT_CLASS (class); + oclass->finalize = caja_connect_server_dialog_finalize; + g_type_class_add_private (class, sizeof (CajaConnectServerDialogDetails)); } @@ -313,7 +735,9 @@ setup_for_type (CajaConnectServerDialog *dialog) int index; GtkTreeIter iter; - /* Get our method info */ + dialog_cleanup (dialog); + + /* get our method info */ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->details->type_combo), &iter); gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dialog->details->type_combo)), &iter, 0, &index, -1); @@ -342,6 +766,11 @@ setup_for_type (CajaConnectServerDialog *dialog) (meth->flags & SHOW_USER) != 0, NULL); + g_object_set (dialog->details->password_entry, + "visible", + (meth->flags & SHOW_USER) != 0, + NULL); + g_object_set (dialog->details->domain_entry, "visible", (meth->flags & SHOW_DOMAIN) != 0, @@ -349,15 +778,14 @@ setup_for_type (CajaConnectServerDialog *dialog) } static void -entry_changed_callback (GtkEditable *editable, - GtkWidget *connect_button) +sensitive_entry_changed_callback (GtkEditable *editable, + GtkWidget *widget) { guint length; length = gtk_entry_get_text_length (GTK_ENTRY (editable)); - gtk_widget_set_sensitive (connect_button, - length > 0); + gtk_widget_set_sensitive (widget, length > 0); } static void @@ -379,7 +807,7 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) GtkWidget *alignment; GtkWidget *content_area; GtkWidget *combo ,* table; - GtkWidget *hbox, *connect_button; + GtkWidget *hbox, *connect_button, *checkbox; GtkListStore *store; GtkCellRenderer *renderer; gchar *str; @@ -396,6 +824,13 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) gtk_box_set_spacing (GTK_BOX (content_area), 2); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + /* infobar */ + dialog->details->info_bar = gtk_info_bar_new (); + gtk_info_bar_set_message_type (GTK_INFO_BAR (dialog->details->info_bar), + GTK_MESSAGE_INFO); + gtk_box_pack_start (GTK_BOX (content_area), dialog->details->info_bar, + FALSE, FALSE, 6); + /* server settings label */ label = gtk_label_new (NULL); str = g_strdup_printf ("%s", _("Server Details")); @@ -480,7 +915,7 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) const gchar * const *supported; int j; - /* skip methods that don't have corresponding MateVFSMethods */ + /* skip methods that don't have corresponding gvfs uri schemes */ supported = g_vfs_get_supported_uri_schemes (g_vfs_get_default ()); if (methods[i].scheme != NULL) @@ -582,7 +1017,7 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) bind_visibility (dialog, alignment, label); dialog->details->user_details = alignment; - table = gtk_table_new (2, 2, FALSE); + table = gtk_table_new (4, 2, FALSE); gtk_container_add (GTK_CONTAINER (alignment), table); gtk_widget_show (table); @@ -620,28 +1055,33 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) bind_visibility (dialog, dialog->details->user_entry, label); - /* add as bookmark */ - dialog->details->bookmark_check = gtk_check_button_new_with_mnemonic (_("Add _bookmark")); - gtk_box_pack_start (GTK_BOX (content_area), dialog->details->bookmark_check, TRUE, TRUE, 0); - gtk_widget_show (dialog->details->bookmark_check); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0); - - label = gtk_label_new (_("Bookmark Name:")); + /* third row: password entry */ + label = gtk_label_new (_("Password:")); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); - - dialog->details->name_entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX (hbox), dialog->details->name_entry, TRUE, TRUE, 0); - - gtk_widget_show_all (hbox); - - g_object_bind_property (dialog->details->bookmark_check, "active", - dialog->details->name_entry, "sensitive", - G_BINDING_DEFAULT | - G_BINDING_SYNC_CREATE); - setup_for_type (dialog); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + + dialog->details->password_entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->password_entry), TRUE); + gtk_entry_set_visibility (GTK_ENTRY (dialog->details->password_entry), FALSE); + gtk_table_attach (GTK_TABLE (table), dialog->details->password_entry, + 1, 2, + 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + + bind_visibility (dialog, dialog->details->password_entry, label); + + /* fourth row: remember checkbox */ + checkbox = gtk_check_button_new_with_label (_("Remember this password")); + gtk_table_attach (GTK_TABLE (table), checkbox, + 1, 2, + 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 0); + dialog->details->remember_checkbox = checkbox; + + bind_visibility (dialog, dialog->details->password_entry, checkbox); gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_HELP, @@ -654,16 +1094,19 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) RESPONSE_CONNECT); gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_CONNECT); + dialog->details->connect_button = connect_button; g_signal_connect (dialog->details->server_entry, "changed", - G_CALLBACK (entry_changed_callback), + G_CALLBACK (sensitive_entry_changed_callback), connect_button); - entry_changed_callback (GTK_EDITABLE (dialog->details->server_entry), - connect_button); + sensitive_entry_changed_callback (GTK_EDITABLE (dialog->details->server_entry), + connect_button); g_signal_connect (dialog, "response", G_CALLBACK (response_callback), dialog); + + setup_for_type (dialog); } GtkWidget * @@ -684,3 +1127,82 @@ caja_connect_server_dialog_new (CajaWindow *window) return dialog; } + +gboolean +caja_connect_server_dialog_fill_details_finish (CajaConnectServerDialog *self, + GAsyncResult *result) +{ + return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result)); +} + +void +caja_connect_server_dialog_fill_details_async (CajaConnectServerDialog *self, + GMountOperation *operation, + const gchar *default_user, + const gchar *default_domain, + GAskPasswordFlags flags, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *fill_details_res; + const gchar *str; + GAskPasswordFlags set_flags; + + fill_details_res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + caja_connect_server_dialog_fill_details_async); + + self->details->fill_details_res = fill_details_res; + set_flags = (flags & G_ASK_PASSWORD_NEED_PASSWORD) | + (flags & G_ASK_PASSWORD_NEED_USERNAME) | + (flags & G_ASK_PASSWORD_NEED_DOMAIN); + + if (set_flags & G_ASK_PASSWORD_NEED_PASSWORD) { + /* provide the password */ + str = gtk_entry_get_text (GTK_ENTRY (self->details->password_entry)); + + if (str != NULL && g_strcmp0 (str, "") != 0 && + !self->details->last_password_set) { + g_mount_operation_set_password (G_MOUNT_OPERATION (operation), + str); + set_flags ^= G_ASK_PASSWORD_NEED_PASSWORD; + + self->details->last_password_set = TRUE; + } + } + + if (set_flags & G_ASK_PASSWORD_NEED_USERNAME) { + /* see if the default username is different from ours */ + str = gtk_entry_get_text (GTK_ENTRY (self->details->user_entry)); + + if (str != NULL && g_strcmp0 (str, "") != 0 && + g_strcmp0 (str, default_user) != 0) { + g_mount_operation_set_username (G_MOUNT_OPERATION (operation), + str); + set_flags ^= G_ASK_PASSWORD_NEED_USERNAME; + } + } + + if (set_flags & G_ASK_PASSWORD_NEED_DOMAIN) { + /* see if the default domain is different from ours */ + str = gtk_entry_get_text (GTK_ENTRY (self->details->domain_entry)); + + if (str != NULL && g_strcmp0 (str, "") && + g_strcmp0 (str, default_domain) != 0) { + g_mount_operation_set_domain (G_MOUNT_OPERATION (operation), + str); + set_flags ^= G_ASK_PASSWORD_NEED_DOMAIN; + } + } + + if (set_flags != 0) { + set_flags |= (flags & G_ASK_PASSWORD_SAVING_SUPPORTED); + self->details->fill_operation = g_object_ref (operation); + dialog_request_additional_details (self, set_flags, default_user, default_domain); + } else { + g_simple_async_result_set_op_res_gboolean (fill_details_res, TRUE); + g_simple_async_result_complete (fill_details_res); + g_object_unref (self->details->fill_details_res); + + self->details->fill_details_res = NULL; + } +} diff --git a/src/caja-connect-server-dialog.h b/src/caja-connect-server-dialog.h index 65c8c58e..1876e8a9 100644 --- a/src/caja-connect-server-dialog.h +++ b/src/caja-connect-server-dialog.h @@ -1,9 +1,9 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - /* * Caja * * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2010 Cosimo Cecchi * * Caja is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,15 +26,22 @@ #include #include + #include "caja-window.h" -#define CAJA_TYPE_CONNECT_SERVER_DIALOG (caja_connect_server_dialog_get_type ()) -#define CAJA_CONNECT_SERVER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAJA_TYPE_CONNECT_SERVER_DIALOG, CajaConnectServerDialog)) -#define CAJA_CONNECT_SERVER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAJA_TYPE_CONNECT_SERVER_DIALOG, CajaConnectServerDialogClass)) -#define CAJA_IS_CONNECT_SERVER_DIALOG(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), CAJA_TYPE_CONNECT_SERVER_DIALOG) +#define CAJA_TYPE_CONNECT_SERVER_DIALOG\ + (caja_connect_server_dialog_get_type ()) +#define CAJA_CONNECT_SERVER_DIALOG(obj)\ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAJA_TYPE_CONNECT_SERVER_DIALOG,\ + CajaConnectServerDialog)) +#define CAJA_CONNECT_SERVER_DIALOG_CLASS(klass)\ + (G_TYPE_CHECK_CLASS_CAST ((klass), CAJA_TYPE_CONNECT_SERVER_DIALOG,\ + CajaConnectServerDialogClass)) +#define CAJA_IS_CONNECT_SERVER_DIALOG(obj)\ + (G_TYPE_INSTANCE_CHECK_TYPE ((obj), CAJA_TYPE_CONNECT_SERVER_DIALOG) -typedef struct _CajaConnectServerDialog CajaConnectServerDialog; -typedef struct _CajaConnectServerDialogClass CajaConnectServerDialogClass; +typedef struct _CajaConnectServerDialog CajaConnectServerDialog; +typedef struct _CajaConnectServerDialogClass CajaConnectServerDialogClass; typedef struct _CajaConnectServerDialogDetails CajaConnectServerDialogDetails; struct _CajaConnectServerDialog @@ -48,13 +55,27 @@ struct _CajaConnectServerDialogClass GtkDialogClass parent_class; }; -GType caja_connect_server_dialog_get_type (void); -GtkWidget* caja_connect_server_dialog_new (CajaWindow *window); +GType caja_connect_server_dialog_get_type (void); + +GtkWidget* caja_connect_server_dialog_new (CajaWindow *window); -/* Private internal calls */ +void caja_connect_server_dialog_display_location_async (CajaConnectServerDialog *self, + CajaApplication *application, + GFile *location, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean caja_connect_server_dialog_display_location_finish (CajaConnectServerDialog *self, + GAsyncResult *result, + GError **error); -void caja_connect_server_dialog_present_uri (CajaApplication *application, - GFile *location, - GtkWidget *widget); +void caja_connect_server_dialog_fill_details_async (CajaConnectServerDialog *self, + GMountOperation *operation, + const gchar *default_user, + const gchar *default_domain, + GAskPasswordFlags flags, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean caja_connect_server_dialog_fill_details_finish (CajaConnectServerDialog *self, + GAsyncResult *result); #endif /* CAJA_CONNECT_SERVER_DIALOG_H */ -- cgit v1.2.1