nautilus-connect-server-dialog.c 38.4 KB
Newer Older
Alexander Larsson's avatar
Alexander Larsson committed
1 2 3 4 5
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
 * Nautilus
 *
 * Copyright (C) 2003 Red Hat, Inc.
6
 * Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
Alexander Larsson's avatar
Alexander Larsson committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * Nautilus is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * Nautilus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; see the file COPYING.  If not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <config.h>
25

Alexander Larsson's avatar
Alexander Larsson committed
26 27 28 29
#include "nautilus-connect-server-dialog.h"

#include <string.h>
#include <eel/eel-stock-dialogs.h>
30
#include <glib/gi18n.h>
31
#include <gio/gio.h>
32
#include <gtk/gtk.h>
33 34 35 36 37

#include "nautilus-bookmark-list.h"
#include "nautilus-connect-server-operation.h"
#include "nautilus-window.h"

38
#include <libnautilus-private/nautilus-global-preferences.h>
39
#include <libnautilus-private/nautilus-icon-names.h>
40 41 42

/* TODO:
 * - name entry + pre-fill
43
 * - NetworkManager integration
44 45
 */

Alexander Larsson's avatar
Alexander Larsson committed
46
struct _NautilusConnectServerDialogDetails {
47
	GtkWidget *primary_grid;
48 49 50
	GtkWidget *user_details;
	GtkWidget *port_spinbutton;

51 52
	GtkWidget *info_bar;
	GtkWidget *info_bar_content;
53 54 55 56 57
	
	GtkWidget *type_combo;
	GtkWidget *server_entry;
	GtkWidget *share_entry;
	GtkWidget *folder_entry;
58
	GtkWidget *domain_entry;
59
	GtkWidget *user_entry;
60 61 62 63
	GtkWidget *password_entry;
	GtkWidget *remember_checkbox;
	GtkWidget *connect_button;

64 65 66
	GtkSizeGroup *labels_size_group;
	GtkSizeGroup *contents_size_group;

67
	GList *iconized_entries;
68

69 70 71 72 73 74 75
	GSimpleAsyncResult *fill_details_res;
	GAskPasswordFlags fill_details_flags;
	GMountOperation *fill_operation;

	gboolean last_password_set;
	gulong password_sensitive_id;
	gboolean should_destroy;
76 77

	GCancellable *mount_cancellable;
Alexander Larsson's avatar
Alexander Larsson committed
78 79
};

80 81
G_DEFINE_TYPE (NautilusConnectServerDialog, nautilus_connect_server_dialog,
	       GTK_TYPE_DIALOG)
Alexander Larsson's avatar
Alexander Larsson committed
82

83 84 85 86 87
static void sensitive_entry_changed_callback (GtkEditable *editable,
					      GtkWidget *widget);
static void iconized_entry_changed_cb (GtkEditable *entry,
				       NautilusConnectServerDialog *dialog);

Alexander Larsson's avatar
Alexander Larsson committed
88
enum {
89
	RESPONSE_CONNECT
Alexander Larsson's avatar
Alexander Larsson committed
90 91
};	

92
struct MethodInfo {
93
	const char *scheme;
94
	guint flags;
95
	guint default_port;
96 97 98
};

/* A collection of flags for MethodInfo.flags */
99
enum {
100
	DEFAULT_METHOD = (1 << 0),
101
	
102
	/* Widgets to display in connect_dialog_setup_for_type */
103 104 105 106
	SHOW_SHARE     = (1 << 1),
	SHOW_PORT      = (1 << 2),
	SHOW_USER      = (1 << 3),
	SHOW_DOMAIN    = (1 << 4),
107
	
108
	IS_ANONYMOUS   = (1 << 5)
109 110 111 112
};

