[nautilus] connect-dialog: integrate password handling



commit 7d004452f333b7b8b804d87de49c858e8743a115
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Sep 1 13:41:56 2010 +0200

    connect-dialog: integrate password handling
    
    Also, use the info bar to display warnings/errors, and tweak the UI
    details.

 src/nautilus-connect-server-dialog-main.c    |  118 ++----
 src/nautilus-connect-server-dialog-nonmain.c |   65 ++-
 src/nautilus-connect-server-dialog.c         |  674 +++++++++++++++++++++++---
 src/nautilus-connect-server-dialog.h         |   49 ++-
 4 files changed, 718 insertions(+), 188 deletions(-)
---
diff --git a/src/nautilus-connect-server-dialog-main.c b/src/nautilus-connect-server-dialog-main.c
index 03c5e71..d047d03 100644
--- a/src/nautilus-connect-server-dialog-main.c
+++ b/src/nautilus-connect-server-dialog-main.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *   Vincent Untz <vincent vuntz net>
+ *   Cosimo Cecchi <cosimoc gnome org>
  */
 
 #include <config.h>
@@ -38,10 +39,9 @@
 #include <libnautilus-private/nautilus-icon-names.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
 
-#include "nautilus-window.h"
 #include "nautilus-connect-server-dialog.h"
 
-static int open_dialogs;
+static GSimpleAsyncResult *display_location_res = NULL;
 
 static void
 main_dialog_destroyed (GtkWidget *widget,
@@ -53,110 +53,55 @@ 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
+nautilus_connect_server_dialog_display_location_finish (NautilusConnectServerDialog *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
+nautilus_connect_server_dialog_display_location_async (NautilusConnectServerDialog *self,
+						       NautilusApplication *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,
+							  nautilus_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);
+	if (error != NULL) {
+		g_simple_async_result_set_from_error (display_location_res, error);
 		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);
-	}
+	g_simple_async_result_complete_in_idle (display_location_res);
 
-	if (error) {
-		g_error_free (error);
-	}
-
-	g_object_unref (location);
 	g_free (uri);
-}
-
-void
-nautilus_connect_server_dialog_present_uri (NautilusApplication *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
@@ -174,8 +119,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));
 
@@ -194,7 +137,6 @@ main (int argc, char *argv[])
 
 	dialog = nautilus_connect_server_dialog_new (NULL);
 
-	open_dialogs = 0;
 	g_signal_connect (dialog, "destroy",
 			  G_CALLBACK (main_dialog_destroyed), NULL);
 
diff --git a/src/nautilus-connect-server-dialog-nonmain.c b/src/nautilus-connect-server-dialog-nonmain.c
index 0dd015f..b6b2ada 100644
--- a/src/nautilus-connect-server-dialog-nonmain.c
+++ b/src/nautilus-connect-server-dialog-nonmain.c
@@ -31,26 +31,69 @@
  * nautilus-connect-server-dialog-main.c for the standalone version.
  */
 
