diff options
Diffstat (limited to 'src/caja-connect-server-dialog.c')
-rw-r--r-- | src/caja-connect-server-dialog.c | 1644 |
1 files changed, 910 insertions, 734 deletions
diff --git a/src/caja-connect-server-dialog.c b/src/caja-connect-server-dialog.c index 3737a15b..6c6036fe 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 <[email protected]> * * Caja is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,56 +23,68 @@ */ #include <config.h> + #include "caja-connect-server-dialog.h" #include <string.h> -#include <eel/eel-gtk-macros.h> #include <eel/eel-stock-dialogs.h> -#include <eel/eel-vfs-extensions.h> #include <glib/gi18n.h> #include <gio/gio.h> #include <gtk/gtk.h> -#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 <libcaja-private/caja-global-preferences.h> #include <libcaja-private/caja-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 caja-connect-server-dialog-main.c + * - NetworkManager integration */ struct _CajaConnectServerDialogDetails { CajaApplication *application; - GtkWidget *table; + GtkWidget *primary_table; + GtkWidget *user_details; + GtkWidget *port_spinbutton; + + GtkWidget *info_bar; + GtkWidget *info_bar_content; GtkWidget *type_combo; - GtkWidget *uri_entry; GtkWidget *server_entry; GtkWidget *share_entry; - GtkWidget *port_entry; 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; }; -static void caja_connect_server_dialog_class_init (CajaConnectServerDialogClass *class); -static void caja_connect_server_dialog_init (CajaConnectServerDialog *dialog); +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); -EEL_CLASS_BOILERPLATE (CajaConnectServerDialog, - caja_connect_server_dialog, - GTK_TYPE_DIALOG) enum { RESPONSE_CONNECT @@ -81,345 +94,435 @@ struct MethodInfo { const char *scheme; guint flags; + guint default_port; }; /* A collection of flags for MethodInfo.flags */ enum { - DEFAULT_METHOD = 0x00000001, + DEFAULT_METHOD = (1 << 0), - /* Widgets to display in setup_for_type */ - SHOW_SHARE = 0x00000010, - SHOW_PORT = 0x00000020, - SHOW_USER = 0x00000040, - SHOW_DOMAIN = 0x00000080, + /* Widgets to display in connect_dialog_setup_for_type */ + SHOW_SHARE = (1 << 1), + SHOW_PORT = (1 << 2), + SHOW_USER = (1 << 3), + SHOW_DOMAIN = (1 << 4), - IS_ANONYMOUS = 0x00001000 + IS_ANONYMOUS = (1 << 5) }; /* Remember to fill in descriptions below */ static struct MethodInfo methods[] = { /* FIXME: we need to alias ssh to sftp */ - { "sftp", SHOW_PORT | SHOW_USER }, - { "ftp", SHOW_PORT | SHOW_USER }, - { "ftp", DEFAULT_METHOD | IS_ANONYMOUS | SHOW_PORT}, - { "smb", SHOW_SHARE | SHOW_USER | SHOW_DOMAIN }, - { "dav", SHOW_PORT | SHOW_USER }, + { "sftp", SHOW_PORT | SHOW_USER, 22 }, + { "ftp", SHOW_PORT | SHOW_USER, 21 }, + { "ftp", DEFAULT_METHOD | IS_ANONYMOUS | SHOW_PORT, 21 }, + { "smb", SHOW_SHARE | SHOW_USER | SHOW_DOMAIN, 0 }, + { "dav", SHOW_PORT | SHOW_USER, 80 }, /* FIXME: hrm, shouldn't it work? */ - { "davs", SHOW_PORT | SHOW_USER }, - { NULL, 0 }, /* Custom URI method */ + { "davs", SHOW_PORT | SHOW_USER, 443 }, }; /* To get around non constant gettext strings */ static const char* get_method_description (struct MethodInfo *meth) { - if (!meth->scheme) - { - return _("Custom Location"); - } - else if (strcmp (meth->scheme, "sftp") == 0) - { + if (strcmp (meth->scheme, "sftp") == 0) { return _("SSH"); - } - else if (strcmp (meth->scheme, "ftp") == 0) - { - if (meth->flags & IS_ANONYMOUS) - { + } else if (strcmp (meth->scheme, "ftp") == 0) { + if (meth->flags & IS_ANONYMOUS) { return _("Public FTP"); - } - else - { + } else { return _("FTP (with login)"); } - } - else if (strcmp (meth->scheme, "smb") == 0) - { + } else if (strcmp (meth->scheme, "smb") == 0) { return _("Windows share"); - } - else if (strcmp (meth->scheme, "dav") == 0) - { + } else if (strcmp (meth->scheme, "dav") == 0) { return _("WebDAV (HTTP)"); - } - else if (strcmp (meth->scheme, "davs") == 0) - { + } else if (strcmp (meth->scheme, "davs") == 0) { return _("Secure WebDAV (HTTPS)"); /* No descriptive text */ - } - else - { + } else { return meth->scheme; } } static void -caja_connect_server_dialog_finalize (GObject *object) +connect_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 +connect_dialog_set_connecting (CajaConnectServerDialog *dialog) { - CajaConnectServerDialog *dialog; + GtkWidget *hbox; + GtkWidget *widget; + GtkWidget *content_area; + gint width, height; + + connect_dialog_restore_info_bar (dialog, GTK_MESSAGE_INFO); + gtk_widget_show (dialog->details->info_bar); - dialog = CAJA_CONNECT_SERVER_DIALOG (object); + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar)); - g_object_unref (dialog->details->uri_entry); - g_object_unref (dialog->details->server_entry); - g_object_unref (dialog->details->share_entry); - g_object_unref (dialog->details->port_entry); - g_object_unref (dialog->details->folder_entry); - g_object_unref (dialog->details->domain_entry); - g_object_unref (dialog->details->user_entry); - g_object_unref (dialog->details->bookmark_check); - g_object_unref (dialog->details->name_entry); + hbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (content_area), hbox); + gtk_widget_show (hbox); - g_free (dialog->details); + dialog->details->info_bar_content = hbox; - EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); + 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 -caja_connect_server_dialog_destroy (GtkObject *object) +connect_dialog_gvfs_error (CajaConnectServerDialog *dialog) { - CajaConnectServerDialog *dialog; + GtkWidget *hbox, *image, *content_area, *label; + + connect_dialog_restore_info_bar (dialog, GTK_MESSAGE_ERROR); - dialog = CAJA_CONNECT_SERVER_DIALOG (object); + content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar)); - EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); + hbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (content_area), hbox); + gtk_widget_show (hbox); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 6); + gtk_widget_show (image); + + label = gtk_label_new (_("Can't load the supported server method list.\n" + "Please check your GVfs installation.")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); + gtk_widget_show (label); + + gtk_widget_set_sensitive (dialog->details->connect_button, FALSE); + gtk_widget_set_sensitive (dialog->details->primary_table, FALSE); + + gtk_widget_show (dialog->details->info_bar); } static void -connect_to_server (CajaConnectServerDialog *dialog) +iconized_entry_restore (gpointer data, + gpointer user_data) { - struct MethodInfo *meth; - char *uri; - GFile *location; - int index; - GtkTreeIter iter; + GtkEntry *entry; + CajaConnectServerDialog *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); - g_assert (index < G_N_ELEMENTS (methods) && index >= 0); - meth = &(methods[index]); - - uri = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->server_entry), 0, -1); - if (strlen (uri) == 0) - { - eel_show_error_dialog (_("Cannot Connect to Server. You must enter a name for the server."), - _("Please enter a name and try again."), - GTK_WINDOW (dialog)); - g_free (uri); - return; - } + entry = data; + dialog = user_data; - if (meth->scheme == NULL) - { - uri = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->uri_entry), 0, -1); - /* FIXME: we should validate it in some way? */ - } - else - { - char *user, *port, *initial_path, *server, *folder, *domain; - char *t, *join; - gboolean free_initial_path, free_user, free_domain, free_port; - - server = uri; - uri = NULL; - - user = ""; - port = ""; - initial_path = ""; - domain = ""; - free_initial_path = FALSE; - free_user = FALSE; - free_domain = FALSE; - free_port = FALSE; - - /* FTP special case */ - if (meth->flags & IS_ANONYMOUS) - { - user = "anonymous"; + gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, + NULL); - /* SMB special case */ - } - else if (strcmp (meth->scheme, "smb") == 0) - { - t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->share_entry), 0, -1); - initial_path = g_strconcat ("/", t, NULL); - free_initial_path = TRUE; - g_free (t); - } - - if (gtk_widget_get_parent (dialog->details->port_entry) != NULL) - { - free_port = TRUE; - port = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->port_entry), 0, -1); - } - folder = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->folder_entry), 0, -1); - if (gtk_widget_get_parent (dialog->details->user_entry) != NULL) - { - free_user = TRUE; + g_signal_handlers_disconnect_by_func (entry, + iconized_entry_changed_cb, + dialog); +} - t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->user_entry), 0, -1); +static void +iconized_entry_changed_cb (GtkEditable *entry, + CajaConnectServerDialog *dialog) +{ + dialog->details->iconized_entries = + g_list_remove (dialog->details->iconized_entries, entry); - user = g_uri_escape_string (t, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE); + iconized_entry_restore (entry, dialog); +} - g_free (t); - } - if (gtk_widget_get_parent (dialog->details->domain_entry) != NULL) - { - free_domain = TRUE; +static void +iconize_entry (CajaConnectServerDialog *dialog, + GtkWidget *entry) +{ + if (!g_list_find (dialog->details->iconized_entries, entry)) { + dialog->details->iconized_entries = + g_list_prepend (dialog->details->iconized_entries, entry); - domain = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->domain_entry), 0, -1); + gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_DIALOG_WARNING); - if (strlen (domain) != 0) - { - t = user; + gtk_widget_grab_focus (entry); - user = g_strconcat (domain , ";" , t, NULL); + g_signal_connect (entry, "changed", + G_CALLBACK (iconized_entry_changed_cb), dialog); + } +} - if (free_user) - { - g_free (t); - } +static void +connect_dialog_set_info_bar_error (CajaConnectServerDialog *dialog, + GError *error) +{ + GtkWidget *content_area, *label, *entry, *hbox, *icon; + gchar *str; + const gchar *folder, *server; + + connect_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); +} - free_user = TRUE; - } - } +static void +connect_dialog_finish_fill (CajaConnectServerDialog *dialog) +{ + GAskPasswordFlags flags; + GMountOperation *op; - if (folder[0] != 0 && - folder[0] != '/') - { - join = "/"; - } - else - { - join = ""; - } + flags = dialog->details->fill_details_flags; + op = G_MOUNT_OPERATION (dialog->details->fill_operation); - t = folder; - folder = g_strconcat (initial_path, join, t, NULL); - g_free (t); + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + g_mount_operation_set_password (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->password_entry))); + } - t = folder; - folder = g_uri_escape_string (t, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE); - g_free (t); + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + g_mount_operation_set_username (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->user_entry))); + } - uri = g_strdup_printf ("%s://%s%s%s%s%s%s", - meth->scheme, - user, (user[0] != 0) ? "@" : "", - server, - (port[0] != 0) ? ":" : "", port, - folder); + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + g_mount_operation_set_domain (op, gtk_entry_get_text (GTK_ENTRY (dialog->details->domain_entry))); + } - if (free_initial_path) - { - g_free (initial_path); - } - g_free (server); - if (free_port) - { - g_free (port); - } - g_free (folder); - if (free_user) - { - g_free (user); - } - if (free_domain) - { - g_free (domain); - } - } + 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); + } - gtk_widget_hide (GTK_WIDGET (dialog)); + connect_dialog_set_connecting (dialog); - location = g_file_new_for_uri (uri); - g_free (uri); + g_simple_async_result_set_op_res_gboolean (dialog->details->fill_details_res, TRUE); + g_simple_async_result_complete (dialog->details->fill_details_res); - /* FIXME: sensitivity */ - 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); - } + g_object_unref (dialog->details->fill_details_res); + dialog->details->fill_details_res = NULL; - g_object_unref (bookmark); - g_object_unref (list); - g_object_unref (icon); - g_free (name); - } + g_object_unref (dialog->details->fill_operation); + dialog->details->fill_operation = NULL; +} - caja_connect_server_dialog_present_uri (dialog->details->application, - location, - GTK_WIDGET (dialog)); +static void +connect_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; + + connect_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 -response_callback (CajaConnectServerDialog *dialog, - int response_id, - gpointer data) +display_location_async_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) { - GError *error; + CajaConnectServerDialog *dialog; + GError *error; - switch (response_id) - { - case RESPONSE_CONNECT: - connect_to_server (dialog); - break; - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_DELETE_EVENT: - case GTK_RESPONSE_CANCEL: - gtk_widget_destroy (GTK_WIDGET (dialog)); - break; - case GTK_RESPONSE_HELP : - error = NULL; - gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog)), - "ghelp:user-guide#caja-server-connect", - gtk_get_current_event_time (), &error); - if (error) - { - eel_show_error_dialog (_("There was an error displaying help."), error->message, - GTK_WINDOW (dialog)); - g_error_free (error); - } - break; - default : - g_assert_not_reached (); - } + dialog = CAJA_CONNECT_SERVER_DIALOG (source); + error = NULL; + + caja_connect_server_dialog_display_location_finish (dialog, + res, &error); + + if (error != NULL) { + connect_dialog_set_info_bar_error (dialog, error); + g_error_free (error); + } else { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } } static void -caja_connect_server_dialog_class_init (CajaConnectServerDialogClass *class) +mount_enclosing_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) { - GObjectClass *gobject_class; - GtkObjectClass *object_class; + 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 { + connect_dialog_set_info_bar_error (dialog, error); + } + } + + if (error != NULL) { + g_error_free (error); + } +} - gobject_class = G_OBJECT_CLASS (class); - gobject_class->finalize = caja_connect_server_dialog_finalize; +static void +connect_dialog_present_uri_async (CajaConnectServerDialog *self, + CajaApplication *application, + GFile *location) +{ + GMountOperation *op; - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = caja_connect_server_dialog_destroy; + 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 -setup_for_type (CajaConnectServerDialog *dialog) +connect_dialog_connect_to_server (CajaConnectServerDialog *dialog) { struct MethodInfo *meth; - int index, i; - GtkWidget *label, *table; + GFile *location; + int index; GtkTreeIter iter; + char *user, *initial_path, *server, *folder, *domain, *port_str; + char *t, *join, *uri; + double port; /* Get our method info */ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->details->type_combo), &iter); @@ -428,483 +531,394 @@ setup_for_type (CajaConnectServerDialog *dialog) g_assert (index < G_N_ELEMENTS (methods) && index >= 0); meth = &(methods[index]); - if (gtk_widget_get_parent (dialog->details->uri_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->uri_entry); - } - if (gtk_widget_get_parent (dialog->details->server_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->server_entry); - } - if (gtk_widget_get_parent (dialog->details->share_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->share_entry); - } - if (gtk_widget_get_parent (dialog->details->port_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->port_entry); - } - if (gtk_widget_get_parent (dialog->details->folder_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->folder_entry); - } - if (gtk_widget_get_parent (dialog->details->user_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->user_entry); - } - if (gtk_widget_get_parent (dialog->details->domain_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->domain_entry); - } - if (gtk_widget_get_parent (dialog->details->bookmark_check) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->bookmark_check); - } - if (gtk_widget_get_parent (dialog->details->name_entry) != NULL) - { - gtk_container_remove (GTK_CONTAINER (dialog->details->table), - dialog->details->name_entry); - } - /* Destroy all labels */ - gtk_container_foreach (GTK_CONTAINER (dialog->details->table), - (GtkCallback) gtk_widget_destroy, NULL); + server = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->server_entry), 0, -1); + user = NULL; + initial_path = g_strdup (""); + domain = NULL; + folder = NULL; - i = 1; - table = dialog->details->table; + /* FTP special case */ + if (meth->flags & IS_ANONYMOUS) { + user = g_strdup ("anonymous"); - if (meth->scheme == NULL) - { - label = gtk_label_new_with_mnemonic (_("_Location (URI):")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->uri_entry); - gtk_widget_show (dialog->details->uri_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->uri_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; - - goto connection_name; - } + /* SMB special case */ + } else if (strcmp (meth->scheme, "smb") == 0) { + g_free (initial_path); - label = gtk_label_new_with_mnemonic (_("_Server:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->server_entry); - gtk_widget_show (dialog->details->server_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->server_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->share_entry), 0, -1); + initial_path = g_strconcat ("/", t, NULL); - label = gtk_label_new (_("Optional information:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 2, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - i++; - - if (meth->flags & SHOW_SHARE) - { - label = gtk_label_new_with_mnemonic (_("_Share:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->share_entry); - gtk_widget_show (dialog->details->share_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->share_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + g_free (t); } - if (meth->flags & SHOW_PORT) - { - label = gtk_label_new_with_mnemonic (_("_Port:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->port_entry); - gtk_widget_show (dialog->details->port_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->port_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + /* username */ + if (!user) { + t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->user_entry), 0, -1); + user = g_uri_escape_string (t, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE); + g_free (t); } - label = gtk_label_new_with_mnemonic (_("_Folder:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); + /* domain */ + domain = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->domain_entry), 0, -1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->folder_entry); - gtk_widget_show (dialog->details->folder_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->folder_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + if (strlen (domain) != 0) { + t = user; - if (meth->flags & SHOW_USER) - { - label = gtk_label_new_with_mnemonic (_("_User Name:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->user_entry); - gtk_widget_show (dialog->details->user_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->user_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + user = g_strconcat (domain , ";" , t, NULL); + g_free (t); } - if (meth->flags & SHOW_DOMAIN) - { - label = gtk_label_new_with_mnemonic (_("_Domain Name:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->domain_entry); - gtk_widget_show (dialog->details->domain_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->domain_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); - - i++; + /* folder */ + folder = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->folder_entry), 0, -1); + + if (folder[0] != 0 && + folder[0] != '/') { + join = "/"; + } else { + join = ""; } + 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); -connection_name: + /* port */ + port = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->details->port_spinbutton)); - gtk_widget_show (dialog->details->bookmark_check); - gtk_table_attach (GTK_TABLE (table), dialog->details->bookmark_check, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); - i++; + if (port != 0 && port != meth->default_port) { + port_str = g_strdup_printf ("%d", (int) port); + } else { + port_str = NULL; + } - label = gtk_label_new_with_mnemonic (_("Bookmark _name:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - i, i+1, - GTK_FILL, GTK_FILL, - 0, 0); + /* final uri */ + uri = g_strdup_printf ("%s://%s%s%s%s%s%s", + meth->scheme, + (user != NULL) ? user : "", + (user[0] != 0) ? "@" : "", + server, + (port_str != NULL) ? ":" : "", + (port_str != NULL) ? port_str : "", + (folder != NULL) ? folder : ""); + + g_free (initial_path); + g_free (server); + g_free (folder); + g_free (user); + g_free (domain); + g_free (port_str); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->name_entry); - gtk_widget_show (dialog->details->name_entry); - gtk_table_attach (GTK_TABLE (table), dialog->details->name_entry, - 1, 2, - i, i+1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 0, 0); + location = g_file_new_for_uri (uri); + g_free (uri); - i++; + connect_dialog_set_connecting (dialog); + connect_dialog_present_uri_async (dialog, + dialog->details->application, + location); + g_object_unref (location); } static void -display_server_location (CajaConnectServerDialog *dialog, GFile *location) +connect_to_server_or_finish_fill (CajaConnectServerDialog *dialog) { -#if 0 /*FIXME */ - struct MethodInfo *meth = NULL; - char *scheme; - int i, index = 0; - char *folder; - const char *t; + if (dialog->details->fill_details_res != NULL) { + connect_dialog_finish_fill (dialog); + } else { + connect_dialog_connect_to_server (dialog); + } +} - /* Find an appropriate method */ - scheme = g_file_get_uri_scheme (location); - g_return_if_fail (scheme != NULL); +static gboolean +connect_dialog_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); - for (i = 0; i < G_N_ELEMENTS (methods); i++) - { - - /* The default is 'Custom URI' */ - if (methods[i].scheme == NULL) - { - meth = &(methods[i]); - index = i; + 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; } - else if (strcmp (methods[i].scheme, scheme) == 0) - { - /* FTP Special case: If no user keep searching for public ftp */ - if (strcmp (scheme, "ftp") == 0) - { - t = mate_vfs_uri_get_user_name (uri); - if ((!t || !t[0] || strcmp (t, "anonymous") == 0) && - (!(methods[i].flags & IS_ANONYMOUS))) - { - continue; - } - } - - meth = &(methods[i]); - index = i; - break; - } + return TRUE; } - g_free (scheme); - g_assert (meth); - - gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->details->type_combo), index); - setup_for_type (dialog); + return FALSE; +} - /* Custom URI */ - if (meth->scheme == NULL) - { - gchar *uri; +static void +connect_dialog_destroy (CajaConnectServerDialog *dialog) +{ + if (connect_dialog_abort_mount_operation (dialog)) { + dialog->details->should_destroy = TRUE; + } else { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } +} - /* FIXME: with mate-vfs, we had MATE_VFS_URI_HIDE_PASSWORD | - * MATE_VFS_URI_HIDE_FRAGMENT_IDENTIFIER */ - uri = g_file_get_uri (location) - gtk_entry_set_text (GTK_ENTRY (dialog->details->uri_entry), uri); - g_free (uri); +static void +connect_dialog_response_cb (CajaConnectServerDialog *dialog, + int response_id, + gpointer data) +{ + GError *error; - } - else + switch (response_id) { - - folder = g_file_get_path (location); - if (!folder) - { - folder = ""; - } - else if (folder[0] == '/') + case RESPONSE_CONNECT: + connect_to_server_or_finish_fill (dialog); + break; + case GTK_RESPONSE_NONE: + case GTK_RESPONSE_DELETE_EVENT: + case GTK_RESPONSE_CANCEL: + connect_dialog_destroy (dialog); + break; + case GTK_RESPONSE_HELP : + error = NULL; + gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog)), + "ghelp:user-guide#caja-server-connect", + gtk_get_current_event_time (), &error); + if (error) { - folder++; + eel_show_error_dialog (_("There was an error displaying help."), error->message, + GTK_WINDOW (dialog)); + g_error_free (error); } + break; + default : + g_assert_not_reached (); + } +} - /* Server */ - t = mate_vfs_uri_get_host_name (uri); - gtk_entry_set_text (GTK_ENTRY (dialog->details->server_entry), - t ? t : ""); +static void +connect_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. */ + connect_dialog_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; +} - /* Share */ - if (meth->flags & SHOW_SHARE) - { - t = strchr (folder, '/'); - if (t) - { - char *share = g_strndup (folder, t - folder); - gtk_entry_set_text (GTK_ENTRY (dialog->details->share_entry), share); - g_free (share); - folder = t + 1; - } +static void +connect_dialog_setup_for_type (CajaConnectServerDialog *dialog) +{ + struct MethodInfo *meth; + int index; + GtkTreeIter iter; - } + connect_dialog_cleanup (dialog); - /* Port */ - if (meth->flags & SHOW_PORT) - { - guint port = mate_vfs_uri_get_host_port (uri); - if (port != 0) - { - char sport[32]; - g_snprintf (sport, sizeof (sport), "%d", port); - gtk_entry_set_text (GTK_ENTRY (dialog->details->port_entry), sport); - } - } + /* get our method info */ + if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dialog->details->type_combo), + &iter)) { + /* there are no entries in the combo, something is wrong + * with our GVfs installation. + */ + connect_dialog_gvfs_error (dialog); - /* Folder */ - gtk_entry_set_text (GTK_ENTRY (dialog->details->folder_entry), folder); - g_free (folder); + return; + } - /* User */ - if (meth->flags & SHOW_USER) - { - const char *user = mate_vfs_uri_get_user_name (uri); - if (user) - { - t = strchr (user, ';'); - if (t) - { - user = t + 1; - } - gtk_entry_set_text (GTK_ENTRY (dialog->details->user_entry), user); - } - } + gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dialog->details->type_combo)), + &iter, 0, &index, -1); + g_assert (index < G_N_ELEMENTS (methods) && index >= 0); + meth = &(methods[index]); - /* Domain */ - if (meth->flags & SHOW_DOMAIN) - { - const char *user = mate_vfs_uri_get_user_name (uri); - if (user) - { - t = strchr (user, ';'); - if (t) - { - char *domain = g_strndup (user, t - user); - gtk_entry_set_text (GTK_ENTRY (dialog->details->domain_entry), domain); - g_free (domain); - } - } - } - } -#endif + g_object_set (dialog->details->share_entry, + "visible", + (meth->flags & SHOW_SHARE) != 0, + NULL); + + g_object_set (dialog->details->port_spinbutton, + "sensitive", + (meth->flags & SHOW_PORT) != 0, + "value", (gdouble) meth->default_port, + NULL); + + g_object_set (dialog->details->user_details, + "visible", + (meth->flags & SHOW_USER) != 0 || + (meth->flags & SHOW_DOMAIN) != 0, + NULL); + + g_object_set (dialog->details->user_entry, + "visible", + (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, + NULL); } static void -combo_changed_callback (GtkComboBox *combo_box, - CajaConnectServerDialog *dialog) +sensitive_entry_changed_callback (GtkEditable *editable, + GtkWidget *widget) { - setup_for_type (dialog); -} + guint length; -static void -port_insert_text (GtkEditable *editable, - const gchar *new_text, - gint new_text_length, - gint *position) -{ - int pos; + length = gtk_entry_get_text_length (GTK_ENTRY (editable)); - if (new_text_length < 0) - { - new_text_length = strlen (new_text); - } - - /* Only allow digits to be inserted as port number */ - for (pos = 0; pos < new_text_length; pos++) - { - if (!g_ascii_isdigit (new_text[pos])) - { - GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editable)); - if (toplevel != NULL) - { - gdk_window_beep (gtk_widget_get_window (toplevel)); - } - g_signal_stop_emission_by_name (editable, "insert_text"); - return; - } - } + gtk_widget_set_sensitive (widget, length > 0); } static void -bookmark_checkmark_toggled (GtkToggleButton *toggle, CajaConnectServerDialog *dialog) +bind_visibility (CajaConnectServerDialog *dialog, + GtkWidget *source, + GtkWidget *dest) { - gtk_widget_set_sensitive (GTK_WIDGET(dialog->details->name_entry), - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (toggle))); + g_object_bind_property (source, + "visible", + dest, + "visible", + G_BINDING_DEFAULT); } static void caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) { GtkWidget *label; - GtkWidget *table; - GtkWidget *combo; - GtkWidget *hbox; - GtkWidget *vbox; + GtkWidget *alignment; + GtkWidget *content_area; + GtkWidget *combo ,* table; + GtkWidget *hbox, *connect_button, *checkbox; GtkListStore *store; GtkCellRenderer *renderer; + gchar *str; int i; - dialog->details = g_new0 (CajaConnectServerDialogDetails, 1); + dialog->details = G_TYPE_INSTANCE_GET_PRIVATE (dialog, CAJA_TYPE_CONNECT_SERVER_DIALOG, + CajaConnectServerDialogDetails); + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + + /* set dialog properties */ gtk_window_set_title (GTK_WINDOW (dialog), _("Connect to Server")); - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 6); + gtk_box_set_spacing (GTK_BOX (content_area), 2); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - vbox = gtk_vbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - vbox, FALSE, TRUE, 0); - gtk_widget_show (vbox); + /* 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")); + gtk_label_set_markup (GTK_LABEL (label), str); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (content_area), label, FALSE, FALSE, 6); + gtk_widget_show (label); + + /* server settings alignment */ + alignment = gtk_alignment_new (0, 0, 0, 0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), + 0, 0, 12, 0); + gtk_box_pack_start (GTK_BOX (content_area), alignment, TRUE, TRUE, 0); + gtk_widget_show (alignment); + + table = gtk_table_new (4, 2, FALSE); + gtk_container_add (GTK_CONTAINER (alignment), table); + gtk_widget_show (table); + + dialog->details->primary_table = table; + + /* first row: server entry + port spinbutton */ + label = gtk_label_new_with_mnemonic (_("_Server:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + gtk_widget_show (label); hbox = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (vbox), - hbox, FALSE, TRUE, 0); gtk_widget_show (hbox); + gtk_table_attach (GTK_TABLE (table), hbox, + 1, 2, + 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); - label = gtk_label_new_with_mnemonic (_("Service _type:")); + dialog->details->server_entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->server_entry), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), dialog->details->server_entry, FALSE, FALSE, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->server_entry); + gtk_widget_show (dialog->details->server_entry); + + /* port */ + label = gtk_label_new_with_mnemonic (_("_Port:")); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + dialog->details->port_spinbutton = + gtk_spin_button_new_with_range (0.0, 65535.0, 1.0); + g_object_set (dialog->details->port_spinbutton, + "digits", 0, + "numeric", TRUE, + "update-policy", GTK_UPDATE_IF_VALID, + NULL); + gtk_box_pack_start (GTK_BOX (hbox), dialog->details->port_spinbutton, + FALSE, FALSE, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->port_spinbutton); + gtk_widget_show (dialog->details->port_spinbutton); + + /* second row: type combobox */ + label = gtk_label_new (_("Type:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), - label, FALSE, FALSE, 0); dialog->details->type_combo = combo = gtk_combo_box_new (); /* each row contains: method index, textual description */ store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store)); - g_object_unref (G_OBJECT (store)); + g_object_unref (store); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); @@ -916,7 +930,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) @@ -960,72 +974,129 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) gtk_widget_show (combo); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); - gtk_box_pack_start (GTK_BOX (hbox), - combo, TRUE, TRUE, 0); - g_signal_connect (combo, "changed", - G_CALLBACK (combo_changed_callback), - dialog); + gtk_table_attach (GTK_TABLE (table), combo, + 1, 2, + 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND, 6, 3); + g_signal_connect_swapped (combo, "changed", + G_CALLBACK (connect_dialog_setup_for_type), + dialog); + + /* third row: share entry */ + label = gtk_label_new (_("Share:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + dialog->details->share_entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->share_entry), TRUE); + gtk_table_attach (GTK_TABLE (table), dialog->details->share_entry, + 1, 2, + 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); - hbox = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (vbox), - hbox, FALSE, TRUE, 0); - gtk_widget_show (hbox); + bind_visibility (dialog, dialog->details->share_entry, label); - label = gtk_label_new_with_mnemonic (" "); + /* fourth row: folder entry */ + label = gtk_label_new (_("Folder:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), - label, FALSE, FALSE, 0); + dialog->details->folder_entry = gtk_entry_new (); + gtk_entry_set_text (GTK_ENTRY (dialog->details->folder_entry), "/"); + gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->folder_entry), TRUE); + gtk_table_attach (GTK_TABLE (table), dialog->details->folder_entry, + 1, 2, + 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + gtk_widget_show (dialog->details->folder_entry); + + /* user details label */ + label = gtk_label_new (NULL); + str = g_strdup_printf ("<b>%s</b>", _("User Details")); + gtk_label_set_markup (GTK_LABEL (label), str); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (content_area), label, FALSE, FALSE, 6); + /* user details alignment */ + alignment = gtk_alignment_new (0, 0, 0, 0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), + 0, 0, 12, 0); + gtk_box_pack_start (GTK_BOX (content_area), alignment, TRUE, TRUE, 0); - dialog->details->table = table = gtk_table_new (5, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); + bind_visibility (dialog, alignment, label); + dialog->details->user_details = alignment; + + table = gtk_table_new (4, 2, FALSE); + gtk_container_add (GTK_CONTAINER (alignment), table); gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (hbox), - table, TRUE, TRUE, 0); - dialog->details->uri_entry = caja_location_entry_new (); - /* hide the clean icon, as it doesn't make sense here */ - g_object_set (dialog->details->uri_entry, "secondary-icon-name", NULL, NULL); - dialog->details->server_entry = gtk_entry_new (); - dialog->details->share_entry = gtk_entry_new (); - dialog->details->port_entry = gtk_entry_new (); - g_signal_connect (dialog->details->port_entry, "insert_text", G_CALLBACK (port_insert_text), - NULL); - dialog->details->folder_entry = gtk_entry_new (); + /* first row: domain entry */ + label = gtk_label_new (_("Domain Name:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); + dialog->details->domain_entry = gtk_entry_new (); - dialog->details->user_entry = gtk_entry_new (); - dialog->details->bookmark_check = gtk_check_button_new_with_mnemonic (_("Add _bookmark")); - dialog->details->name_entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->domain_entry), TRUE); + gtk_table_attach (GTK_TABLE (table), dialog->details->domain_entry, + 1, 2, + 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); - g_signal_connect (dialog->details->bookmark_check, "toggled", - G_CALLBACK (bookmark_checkmark_toggled), dialog); + bind_visibility (dialog, dialog->details->domain_entry, label); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->details->bookmark_check), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET(dialog->details->name_entry), FALSE); + /* second row: username entry */ + label = gtk_label_new (_("User Name:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, + 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->uri_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->server_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->share_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->port_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->folder_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->domain_entry), TRUE); + dialog->details->user_entry = gtk_entry_new (); gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->user_entry), TRUE); - gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->name_entry), TRUE); + gtk_table_attach (GTK_TABLE (table), dialog->details->user_entry, + 1, 2, + 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 6, 3); - /* We need an extra ref so we can remove them from the table */ - g_object_ref (dialog->details->uri_entry); - g_object_ref (dialog->details->server_entry); - g_object_ref (dialog->details->share_entry); - g_object_ref (dialog->details->port_entry); - g_object_ref (dialog->details->folder_entry); - g_object_ref (dialog->details->domain_entry); - g_object_ref (dialog->details->user_entry); - g_object_ref (dialog->details->bookmark_check); - g_object_ref (dialog->details->name_entry); + bind_visibility (dialog, dialog->details->user_entry, label); - setup_for_type (dialog); + /* third row: password entry */ + label = gtk_label_new (_("Password:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + 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, @@ -1033,21 +1104,56 @@ caja_connect_server_dialog_init (CajaConnectServerDialog *dialog) gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_dialog_add_button (GTK_DIALOG (dialog), - _("C_onnect"), - RESPONSE_CONNECT); + connect_button = gtk_dialog_add_button (GTK_DIALOG (dialog), + _("C_onnect"), + 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 (sensitive_entry_changed_callback), + connect_button); + sensitive_entry_changed_callback (GTK_EDITABLE (dialog->details->server_entry), + connect_button); g_signal_connect (dialog, "response", - G_CALLBACK (response_callback), + G_CALLBACK (connect_dialog_response_cb), dialog); + connect_dialog_setup_for_type (dialog); +} +static void +caja_connect_server_dialog_finalize (GObject *object) +{ + CajaConnectServerDialog *dialog; + + dialog = CAJA_CONNECT_SERVER_DIALOG (object); + + connect_dialog_abort_mount_operation (dialog); + + if (dialog->details->iconized_entries != NULL) { + 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)); } GtkWidget * -caja_connect_server_dialog_new (CajaWindow *window, GFile *location) +caja_connect_server_dialog_new (CajaWindow *window) { CajaConnectServerDialog *conndlg; GtkWidget *dialog; @@ -1062,14 +1168,84 @@ caja_connect_server_dialog_new (CajaWindow *window, GFile *location) conndlg->details->application = window->application; } - if (location) - { - /* If it's a remote URI, then load as the default */ - if (!g_file_is_native (location)) - { - display_server_location (conndlg, location); - } - } - 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); + connect_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; + } +} |