/* Remember to fill in descriptions below */
static struct MethodInfo methods[] = {
113
	{ "afp", SHOW_SHARE | SHOW_USER, 548 },
114
	/* FIXME: we need to alias ssh to sftp */
115 116 117 118 119
	{ "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 },
120
	/* FIXME: hrm, shouldn't it work? */
121
	{ "davs", SHOW_PORT | SHOW_USER, 443 },
122 123
};

124 125 126 127
/* To get around non constant gettext strings */
static const char*
get_method_description (struct MethodInfo *meth)
{
128
	if (strcmp (meth->scheme, "sftp") == 0) {
129
		return _("SSH");
130
	} else if (strcmp (meth->scheme, "ftp") == 0) {
131 132 133 134 135
		if (meth->flags & IS_ANONYMOUS) {
			return _("Public FTP");
		} else {
			return _("FTP (with login)");
		}
136
	} else if (strcmp (meth->scheme, "smb") == 0) {
137
		return _("Windows share");
138
	} else if (strcmp (meth->scheme, "dav") == 0) {
139
		return _("WebDAV (HTTP)");
140
	} else if (strcmp (meth->scheme, "davs") == 0) {
141
		return _("Secure WebDAV (HTTPS)");
142 143
	} else if (strcmp (meth->scheme, "afp") == 0) {
		return _("Apple Filing Protocol (AFP)");
144
	} else {
145
		/* No descriptive text */
146
		return meth->scheme;
147 148 149
	}
}

150
static void
151 152
connect_dialog_restore_info_bar (NautilusConnectServerDialog *dialog,
				 GtkMessageType message_type)
153 154 155 156 157 158 159 160 161 162 163
{
	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
164
connect_dialog_set_connecting (NautilusConnectServerDialog *dialog)
165 166 167 168 169 170
{
	GtkWidget *hbox;
	GtkWidget *widget;
	GtkWidget *content_area;
	gint width, height;

171
	connect_dialog_restore_info_bar (dialog, GTK_MESSAGE_INFO);
172 173 174 175
	gtk_widget_show (dialog->details->info_bar);	

	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar));

176
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
	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);
}

196 197 198 199 200 201 202 203 204
static void
connect_dialog_gvfs_error (NautilusConnectServerDialog *dialog)
{
	GtkWidget *hbox, *image, *content_area, *label;

	connect_dialog_restore_info_bar (dialog, GTK_MESSAGE_ERROR);

	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->details->info_bar));

205
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
206 207 208 209 210 211 212 213
	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"
214
				 "Please check your gvfs installation."));
215 216 217 218
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6);
	gtk_widget_show (label);

	gtk_widget_set_sensitive (dialog->details->connect_button, FALSE);
219
	gtk_widget_set_sensitive (dialog->details->primary_grid, FALSE);
220 221 222

	gtk_widget_show (dialog->details->info_bar);
}
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

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)
{
257 258 259
	if (!g_list_find (dialog->details->iconized_entries, entry)) {
		dialog->details->iconized_entries =
			g_list_prepend (dialog->details->iconized_entries, entry);
260

261 262 263
		gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
					       GTK_ENTRY_ICON_SECONDARY,
					       GTK_STOCK_DIALOG_WARNING);
264

265
		gtk_widget_grab_focus (entry);
266

267 268 269
		g_signal_connect (entry, "changed",
				  G_CALLBACK (iconized_entry_changed_cb), dialog);
	}
270 271 272
}

static void
273 274
connect_dialog_set_info_bar_error (NautilusConnectServerDialog *dialog,
				   GError *error)
275 276 277 278 279
{
	GtkWidget *content_area, *label, *entry, *hbox, *icon;
	gchar *str;
	const gchar *folder, *server;

280
	connect_dialog_restore_info_bar (dialog, GTK_MESSAGE_WARNING);
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

	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);

317
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
	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
341
connect_dialog_finish_fill (NautilusConnectServerDialog *dialog)
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
{
	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);
	}

366
	connect_dialog_set_connecting (dialog);
367 368 369 370 371 372 373 374 375 376 377 378

	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
379 380 381 382
connect_dialog_request_additional_details (NautilusConnectServerDialog *self,
					   GAskPasswordFlags flags,
					   const gchar *default_user,
					   const gchar *default_domain)
383
{
384
	GtkWidget *content_area, *label, *hbox, *icon;
385 386 387

	self->details->fill_details_flags = flags;

388
	connect_dialog_restore_info_bar (self, GTK_MESSAGE_WARNING);
389 390 391

	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (self->details->info_bar));