+static GSimpleAsyncResult *display_location_res = NULL;
+
+static void
+window_go_to_cb (NautilusWindow *window,
+		 GError *error,
+		 gpointer user_data)
+{
+	NautilusConnectServerDialog *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
+nautilus_connect_server_dialog_display_location_finish (NautilusConnectServerDialog *self,
+							GAsyncResult *res,
+							GError **error)
+{
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 void
-nautilus_connect_server_dialog_present_uri (NautilusApplication *application,
-					    GFile *location,
-					    GtkWidget *widget)
+nautilus_connect_server_dialog_display_location_async (NautilusConnectServerDialog *self,
+						       NautilusApplication *application,
+						       GFile *location,
+						       GAsyncReadyCallback callback,
+						       gpointer user_data)
 {
 	NautilusWindow *window;
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (self);
+
+	display_location_res =
+		g_simple_async_result_new (G_OBJECT (self),
+					   callback, user_data,
+					   nautilus_connect_server_dialog_display_location_async);
 
 	if (g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
 		window = nautilus_application_create_navigation_window (application,
 									NULL,
 									gtk_widget_get_screen (widget));
-		nautilus_window_go_to (window, location);
 	} else {
-		nautilus_application_present_spatial_window (application,
-							     NULL,
-							     NULL,
-							     location,
-							     gtk_widget_get_screen (widget));
+		window = nautilus_application_get_spatial_window (application,
+								  NULL,
+								  NULL,
+								  location,
+								  gtk_widget_get_screen (widget),
+								  NULL);
 	}
 
-	gtk_widget_destroy (widget);
-	g_object_unref (location);
+	nautilus_window_go_to_full (window, location,
+				    window_go_to_cb, self);
 }
diff --git a/src/nautilus-connect-server-dialog.c b/src/nautilus-connect-server-dialog.c
index 22cbd2b..7b2207c 100644
--- a/src/nautilus-connect-server-dialog.c
+++ b/src/nautilus-connect-server-dialog.c
@@ -3,6 +3,7 @@
  * Nautilus
  *
  * Copyright (C) 2003 Red Hat, Inc.
+ * Copyright (C) 2010 Cosimo Cecchi <cosimoc gnome org>
  *
  * Nautilus is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -21,6 +22,7 @@
  */
 
 #include <config.h>
+
 #include "nautilus-connect-server-dialog.h"
 
 #include <string.h>
@@ -28,20 +30,17 @@
 #include <glib/gi18n.h>
 #include <gio/gio.h>
 #include <gtk/gtk.h>
-#include "nautilus-location-entry.h"
+
+#include "nautilus-application.h"
+#include "nautilus-bookmark-list.h"
+#include "nautilus-connect-server-operation.h"
+#include "nautilus-window.h"
+
 #include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-icon-names.h>
 
 /* 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 nautilus-connect-server-dialog-main.c
  */
 
 struct _NautilusConnectServerDialogDetails {
@@ -50,7 +49,8 @@ struct _NautilusConnectServerDialogDetails {
 	GtkWidget *user_details;
 	GtkWidget *port_spinbutton;
 
-	GtkWidget *table;
+	GtkWidget *info_bar;
+	GtkWidget *info_bar_content;
 	
 	GtkWidget *type_combo;
 	GtkWidget *server_entry;
@@ -58,14 +58,29 @@ struct _NautilusConnectServerDialogDetails {
 	GtkWidget *folder_entry;
 	GtkWidget *domain_entry;
 	GtkWidget *user_entry;
+	GtkWidget *password_entry;
+	GtkWidget *remember_checkbox;
+	GtkWidget *connect_button;
+
+	GList *iconized_entries;
 
-	GtkWidget *bookmark_check;
-	GtkWidget *name_entry;
+	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 (NautilusConnectServerDialog, nautilus_connect_server_dialog,
 	       GTK_TYPE_DIALOG)
 
+static void sensitive_entry_changed_callback (GtkEditable *editable,
+					      GtkWidget *widget);
+static void iconized_entry_changed_cb (GtkEditable *entry,
+				       NautilusConnectServerDialog *dialog);
+
 enum {
 	RESPONSE_CONNECT
 };	
@@ -127,6 +142,341 @@ get_method_description (struct MethodInfo *meth)
 }
 
 static void
+dialog_restore_info_bar (NautilusConnectServerDialog *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 (NautilusConnectServerDialog *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;
+	NautilusConnectServerDialog *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,
+			   NautilusConnectServerDialog *dialog)
+{
+	dialog->details->iconized_entries =
+		g_list_remove (dialog->details->iconized_entries, entry);
+
+	iconized_entry_restore (entry, dialog);
+}
+
+static void
+iconize_entry (NautilusConnectServerDialog *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 (NautilusConnectServerDialog *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 (NautilusConnectServerDialog *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 (NautilusConnectServerDialog *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)
+{
+	NautilusConnectServerDialog *dialog;
+	GError *error;
+
+	dialog = NAUTILUS_CONNECT_SERVER_DIALOG (source);
+	error = NULL;
+
+	nautilus_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;
+	NautilusConnectServerDialog *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 */
+		nautilus_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 (NautilusConnectServerDialog *self,
+			  NautilusApplication *application,
+			  GFile *location)
+{
+	GMountOperation *op;
+
+	op = nautilus_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 (NautilusConnectServerDialog *dialog)
 {
 	struct MethodInfo *meth;
@@ -147,7 +497,7 @@ connect_to_server (NautilusConnectServerDialog *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;
 
@@ -157,15 +507,14 @@ connect_to_server (NautilusConnectServerDialog *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);
@@ -193,17 +542,17 @@ connect_to_server (NautilusConnectServerDialog *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 {
@@ -227,35 +576,56 @@ connect_to_server (NautilusConnectServerDialog *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;
-		NautilusBookmark *bookmark;
-		NautilusBookmarkList *list;
-		GIcon *icon;
-
-		name = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->name_entry), 0, -1);
-		icon = g_themed_icon_new (NAUTILUS_ICON_FOLDER_REMOTE);
-		bookmark = nautilus_bookmark_new (location, strlen (name) ? name : NULL,
-		                                  TRUE, icon);
-		list = nautilus_bookmark_list_new ();
-		if (!nautilus_bookmark_list_contains (list, bookmark)) {
-			nautilus_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 (NautilusConnectServerDialog *dialog)
+{
+	if (dialog->details->fill_details_res != NULL) {
+		dialog_finish_fill (dialog);
+	} else {
+		connect_to_server (dialog);
+	}
+}
+
+static gboolean
+abort_mount_operation (NautilusConnectServerDialog *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;
 	}
 
-	nautilus_connect_server_dialog_present_uri (dialog->details->application,
-						    location,
-						    GTK_WIDGET (dialog));
+	return FALSE;
+}
+
+static void
+destroy_dialog (NautilusConnectServerDialog *dialog)
+{
+	if (abort_mount_operation (dialog)) {
+		dialog->details->should_destroy = TRUE;
+	} else {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+	}
 }
 
 static void
@@ -267,12 +637,12 @@ response_callback (NautilusConnectServerDialog *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;
@@ -291,8 +661,62 @@ response_callback (NautilusConnectServerDialog *dialog,
 }
 
 static void
+dialog_cleanup (NautilusConnectServerDialog *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
+nautilus_connect_server_dialog_finalize (GObject *object)
+{
+	NautilusConnectServerDialog *dialog;
+
+	dialog = NAUTILUS_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 (nautilus_connect_server_dialog_parent_class)->finalize (object);
+}
+
+static void
 nautilus_connect_server_dialog_class_init (NautilusConnectServerDialogClass *class)
 {
+	GObjectClass *oclass;
+
+	oclass = G_OBJECT_CLASS (class);
+	oclass->finalize = nautilus_connect_server_dialog_finalize;
+
 	g_type_class_add_private (class, sizeof (NautilusConnectServerDialogDetails));
 }
 
@@ -302,8 +726,10 @@ setup_for_type (NautilusConnectServerDialog *dialog)
 	struct MethodInfo *meth;
 	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);
@@ -332,6 +758,11 @@ setup_for_type (NautilusConnectServerDialog *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,
@@ -339,15 +770,14 @@ setup_for_type (NautilusConnectServerDialog *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
@@ -369,7 +799,7 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *dialog)
 	GtkWidget *alignment;
 	GtkWidget *content_area;
 	GtkWidget *combo ,* table;
-	GtkWidget *hbox, *connect_button;
+	GtkWidget *hbox, *connect_button, *checkbox;
 	GtkListStore *store;
 	GtkCellRenderer *renderer;
 	gchar *str;
@@ -386,6 +816,13 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *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 ("<b>%s</b>", _("Server Details"));
@@ -469,7 +906,7 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *dialog)
 		const gchar * const *supported;
 		int j;
 
-		/* skip methods that don't have corresponding GnomeVFSMethods */
+		/* 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) {
@@ -566,7 +1003,7 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *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);
 
@@ -604,28 +1041,33 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *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);
+	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);
 
-	dialog->details->name_entry = gtk_entry_new ();
-	gtk_box_pack_start (GTK_BOX (hbox), dialog->details->name_entry, TRUE, TRUE, 0);
+	bind_visibility (dialog, dialog->details->password_entry, label);
 
-	gtk_widget_show_all (hbox);
+	/* 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;
 
-	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);
+	bind_visibility (dialog, dialog->details->password_entry, checkbox);
 
         gtk_dialog_add_button (GTK_DIALOG (dialog),
                                GTK_STOCK_HELP,
@@ -638,16 +1080,19 @@ nautilus_connect_server_dialog_init (NautilusConnectServerDialog *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 *
@@ -667,3 +1112,82 @@ nautilus_connect_server_dialog_new (NautilusWindow *window)
 
 	return dialog;
 }
+
+gboolean
+nautilus_connect_server_dialog_fill_details_finish (NautilusConnectServerDialog *self,
+						    GAsyncResult *result)
+{
+	return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+}
+
+void
+nautilus_connect_server_dialog_fill_details_async (NautilusConnectServerDialog *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,
+						      nautilus_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/nautilus-connect-server-dialog.h b/src/nautilus-connect-server-dialog.h
index 2fcd8a5..254896d 100644
--- a/src/nautilus-connect-server-dialog.h
+++ b/src/nautilus-connect-server-dialog.h
@@ -1,9 +1,9 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-
 /*
  * Nautilus
  *
  * Copyright (C) 2003 Red Hat, Inc.
+ * Copyright (C) 2010 Cosimo Cecchi <cosimoc gnome org>
  *
  * Nautilus 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 <gio/gio.h>
 #include <gtk/gtk.h>
+
 #include "nautilus-window.h"
 
-#define NAUTILUS_TYPE_CONNECT_SERVER_DIALOG         (nautilus_connect_server_dialog_get_type ())
-#define NAUTILUS_CONNECT_SERVER_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG, NautilusConnectServerDialog))
-#define NAUTILUS_CONNECT_SERVER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG, NautilusConnectServerDialogClass))
-#define NAUTILUS_IS_CONNECT_SERVER_DIALOG(obj)      (G_TYPE_INSTANCE_CHECK_TYPE ((obj), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG)
+#define NAUTILUS_TYPE_CONNECT_SERVER_DIALOG\
+	(nautilus_connect_server_dialog_get_type ())
+#define NAUTILUS_CONNECT_SERVER_DIALOG(obj)\
+        (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG,\
+				     NautilusConnectServerDialog))
+#define NAUTILUS_CONNECT_SERVER_DIALOG_CLASS(klass)\
+	(G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG,\
+				  NautilusConnectServerDialogClass))
+#define NAUTILUS_IS_CONNECT_SERVER_DIALOG(obj)\
+	(G_TYPE_INSTANCE_CHECK_TYPE ((obj), NAUTILUS_TYPE_CONNECT_SERVER_DIALOG)
 
-typedef struct _NautilusConnectServerDialog        NautilusConnectServerDialog;
-typedef struct _NautilusConnectServerDialogClass   NautilusConnectServerDialogClass;
+typedef struct _NautilusConnectServerDialog NautilusConnectServerDialog;
+typedef struct _NautilusConnectServerDialogClass NautilusConnectServerDialogClass;
 typedef struct _NautilusConnectServerDialogDetails NautilusConnectServerDialogDetails;
 
 struct _NautilusConnectServerDialog {
@@ -46,13 +53,27 @@ struct _NautilusConnectServerDialogClass {
 	GtkDialogClass parent_class;
 };
 
-GType      nautilus_connect_server_dialog_get_type (void);
-GtkWidget* nautilus_connect_server_dialog_new      (NautilusWindow *window);
+GType nautilus_connect_server_dialog_get_type (void);
+
+GtkWidget* nautilus_connect_server_dialog_new (NautilusWindow *window);
+
+void nautilus_connect_server_dialog_display_location_async (NautilusConnectServerDialog *self,
+							    NautilusApplication *application,
+							    GFile *location,
+							    GAsyncReadyCallback callback,
+							    gpointer user_data);
+gboolean nautilus_connect_server_dialog_display_location_finish (NautilusConnectServerDialog *self,
+								 GAsyncResult *result,
+								 GError **error);
 
-/* Private internal calls */
+void nautilus_connect_server_dialog_fill_details_async (NautilusConnectServerDialog *self,
+							GMountOperation *operation,
+							const gchar *default_user,
+							const gchar *default_domain,
+							GAskPasswordFlags flags,
+							GAsyncReadyCallback callback,
+							gpointer user_data);
+gboolean nautilus_connect_server_dialog_fill_details_finish (NautilusConnectServerDialog *self,
+							     GAsyncResult *result);
 
-void       nautilus_connect_server_dialog_present_uri (NautilusApplication *application,
-						       GFile *location,
-						       GtkWidget *widget);
-						     
 #endif /* NAUTILUS_CONNECT_SERVER_DIALOG_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]