392
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
	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) {
459
		connect_dialog_set_info_bar_error (dialog, error);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
		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 */
483
		nautilus_connect_server_dialog_display_location_async (dialog, location,
484 485 486 487 488
								       display_location_async_cb, NULL);
	} else {
		if (dialog->details->should_destroy) {
			gtk_widget_destroy (GTK_WIDGET (dialog));
		} else {
489
			connect_dialog_set_info_bar_error (dialog, error);
490 491 492
		}
	}

493 494
	g_clear_object (&dialog->details->mount_cancellable);

495 496 497 498 499 500
	if (error != NULL) {
		g_error_free (error);
	}
}

static void
501 502
connect_dialog_present_uri_async (NautilusConnectServerDialog *self,
				  GFile *location)
503 504 505
{
	GMountOperation *op;

506 507
	self->details->mount_cancellable = g_cancellable_new ();

508 509
	op = nautilus_connect_server_operation_new (self);
	g_file_mount_enclosing_volume (location,
510
				       0, op, self->details->mount_cancellable,
511 512 513 514
				       mount_enclosing_ready_cb, self);
	g_object_unref (op);
}

Alexander Larsson's avatar
Alexander Larsson committed
515
static void
516
connect_dialog_connect_to_server (NautilusConnectServerDialog *dialog)
Alexander Larsson's avatar
Alexander Larsson committed
517
{
518
	struct MethodInfo *meth;
519
	GFile *location;
520
	int index;
521
	GtkTreeIter iter;
522 523
	char *user, *initial_path, *server, *folder, *domain, *port_str;
	char *t, *join, *uri;
524
	char *temp, *stripped_server;
525 526
	double port;

527
	/* Get our method info */
528 529 530
	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);
531 532
	g_assert (index < G_N_ELEMENTS (methods) && index >= 0);
	meth = &(methods[index]);
533

534
	server = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->server_entry), 0, -1);
535

536 537 538 539 540 541 542 543
	temp = g_strconcat (meth->scheme, "://", NULL);
	if (g_str_has_prefix (server, temp)) {
		stripped_server = g_strdup (server + strlen (temp));
		g_free (server);
		server = stripped_server;
	}
	g_free (temp);

544
	user = NULL;
545
	initial_path = g_strdup ("");
546 547 548 549
	domain = NULL;
	folder = NULL;

	if (meth->flags & IS_ANONYMOUS) {
550
		/* FTP special case */
551
		user = g_strdup ("anonymous");
552 553 554
	} else if ((strcmp (meth->scheme, "smb") == 0) ||
		   (strcmp (meth->scheme, "afp") == 0)){
		/* SMB/AFP special case */
555 556
		g_free (initial_path);

557 558
		t = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->share_entry), 0, -1);
		initial_path = g_strconcat ("/", t, NULL);
559

560 561
		g_free (t);
	}
562

563 564 565 566 567 568
	/* 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);
	}
569

570 571
	/* domain */
	domain = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->domain_entry), 0, -1);
572
			
573 574
	if (strlen (domain) != 0) {
		t = user;
575

576 577 578
		user = g_strconcat (domain , ";" , t, NULL);
		g_free (t);
	}
579

580 581
	/* folder */
	folder = gtk_editable_get_chars (GTK_EDITABLE (dialog->details->folder_entry), 0, -1);
Alexander Larsson's avatar
Alexander Larsson committed
582

583 584 585 586 587 588
	if (folder[0] != 0 &&
	    folder[0] != '/') {
		join = "/";
	} else {
		join = "";
	}
589

590 591 592
	t = folder;
	folder = g_strconcat (initial_path, join, t, NULL);
	g_free (t);
593

594 595 596
	t = folder;
	folder = g_uri_escape_string (t, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);
	g_free (t);
597

598
	/* port */
599 600
	port = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->details->port_spinbutton));

601 602 603 604
	if (port != 0 && port != meth->default_port) {
		port_str = g_strdup_printf ("%d", (int) port);
	} else {
		port_str = NULL;
605
	}
606

607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
	/* 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);

624 625 626
	location = g_file_new_for_uri (uri);
	g_free (uri);

627 628 629
	connect_dialog_set_connecting (dialog);
	connect_dialog_present_uri_async (dialog,
					  location);
630 631 632 633 634 635 636 637

	g_object_unref (location);
}

static void
connect_to_server_or_finish_fill (NautilusConnectServerDialog *dialog)
{
	if (dialog->details->fill_details_res != NULL) {
638
		connect_dialog_finish_fill (dialog);
639
	} else {
640
		connect_dialog_connect_to_server (dialog);
641 642 643 644
	}
}

static gboolean
645
connect_dialog_abort_mount_operation (NautilusConnectServerDialog *dialog)
646
{
647 648 649 650 651 652
	gboolean retval = FALSE;

	if (dialog->details->mount_cancellable != NULL) {
		g_cancellable_cancel (dialog->details->mount_cancellable);
		retval = TRUE;
	} else if (dialog->details->fill_details_res != NULL) {
653 654 655 656 657 658 659 660 661
		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;
Alexander Larsson's avatar
Alexander Larsson committed
662
		}
663

664
		retval = TRUE;
Alexander Larsson's avatar
Alexander Larsson committed
665
	}
666

667
	return retval;
668 669 670
}

static void
671
connect_dialog_destroy (NautilusConnectServerDialog *dialog)
672
{
673
	if (connect_dialog_abort_mount_operation (dialog)) {
674
		dialog->details->should_destroy = TRUE;
675
		gtk_widget_hide (GTK_WIDGET (dialog));
676 677 678
	} else {
		gtk_widget_destroy (GTK_WIDGET (dialog));
	}
Alexander Larsson's avatar
Alexander Larsson committed
679 680 681
}

static void
682 683 684
connect_dialog_response_cb (NautilusConnectServerDialog *dialog,
			    int response_id,
			    gpointer data)
Alexander Larsson's avatar
Alexander Larsson committed
685
{
686 687
	GError *error;

Alexander Larsson's avatar
Alexander Larsson committed
688 689
	switch (response_id) {
	case RESPONSE_CONNECT:
690
		connect_to_server_or_finish_fill (dialog);
Alexander Larsson's avatar
Alexander Larsson committed
691 692 693
		break;
	case GTK_RESPONSE_NONE:
	case GTK_RESPONSE_DELETE_EVENT:
694
	case GTK_RESPONSE_CANCEL:
695
		connect_dialog_destroy (dialog);
Alexander Larsson's avatar
Alexander Larsson committed
696
		break;
697 698
	case GTK_RESPONSE_HELP :
		error = NULL;
699
		gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog)),
700
			      "help:gnome-help/nautilus-connect",
701
			      gtk_get_current_event_time (), &error);
702 703 704 705 706 707
		if (error) {
			eel_show_error_dialog (_("There was an error displaying help."), error->message,
					       GTK_WINDOW (dialog));
			g_error_free (error);
		}
		break;
Alexander Larsson's avatar
Alexander Larsson committed
708 709 710 711 712
	default :
		g_assert_not_reached ();
	}
}

713
static void
714
connect_dialog_cleanup (NautilusConnectServerDialog *dialog)
715 716 717 718 719 720 721 722 723
{
	/* 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. */
724
	connect_dialog_abort_mount_operation (dialog);
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745

	/* 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;
}


Alexander Larsson's avatar
Alexander Larsson committed
746
static void
747
connect_dialog_setup_for_type (NautilusConnectServerDialog *dialog)
Alexander Larsson's avatar
Alexander Larsson committed
748
{
749
	struct MethodInfo *meth;
750
	int index;;
751
	GtkTreeIter iter;
752

753
	connect_dialog_cleanup (dialog);
754 755

	/* get our method info */
756 757 758 759 760 761 762 763 764 765
	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);

		return;
	}

766 767
	gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dialog->details->type_combo)),
			    &iter, 0, &index, -1);
768 769
	g_assert (index < G_N_ELEMENTS (methods) && index >= 0);
	meth = &(methods[index]);
Alexander Larsson's avatar
Alexander Larsson committed
770

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
	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);

793 794 795 796 797
	g_object_set (dialog->details->password_entry,
		      "visible",
		      (meth->flags & SHOW_USER) != 0,
		      NULL);

798 799 800 801
	g_object_set (dialog->details->domain_entry,
		      "visible",
		      (meth->flags & SHOW_DOMAIN) != 0,
		      NULL);
802 803
}

804
static void
805 806
sensitive_entry_changed_callback (GtkEditable *editable,
				  GtkWidget *widget)
807
{
808
	guint length;
809

810
	length = gtk_entry_get_text_length (GTK_ENTRY (editable));
Alexander Larsson's avatar
Alexander Larsson committed
811

812
	gtk_widget_set_sensitive (widget, length > 0);
813 814
}

815
static void
816 817 818
bind_visibility (NautilusConnectServerDialog *dialog,
		 GtkWidget *source,
		 GtkWidget *dest)
819
{
820 821 822 823 824
	g_object_bind_property (source,
				"visible",
				dest,
				"visible",
				G_BINDING_DEFAULT);
825 826
}

827 828 829 830
static void
nautilus_connect_server_dialog_init (NautilusConnectServerDialog *dialog)
{
	GtkWidget *label;
831 832
	GtkWidget *alignment;
	GtkWidget *content_area;
833
	GtkWidget *combo, *grid;
834
	GtkWidget *hbox, *connect_button, *checkbox;
835 836
	GtkListStore *store;
	GtkCellRenderer *renderer;
837
	gchar *str;
838
	int i;
839
	
840 841
	dialog->details = G_TYPE_INSTANCE_GET_PRIVATE (dialog, NAUTILUS_TYPE_CONNECT_SERVER_DIALOG,
						       NautilusConnectServerDialogDetails);
842

843 844 845
	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

	/* set dialog properties */
846
	gtk_window_set_title (GTK_WINDOW (dialog), _("Connect to Server"));
847 848
	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
	gtk_box_set_spacing (GTK_BOX (content_area), 2);
Dennis Cranston's avatar
Dennis Cranston committed
849
	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
850

851 852 853 854
	/* create the size group */
	dialog->details->labels_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
	dialog->details->contents_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

855 856 857 858 859 860 861
	/* 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);

862 863 864 865 866 867
	/* 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);
868
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
869 870 871 872 873 874 875 876 877
	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);

878 879 880 881 882 883
	grid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
	gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
	gtk_container_add (GTK_CONTAINER (alignment), grid);
	gtk_widget_show (grid);
884

885
	dialog->details->primary_grid = grid;
886

887 888 889
	/* first row: server entry + port spinbutton */
	label = gtk_label_new_with_mnemonic (_("_Server:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
890
	gtk_container_add (GTK_CONTAINER (grid), label);
891
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
892 893
	gtk_widget_show (label);

894
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
895
	gtk_widget_show (hbox);
896 897 898
	gtk_grid_attach_next_to (GTK_GRID (grid), hbox, label,
				 GTK_POS_RIGHT,
				 1, 1);
899
	gtk_size_group_add_widget (dialog->details->contents_size_group, hbox);
900 901 902 903 904 905 906 907 908 909 910

	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);
911
	gtk_widget_show (label);
912 913 914 915 916 917 918 919 920 921 922 923 924 925

	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 */
926
	label = gtk_label_new_with_mnemonic (_("_Type:"));
927
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
928
	gtk_container_add (GTK_CONTAINER (grid), label);
929
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
930 931
	gtk_widget_show (label);

932
	dialog->details->type_combo = combo = gtk_combo_box_new ();
933
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->type_combo);
934
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->type_combo);
935 936 937 938

	/* 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));
939
	g_object_unref (store);
940 941 942 943 944

	renderer = gtk_cell_renderer_text_new ();
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 1);

945
	for (i = 0; i < G_N_ELEMENTS (methods); i++) {
946
		GtkTreeIter iter;
947 948 949
		const gchar * const *supported;
		int j;

950
		/* skip methods that don't have corresponding gvfs uri schemes */
951
		supported = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
952

953 954 955 956 957 958 959 960 961 962 963 964 965 966
		if (methods[i].scheme != NULL) {
			gboolean found;

			found = FALSE;
			for (j = 0; supported[j] != NULL; j++) {
				if (strcmp (methods[i].scheme, supported[j]) == 0) {
					found = TRUE;
					break;
				}
			}

			if (!found) {
				continue;
			}
967 968 969 970 971 972 973 974 975
		}

		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
				    0, i,
				    1, get_method_description (&(methods[i])),
				    -1);


976
		if (methods[i].flags & DEFAULT_METHOD) {
977
			gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
978 979 980
		}
	}

981 982 983 984 985
	if (gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) < 0) {
		/* default method not available, use any other */
		gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
	}

986 987
	gtk_widget_show (combo);
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
988 989
	gtk_grid_attach_next_to (GTK_GRID (grid), combo, label,
				 GTK_POS_RIGHT, 1, 1);
990
	g_signal_connect_swapped (combo, "changed",
991
				  G_CALLBACK (connect_dialog_setup_for_type),
992
				  dialog);
993

994
	/* third row: share entry */
995
	label = gtk_label_new_with_mnemonic (_("Sh_are:"));
996
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
997
	gtk_container_add (GTK_CONTAINER (grid), label);
998
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
999

1000 1001
	dialog->details->share_entry = gtk_entry_new ();
	gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->share_entry), TRUE);
1002 1003
	gtk_grid_attach_next_to (GTK_GRID (grid), dialog->details->share_entry, label,
				 GTK_POS_RIGHT, 1, 1);
1004
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->share_entry);
1005
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->share_entry);
1006 1007 1008 1009

	bind_visibility (dialog, dialog->details->share_entry, label);

	/* fourth row: folder entry */
1010
	label = gtk_label_new_with_mnemonic (_("_Folder:"));
1011
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1012
	gtk_container_add (GTK_CONTAINER (grid), label);
1013
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
1014
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->share_entry);
1015 1016 1017
	gtk_widget_show (label);

	dialog->details->folder_entry = gtk_entry_new ();
1018 1019
	gtk_entry_set_text (GTK_ENTRY (dialog->details->folder_entry), "/");
	gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->folder_entry), TRUE);
1020 1021
	gtk_grid_attach_next_to (GTK_GRID (grid), dialog->details->folder_entry, label,
				 GTK_POS_RIGHT, 1, 1);
1022
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->folder_entry);
1023
	gtk_widget_show (dialog->details->folder_entry);
1024
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->folder_entry);
1025 1026 1027 1028 1029 1030

	/* 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);
1031
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
	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);

	bind_visibility (dialog, alignment, label);
	dialog->details->user_details = alignment;

1043 1044 1045 1046 1047 1048
	grid = gtk_grid_new ();
	gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
	gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
	gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL);
	gtk_container_add (GTK_CONTAINER (alignment), grid);
	gtk_widget_show (grid);
1049 1050

	/* first row: domain entry */
1051
	label = gtk_label_new_with_mnemonic (_("_Domain name:"));
1052
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1053
	gtk_container_add (GTK_CONTAINER (grid), label);
1054

1055
	dialog->details->domain_entry = gtk_entry_new ();
1056
	gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->domain_entry), TRUE);
1057
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
1058 1059 1060
	gtk_grid_attach_next_to (GTK_GRID (grid), dialog->details->domain_entry, label,
				 GTK_POS_RIGHT, 1, 1);

1061
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->domain_entry);
1062
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->domain_entry);
1063 1064 1065
	bind_visibility (dialog, dialog->details->domain_entry, label);

	/* second row: username entry */
1066
	label = gtk_label_new_with_mnemonic (_("_User name:"));
1067
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1068
	gtk_container_add (GTK_CONTAINER (grid), label);
1069
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
1070

1071
	dialog->details->user_entry = gtk_entry_new ();
1072
	gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->user_entry), TRUE);
1073 1074
	gtk_grid_attach_next_to (GTK_GRID (grid), dialog->details->user_entry, label,
				 GTK_POS_RIGHT, 1, 1);
1075
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->user_entry);
1076
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->user_entry);
1077 1078 1079

	bind_visibility (dialog, dialog->details->user_entry, label);

1080
	/* third row: password entry */
1081
	label = gtk_label_new_with_mnemonic (_("Pass_word:"));
1082
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1083
	gtk_container_add (GTK_CONTAINER (grid), label);
1084
	gtk_size_group_add_widget (dialog->details->labels_size_group, label);
1085 1086 1087 1088

	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);
1089 1090
	gtk_grid_attach_next_to (GTK_GRID (grid), dialog->details->password_entry, label,
				 GTK_POS_RIGHT, 1, 1);
1091
	gtk_size_group_add_widget (dialog->details->contents_size_group, dialog->details->password_entry);
1092
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->details->password_entry);
1093

1094
	bind_visibility (dialog, dialog->details->password_entry, label);
1095

1096
	/* fourth row: remember checkbox */
1097
	checkbox = gtk_check_button_new_with_mnemonic (_("_Remember this password"));
1098 1099
	gtk_grid_attach_next_to (GTK_GRID (grid), checkbox, dialog->details->password_entry,
				 GTK_POS_BOTTOM, 1, 1);
1100
	dialog->details->remember_checkbox = checkbox;
1101

1102
	bind_visibility (dialog, dialog->details->password_entry, checkbox);
1103

1104 1105 1106
        gtk_dialog_add_button (GTK_DIALOG (dialog),
                               GTK_STOCK_HELP,
                               GTK_RESPONSE_HELP);
Alexander Larsson's avatar
Alexander Larsson committed
1107 1108
	gtk_dialog_add_button (GTK_DIALOG (dialog),
			       GTK_STOCK_CANCEL,
1109
			       GTK_RESPONSE_CANCEL);
1110 1111 1112
	connect_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
						_("C_onnect"),
						RESPONSE_CONNECT);
Alexander Larsson's avatar
Alexander Larsson committed
1113 1114
	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
					 RESPONSE_CONNECT);
1115
	dialog->details->connect_button = connect_button;
Alexander Larsson's avatar
Alexander Larsson committed
1116

1117
	g_signal_connect (dialog->details->server_entry, "changed",
1118
			  G_CALLBACK (sensitive_entry_changed_callback),
1119
			  connect_button);
1120 1121
	sensitive_entry_changed_callback (GTK_EDITABLE (dialog->details->server_entry),
					  connect_button);
1122

Alexander Larsson's avatar
Alexander Larsson committed
1123
	g_signal_connect (dialog, "response",
1124
			  G_CALLBACK (connect_dialog_response_cb),
Alexander Larsson's avatar
Alexander Larsson committed
1125
			  dialog);
1126

1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
	connect_dialog_setup_for_type (dialog);
}

static void
nautilus_connect_server_dialog_finalize (GObject *object)
{
	NautilusConnectServerDialog *dialog;

	dialog = NAUTILUS_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 (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));
Alexander Larsson's avatar
Alexander Larsson committed
1156 1157 1158
}

GtkWidget *
1159
nautilus_connect_server_dialog_new (NautilusWindow *window)
Alexander Larsson's avatar
Alexander Larsson committed
1160 1161 1162 1163 1164 1165 1166 1167
{
	GtkWidget *dialog;

	dialog = gtk_widget_new (NAUTILUS_TYPE_CONNECT_SERVER_DIALOG, NULL);

	if (window) {
		gtk_window_set_screen (GTK_WINDOW (dialog),
				       gtk_window_get_screen (GTK_WINDOW (window)));
1168
	}
1169

Alexander Larsson's avatar
Alexander Larsson committed
1170 1171
	return dialog;
}
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192

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;

1193 1194 1195 1196 1197 1198 1199 1200 1201
	if (g_cancellable_is_cancelled (self->details->mount_cancellable)) {
		g_simple_async_report_error_in_idle (G_OBJECT (self),
						     callback, user_data,
						     G_IO_ERROR, G_IO_ERROR_CANCELLED,
						     "%s", _("Operation cancelled"));

		return;
	}

1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
	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;
1219 1220 1221 1222 1223 1224
			
			if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED &&
			    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->details->remember_checkbox))) {
				g_mount_operation_set_password_save (G_MOUNT_OPERATION (operation),
								     G_PASSWORD_SAVE_PERMANENTLY);
			}
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256

			self->details->last_password_set = TRUE;
		}
	}