nautilus-first-time-druid.c 48.3 KB
Newer Older
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

/*
 * Nautilus
 *
 * Copyright (C) 2000 Eazel, Inc.
 *
 * This program 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.
 *
 * This program 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; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Andy Hertzfeld <andy@eazel.com>
 */

26
#include <config.h>
27
#include "nautilus-first-time-druid.h"
28

29
#include <ctype.h>
30
#include <dirent.h>
Ramiro Estrugo's avatar
Ramiro Estrugo committed
31 32 33 34 35 36 37 38
#include <eel/eel-background.h>
#include <eel/eel-gdk-extensions.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-extensions.h>
#include <eel/eel-image.h>
#include <eel/eel-label.h>
#include <eel/eel-radio-button-group.h>
Ramiro Estrugo's avatar
Ramiro Estrugo committed
39
#include <eel/eel-stock-dialogs.h>
Ramiro Estrugo's avatar
Ramiro Estrugo committed
40
#include <eel/eel-string.h>
Ramiro Estrugo's avatar
Ramiro Estrugo committed
41 42 43 44
#include <eel/eel-vfs-extensions.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gnome.h>
#include <libgnomevfs/gnome-vfs.h>
45 46 47 48 49
#include <libnautilus-private/nautilus-druid-page-eazel.h>
#include <libnautilus-private/nautilus-druid.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libnautilus-private/nautilus-global-preferences.h>
#include <libnautilus-private/nautilus-link.h>
50 51
#include <nautilus-main.h>
#include <netdb.h>
52
#include <signal.h>
53 54 55 56 57 58
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
59

Ramiro Estrugo's avatar
Ramiro Estrugo committed
60
#define SIZE_BODY_LABEL(l)  eel_label_make_smaller (EEL_LABEL (l), 1)
61

62 63
#define SERVICE_UPDATE_ARCHIVE_PATH "/tmp/nautilus_update.tgz"
#define WELCOME_PACKAGE_URI "http://services.eazel.com/downloads/eazel/updates.tgz"
64

65
/* Druid page number enumeration */
66 67
enum {
	USER_LEVEL_PAGE = 0,
68
#ifdef TRANSITIONAL_NAUTILUS
69
	GMC_TRANSITION_PAGE,
70
#endif
71 72 73 74 75
	OFFER_UPDATE_PAGE,
	UPDATE_FEEDBACK_PAGE,
	PROXY_CONFIGURATION_PAGE,
	NUMBER_OF_STANDARD_PAGES	/* This must be the last item in the enumeration. */
};
76

77
/* Preference for http proxy settings */
78
#define DEFAULT_HTTP_PROXY_PORT 8080
Darin Adler's avatar
Darin Adler committed
79
#define DEFAULT_HTTP_PROXY_PORT_STRING "8080"
80 81
#define GNOME_VFS_PREFERENCES_HTTP_PROXY_HOST "/system/gnome-vfs/http-proxy-host"
#define GNOME_VFS_PREFERENCES_HTTP_PROXY_PORT "/system/gnome-vfs/http-proxy-port"
82
#define GNOME_VFS_PREFERENCES_USE_HTTP_PROXY "/system/gnome-vfs/use-http-proxy"
83

84 85
#define READ_FILE_HANDLE_TAG "Nautilus first time druid read file handle"

86 87 88 89
/* The number of seconds we'll wait for our experimental DNS resolution */
#define NETWORK_CHECK_TIMEOUT_SECONDS 15
#define DEFAULT_DNS_CHECK_HOST "services.eazel.com"

90
#define GALEON_PREFS_PATH "/.gnome/galeon"
91

92 93 94 95
#define GETLINE_INITIAL_BUFFER_SIZE 256

#define NETSCAPE_PREFS_PATH "/.netscape/preferences.js"

96
/* globals */
97
static NautilusApplication *save_application;
98

99 100
static GtkWidget *start_page;
static GtkWidget *finish_page;
101
static GtkWidget *pages[NUMBER_OF_STANDARD_PAGES];
102

103
static GtkWidget *download_label;
104
static GtkWidget *finished_label;
105

106
static int last_update_choice = 0;
107 108 109 110
static int last_proxy_choice = 1;

static GtkWidget *port_number_entry;
static GtkWidget *proxy_address_entry;
111

112 113 114 115 116
/* Only set true when we're absolutely totally positive that we've got
 * an http connection to the outside world.
 */
static gboolean http_is_known_to_work = FALSE;

117
/* Set by set_http_proxy; used by check_network_connectivity */
118

119 120
/* NULL indicates no HTTP proxy */
static char *http_proxy_host = NULL;
121

122 123 124 125 126 127 128
/* The result of the last check_network_connectivity call */
static enum {
	Untested,
	Success,
	Fail
} network_status = Untested;

129

130 131 132 133
/* Globals used to implement DNS timeout. */
static gboolean sigalrm_occurred;
static pid_t child_pid;

134 135
/* GMC transition tool globals */
static gboolean draw_desktop = TRUE;
136
#ifdef TRANSITIONAL_NAUTILUS
137 138
static gboolean add_to_session = TRUE;
static gboolean transfer_gmc_icons = TRUE;
139
static GtkWidget *draw_desktop_checkbox_widget;
140
#endif
141

142 143
static int current_user_level;

144 145
static void     initiate_file_download           (GnomeDruid 	*druid);
static gboolean set_http_proxy                   (const char 	*proxy_url);
146 147
static gboolean attempt_http_proxy_autoconfigure (void);
static gboolean check_network_connectivity	 (void);
148
#ifdef TRANSITIONAL_NAUTILUS
149
static gint	convert_gmc_desktop_icons 	 (gpointer       unused_data);
150
#endif
151
static void	update_finished_label		 (void);
152

153 154 155
static void
druid_cancel (GtkWidget *druid)
{
156 157
	gtk_widget_destroy (gtk_widget_get_toplevel (druid));

158
	/* FIXME bugzilla.eazel.com 5050: Why _exit instead of a plain exit? It might be OK
159 160 161
	 * to do nothing here now that Nautilus knows to quit when
	 * windows go away.
	 */
162 163 164 165 166
	_exit (0);
}

/* handle the final page finishing  */

167 168 169 170 171
static void
druid_set_first_time_file_flag (void)
{
	FILE *stream;
	char *user_directory, *druid_flag_file_name;
172 173 174 175
	const char * const blurb =
		_("Existence of this file indicates that the Nautilus configuration druid\n"
		  "has been presented.\n\n"
		  "You can manually erase this file to present the druid again.\n");
176 177
	
	user_directory = nautilus_get_user_directory ();
178
	druid_flag_file_name = nautilus_make_path (user_directory, "first-time-flag");
179 180 181
	g_free (user_directory);
		
	stream = fopen (druid_flag_file_name, "w");
182 183 184
	if (stream != NULL) {
		fwrite (blurb, sizeof (char), strlen (blurb), stream);
		fclose (stream);
185 186 187 188
	}
	g_free (druid_flag_file_name);
}

189 190 191
static void
druid_finished (GtkWidget *druid_page)
{
192
	char *user_main_directory;
193
	const char *signup_uris[3];
194
	
195 196 197 198
	
	/* Hide druid so we don't have a blocked dialog visible while we process the startup tasks. */
	gtk_widget_hide_all (gtk_widget_get_toplevel (druid_page));
	
199
	user_main_directory = nautilus_get_user_main_directory ();
200 201 202

	g_free (user_main_directory);

203 204
	/* write out the first time file to indicate that we've successfully traversed the druid */
	druid_set_first_time_file_flag ();
205

206
	/* Do the user level config */
207
	eel_preferences_set_user_level (current_user_level);
208
	
209 210
	/* Here we check to see if we can resolve hostnames in a timely
	 * fashion. If we can't then we silently tell nautilus to start up
211 212
	 * pointing to the home directory and not any of the HTTP addresses--
	 * we don't want Nautilus to hang indefinitely trying to resolve
213
	 * an HTTP address.
214
	 */
215
	/* FIXME bugzilla.eazel.com 5051: Perhaps we can fix the underlying problem instead of
216 217
	 * having this hack here to guess whether the network is broken.
	 */
218
	if (Untested == network_status) {
219 220
		check_network_connectivity ();
	}
221

222
	signup_uris[0] = eel_preferences_get (NAUTILUS_PREFERENCES_HOME_URI);
223
	signup_uris[1] = NULL;
224

225

226
#ifdef TRANSITIONAL_NAUTILUS
227
	/* Do the GMC to Nautilus Transition */
228 229
	nautilus_preferences_set_boolean (NAUTILUS_PREFERENCES_SHOW_DESKTOP, draw_desktop);	
	nautilus_preferences_set_boolean (NAUTILUS_PREFERENCES_ADD_TO_SESSION, add_to_session);	
230
	if (transfer_gmc_icons) {
231 232 233 234 235
		/* Do this at idle time, once nautilus has initialized
		 * itself. Otherwise we may spawn a second nautilus
		 * process when looking for a metadata factory..
		 */
		gtk_idle_add (convert_gmc_desktop_icons, NULL);
236
	}
237
#endif
238 239
	
	/* Time to start. Hooray! */
240
	nautilus_application_startup (save_application, FALSE, FALSE, draw_desktop, 
241
				      FALSE, FALSE, NULL, (signup_uris[0] != NULL) ? signup_uris : NULL);
242 243
	
	/* Destroy druid last because it may be the only thing keeping the main event loop alive. */
244
	gtk_widget_destroy (gtk_widget_get_toplevel (druid_page));
245 246 247 248
}

/* set up an event box to serve as the background */

249
static GtkWidget *
250
set_up_background (NautilusDruidPageEazel *page, const char *background_color)
251 252
{
	GtkWidget *event_box;
Ramiro Estrugo's avatar
Ramiro Estrugo committed
253
	EelBackground *background;
254
	
255
	event_box = gtk_event_box_new ();
256
	
Ramiro Estrugo's avatar
Ramiro Estrugo committed
257 258
	background = eel_get_widget_background (event_box);
	eel_background_set_color (background, background_color);
259 260 261
	
	gtk_widget_show (event_box);

262 263
	nautilus_druid_page_eazel_put_widget (page, event_box);

264 265 266
	return event_box;
}

267
static void
268
update_draw_desktop_checkbox_state (void)
269
{
270
#ifdef TRANSITIONAL_NAUTILUS
271
	if (current_user_level == EEL_USER_LEVEL_NOVICE) {
272 273 274 275
		gtk_widget_hide (draw_desktop_checkbox_widget);
	} else {
		gtk_widget_show (draw_desktop_checkbox_widget);
	}
276
#endif
277 278
}

279 280
/* handler for user level buttons changing */
static void
281
user_level_selection_changed (GtkWidget *radio_button, gpointer user_data)
282
{
283
	if (GTK_TOGGLE_BUTTON (radio_button)->active) {
284
	    current_user_level = GPOINTER_TO_INT (user_data);
285
	}
286

287
	update_draw_desktop_checkbox_state ();
288 289
}

290
/* handler for signup buttons changing */
291 292 293
static void
update_selection_changed (GtkWidget *radio_buttons, gpointer user_data)
{
Ramiro Estrugo's avatar
Ramiro Estrugo committed
294
	last_update_choice = eel_radio_button_group_get_active_index (EEL_RADIO_BUTTON_GROUP (radio_buttons));
295 296
}

297 298 299
static void
proxy_selection_changed (GtkWidget *radio_buttons, gpointer user_data)
{
Ramiro Estrugo's avatar
Ramiro Estrugo committed
300
	last_proxy_choice = eel_radio_button_group_get_active_index (EEL_RADIO_BUTTON_GROUP (radio_buttons));
301 302
}

303

304 305
/* Utility to allocate a non anti-aliased description label. Used for
 * body text in the druid pages. */
306 307

static GtkWidget*
308
label_new_left_justified (const char *text)
309 310 311
{
	GtkWidget *label;
	
Ramiro Estrugo's avatar
Ramiro Estrugo committed
312 313 314
	label = eel_label_new (text);
	eel_label_set_justify (EEL_LABEL (label), GTK_JUSTIFY_LEFT);
	eel_label_set_is_smooth (EEL_LABEL (label), FALSE);
315 316 317 318 319 320 321 322

	return label;
}

static GtkWidget *
new_title_label (const char *text)
{
	GtkWidget *label;
Ramiro Estrugo's avatar
Ramiro Estrugo committed
323
	EelScalableFont *font;
324 325 326

	label = label_new_left_justified (text);

Ramiro Estrugo's avatar
Ramiro Estrugo committed
327
	font = eel_scalable_font_get_default_font ();
328 329 330 331 332 333 334 335

	/* Force the label into smooth mode only if our locale is not
	 * multibyte.  The problem is that for multibyte locales it is
	 * likely that there will be no properly encoded font setup for
	 * nautilus use at this time.  By making the label not smooth in 
	 * multi bytes locales, we make the first time druid work in more
	 * systems.
	 */
Ramiro Estrugo's avatar
Ramiro Estrugo committed
336 337 338 339 340 341 342 343
	eel_label_set_is_smooth (EEL_LABEL (label), 
				      !eel_dumb_down_for_multi_byte_locale_hack ());

	eel_label_set_smooth_font (EEL_LABEL (label), font);
	eel_label_make_larger (EEL_LABEL (label), 10);
	eel_label_set_smooth_drop_shadow_offset (EEL_LABEL (label), 2);
	eel_label_set_smooth_drop_shadow_color (EEL_LABEL (label),
						     EEL_RGBA_COLOR_PACK
344 345 346 347 348 349 350 351 352 353 354
						     (191, 191, 191, 255));
	return label;
}

static GtkWidget *
new_body_label (const char *text)
{
	GtkWidget *label;

	label = gtk_label_new (text);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
355 356 357

	return label;
}
358

359 360 361 362 363 364 365 366 367 368
static GdkPixbuf*
create_named_pixbuf (const char *name) 
{
	GdkPixbuf	*pixbuf;
	char		*path;
	
	g_return_val_if_fail (name != NULL, NULL);
	
	path = nautilus_pixmap_file (name);

369 370 371 372
	if (path == NULL) {
		return NULL;
	}

373 374 375 376 377 378
	pixbuf = gdk_pixbuf_new_from_file (path);
	g_free (path);

	return pixbuf;
}

379 380
static GtkWidget *
make_hbox_user_level_radio_button (int index, GtkWidget *radio_buttons[],
381
				   const char *icon_name,
382 383
				   const char *comment, const char *background)
{
384 385
	GtkWidget *hbox, *vbox;
	GtkWidget *label_box, *icon, *label, *alignment;
386 387
	GtkWidget *comment_vbox, *comment_hbox;
	GdkPixbuf *icon_pixbuf;
388
	char *user_level_name;
389 390 391

	hbox = gtk_hbox_new (FALSE, 0);

392
	user_level_name = eel_preferences_get_user_level_name_for_display (index);
393

394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
	/* make new box for radiobutton/comment */
	comment_vbox = gtk_vbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (hbox), comment_vbox, FALSE, FALSE, 0);

	/* Make new radio button */
	if (index > 0) {
		radio_buttons[index] = gtk_radio_button_new_from_widget
			(GTK_RADIO_BUTTON (radio_buttons[0]));
	} else {
		radio_buttons[0] = gtk_radio_button_new (NULL);
	}
	gtk_box_pack_start (GTK_BOX (comment_vbox), radio_buttons[index], FALSE, FALSE, 0);

	/* Make label */
	label_box = gtk_hbox_new (FALSE, 5);

	icon_pixbuf = create_named_pixbuf (icon_name);
Ramiro Estrugo's avatar
Ramiro Estrugo committed
411
	icon = eel_image_new (NULL);
412
	if (icon_pixbuf != NULL) {
Ramiro Estrugo's avatar
Ramiro Estrugo committed
413
		eel_image_set_pixbuf (EEL_IMAGE (icon), icon_pixbuf);
414
	}
415
	gtk_box_pack_start (GTK_BOX (label_box), icon, FALSE, FALSE, 0);
416
	label = new_body_label (user_level_name);
Ramiro Estrugo's avatar
Ramiro Estrugo committed
417
	eel_gtk_label_make_bold (GTK_LABEL (label));
418
	g_free (user_level_name);
419

420 421 422 423 424 425 426
	/* extra vbox to help with alignment */
	vbox = gtk_vbox_new (FALSE, 0);
	alignment = gtk_alignment_new (1.0, 1.0, 1.0, 1.0);
	gtk_widget_set_usize (alignment, -1, 6);
	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
	gtk_box_pack_start (GTK_BOX (label_box), vbox, FALSE, FALSE, 0);
427 428 429 430 431 432 433 434 435 436 437 438 439 440

	/* add label to radio button */
	gtk_container_add (GTK_CONTAINER (radio_buttons[index]), label_box);

	/* make new hbox for comment */
	comment_hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (comment_vbox), comment_hbox, FALSE, FALSE, 0);

	/* Add an "indent" */
	alignment = gtk_alignment_new (1.0, 1.0, 1.0, 1.0);
	gtk_widget_set_usize (alignment, 50, -1);
	gtk_box_pack_start (GTK_BOX (comment_hbox), alignment, FALSE, FALSE, 0);

	/* Make comment label */
441
	label = new_body_label (comment);
442

443
	gtk_box_pack_start (GTK_BOX (comment_hbox), label, FALSE, FALSE, 0);
444 445 446 447
	gtk_widget_show_all (hbox);
	return hbox;
}

448 449
/* set up the user level page */
static void
450
set_up_user_level_page (NautilusDruidPageEazel *page)
451
{
452 453
	char *operating_system_name;
	char *message;
454 455
	GtkWidget *radio_buttons[3], *label;
	GtkWidget *container, *main_box, *hbox;
456
	int index;
457

458
	container = set_up_background (page, "rgb:ffff/ffff/ffff:h");
459 460 461 462 463 464

	/* allocate a vbox to hold the description and the widgets */
	main_box = gtk_vbox_new (FALSE, 0);
	gtk_container_add (GTK_CONTAINER (container), main_box);
	
	/* allocate a descriptive label */
465 466 467
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);

468 469 470 471 472 473 474 475 476 477
	operating_system_name = eel_get_operating_system_name ();

	message = g_strdup_printf (_("Your user level adjusts Nautilus to your degree of experience\n"
				     "using GNOME and %s. Choose a level that's comfortable for\n"
				     "you - you can always change it later."),
				   operating_system_name);
	
	
	label = new_body_label (message);
	g_free (message);
478

479
	gtk_widget_show (label);
480 481 482 483
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

	/* Make the user level radio buttons and fill the radio_buttons
	 * array */
484 485 486
	message = g_strdup_printf (_("For users who have no previous experience with GNOME\n"
				     "and %s."),
				   operating_system_name);
487
	hbox = make_hbox_user_level_radio_button (EEL_USER_LEVEL_NOVICE, radio_buttons, "novice.png",
488 489 490
						  message,
						  NULL);
	g_free (message);
491
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 2);
492 493 494
	message = g_strdup_printf (_("For users who are comfortable with GNOME and %s,\n"
				     "but don't describe themselves as ``technical.''"),
				   operating_system_name);
495
	hbox = make_hbox_user_level_radio_button (EEL_USER_LEVEL_INTERMEDIATE,
496 497 498 499 500
						  radio_buttons,
						  "intermediate.png",
						  message,
						  NULL);
	g_free (message);
501
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 2);
502 503 504
	message = g_strdup_printf (_("For users who have GNOME and %s experience, and\n"
				     "like to see every detail of the operating system."),
				   operating_system_name);
505
	hbox = make_hbox_user_level_radio_button (EEL_USER_LEVEL_ADVANCED,
506 507 508 509 510 511
						  radio_buttons,
						  "expert.png",
						  message,
						  NULL);
	g_free (message);
	g_free (operating_system_name);
512
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 2);
513

514 515
	g_assert (current_user_level >= EEL_USER_LEVEL_NOVICE
		  && current_user_level <= EEL_USER_LEVEL_ADVANCED);
516
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_buttons[current_user_level]), TRUE);
517 518


519
	for (index = EEL_USER_LEVEL_NOVICE; index <= EEL_USER_LEVEL_ADVANCED; index ++) {
520 521 522 523 524
		gtk_signal_connect (GTK_OBJECT (radio_buttons[index]),
				    "toggled",
				    GTK_SIGNAL_FUNC (user_level_selection_changed),
				    GINT_TO_POINTER (index));
	}
525

526
	gtk_widget_show_all (main_box);
527 528
}

529 530
/* set up the "Nautilus Update" page */
static void
531
set_up_update_page (NautilusDruidPageEazel *page)
532
{
533 534
	GtkWidget *radio_buttons, *label;
	GtkWidget *container, *main_box, *hbox;
535

536
	container = set_up_background (page, "rgb:ffff/ffff/ffff:h");
537 538 539 540 541 542 543

	/* allocate a vbox to hold the description and the widgets */
	main_box = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (main_box);
	gtk_container_add (GTK_CONTAINER (container), main_box);
	
	/* allocate a descriptive label */
544 545 546 547 548 549 550 551 552
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);

	label = new_body_label (_("To verify your Internet connection and make sure you have\n"
				  "the latest Nautilus updates, Nautilus will now connect to\n"
				  "Eazel's web site. This will take seconds if your copy of\n"
				  "Nautilus is recent; longer (but no more than a minute or two)\n"
				  "if you need an update.\n\n"
				  "If you know your computer uses a proxy connection, click\n"
553
				  "Verify and Nautilus will use it.\n"));
554

555
	gtk_widget_show (label);
556
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
557
	
Ramiro Estrugo's avatar
Ramiro Estrugo committed
558
	radio_buttons = eel_radio_button_group_new (FALSE);
559
	gtk_box_pack_start (GTK_BOX (main_box), radio_buttons, FALSE, FALSE, 0);
560

Ramiro Estrugo's avatar
Ramiro Estrugo committed
561 562
	eel_radio_button_group_insert (EEL_RADIO_BUTTON_GROUP (radio_buttons), _("Verify my connection and check for updates"));
	eel_radio_button_group_insert (EEL_RADIO_BUTTON_GROUP (radio_buttons), _("Don't verify my connection or check for updates"));	
563 564 565 566 567 568 569 570

	gtk_signal_connect (GTK_OBJECT (radio_buttons),
			    "changed",
			    GTK_SIGNAL_FUNC (update_selection_changed),
			    (gpointer) NULL);

	gtk_widget_show (radio_buttons);

571
	gtk_widget_show_all (main_box);
572 573
}

574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604

static gint
proxy_address_entry_key_press (GtkWidget	*widget,
                 	       GdkEventKey	*event,
                 	       gpointer		callback_data)
{
	char *keysym_name;
	GtkWidget *focus_target;

	focus_target = GTK_WIDGET (callback_data);

	g_return_val_if_fail (NULL != focus_target, FALSE);
	
	keysym_name = gdk_keyval_name (event->keyval);

	if (strcmp (keysym_name, "Tab") == 0) {
		gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");

		gtk_widget_grab_focus (focus_target);

		if (GTK_IS_EDITABLE (focus_target)) {
			gtk_editable_select_region (GTK_EDITABLE (focus_target), 0, -1);
		}

		return TRUE;
	}

	return FALSE;
}


605 606 607 608 609
/* set up the proxy configuration page */
static void
set_up_proxy_config_page (NautilusDruidPageEazel *page)
{
	GtkWidget *radio_buttons;
610
	GtkWidget *label;
611 612 613 614 615 616 617 618 619 620 621 622 623
	GtkWidget *container, *main_box;
	GtkWidget *vbox, *hbox;
	GtkWidget *alignment;
	int proxy_label_width;
	
	container = set_up_background (page, "rgb:ffff/ffff/ffff:h");

	/* allocate a vbox to hold the description and the widgets */
	main_box = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (main_box);
	gtk_container_add (GTK_CONTAINER (container), main_box);
	
	/* allocate a descriptive label */
624 625 626 627 628 629
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);

	label = new_body_label (_("We are having trouble making an external web connection.\n"
				  "Sometimes, firewalls require you to specify a web proxy server.\n"
				  "Fill in the name or port of your proxy server, if any, below."));
630
	gtk_widget_show (label);
631
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
632 633 634 635 636
	
	/* allocate a pair of radio buttons */
	vbox = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox);

Ramiro Estrugo's avatar
Ramiro Estrugo committed
637
	radio_buttons = eel_radio_button_group_new (FALSE);
638

Ramiro Estrugo's avatar
Ramiro Estrugo committed
639 640
	eel_radio_button_group_insert (EEL_RADIO_BUTTON_GROUP (radio_buttons), _("No proxy server required."));
	eel_radio_button_group_insert (EEL_RADIO_BUTTON_GROUP (radio_buttons), _("Use this proxy server:"));	
641
	
Ramiro Estrugo's avatar
Ramiro Estrugo committed
642
	eel_radio_button_group_set_active_index (EEL_RADIO_BUTTON_GROUP (radio_buttons), 1);
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664

	gtk_signal_connect (GTK_OBJECT (radio_buttons),
			    "changed",
			    GTK_SIGNAL_FUNC (proxy_selection_changed),
			    (gpointer) NULL);

	gtk_widget_show (radio_buttons);	

	gtk_box_pack_start (GTK_BOX (vbox), radio_buttons, FALSE, FALSE, 2);

	/* allocate the proxy name entry */
	
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox);

	/* allocate an alignment width to indent */
	alignment = gtk_alignment_new (1.0, 1.0, 1.0, 1.0);
	gtk_widget_show (alignment);
	gtk_widget_set_usize (alignment, 24, -1);
	gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0);
	
	/* allocate the proxy label, followed by the entry */
Ramiro Estrugo's avatar
Ramiro Estrugo committed
665
	label = eel_label_new (_("Proxy address:"));
666
	gtk_widget_show (label);
667
	SIZE_BODY_LABEL (label);
668 669 670 671 672 673 674 675 676 677 678 679 680 681
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
	proxy_label_width = label->allocation.width;
	proxy_address_entry = gtk_entry_new_with_max_length (24);
	gtk_widget_set_usize (proxy_address_entry, 180, -1);
	gtk_widget_show (proxy_address_entry);
	gtk_box_pack_start (GTK_BOX (hbox), proxy_address_entry, FALSE, FALSE, 2);
	
	/* allocate the port number entry */
	
	alignment = gtk_alignment_new (1.0, 1.0, 1.0, 1.0);
	gtk_box_pack_start (GTK_BOX (hbox), alignment, FALSE, FALSE, 0);
	gtk_widget_set_usize (alignment, 8, -1);
	
	/* allocate the proxy label, followed by the entry */
Ramiro Estrugo's avatar
Ramiro Estrugo committed
682
	label = eel_label_new (_("Port:"));
683
	SIZE_BODY_LABEL (label);
684 685 686 687
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);

	port_number_entry = gtk_entry_new_with_max_length (5);
688 689
	gtk_entry_set_text (GTK_ENTRY (port_number_entry), DEFAULT_HTTP_PROXY_PORT_STRING);
	
690 691 692 693 694
	gtk_widget_set_usize (port_number_entry, 48, -1);
	gtk_widget_show (port_number_entry);
	gtk_box_pack_start (GTK_BOX (hbox), port_number_entry, FALSE, FALSE, 2);
	
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 2);
695
	gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 2);
696 697


698 699 700 701 702 703 704 705 706
	/* Slam it so that the <tab> in "Proxy Address" goes to "Port"
	 * I have no idea why this doesn't just work
	 */

	gtk_signal_connect (GTK_OBJECT (proxy_address_entry),
			    "key_press_event",
			    GTK_SIGNAL_FUNC (proxy_address_entry_key_press),
			    port_number_entry);

707 708
}

709 710
/* set up the update feedback page */
static void
711
set_up_update_feedback_page (NautilusDruidPageEazel *page)
712
{
713
	GtkWidget *label;
714
	GtkWidget *container, *main_box, *hbox;
715

716
	container = set_up_background (page, "rgb:ffff/ffff/ffff:h");
717 718 719 720 721 722 723

	/* allocate a vbox to hold the description and the widgets */
	main_box = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (main_box);
	gtk_container_add (GTK_CONTAINER (container), main_box);
	
	/* allocate a descriptive label */
724 725 726
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox);

727
	label = new_body_label (_("Verifying your Internet connection and checking for updates..."));
728 729
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
730
		
731
		
732 733 734
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox);

735
	download_label = new_body_label (_("Downloading Nautilus updates..."));
736 737
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);
	gtk_box_pack_start (GTK_BOX (hbox), download_label, FALSE, FALSE, 0);
738

739
	gtk_widget_show_all (main_box);
740 741 742 743
}

/* handle the "next" signal for the update page based on the user's choice */
static gboolean
744
next_update_page_callback (GtkWidget *button, GnomeDruid *druid)
745 746 747
{
	if (last_update_choice == 0) {
		/* initiate the file transfer and launch a timer task to track feedback */
748
		/* FIXME bugzilla.eazel.com 5053: There's no timer task! */
749 750
		initiate_file_download (druid);
		
751 752 753 754 755
		/* return FALSE to display the feedback page */
		return FALSE;
	}

	/* the user declined to update, so skip the feedback page and go directly to finish */
756
	update_finished_label ();
757
	gnome_druid_set_page (druid, GNOME_DRUID_PAGE (finish_page));
758 759 760
	return TRUE;
}

761 762
/* handle the "next" signal for the update feedback page to skip the error page */
static gboolean
763
next_update_feedback_page_callback (GtkWidget *button, GnomeDruid *druid)
764 765
{
	/* skip the error page by going write to the finish line */
766
	gnome_druid_set_page (druid, GNOME_DRUID_PAGE (finish_page));
767 768 769 770 771
	return TRUE;
}

/* handle the "next" signal for the update feedback page to skip the error page */
static gboolean
772
next_proxy_configuration_page_callback (GtkWidget *button, GnomeDruid *druid)
773
{
774 775
	const char *proxy_text;
	const char *port_text;
776
	char *proxy_url;
777 778 779 780 781

	proxy_text = gtk_entry_get_text (GTK_ENTRY (proxy_address_entry));
	port_text = gtk_entry_get_text (GTK_ENTRY (port_number_entry));

	/* Update the http proxy only if there is some user input */
Ramiro Estrugo's avatar
Ramiro Estrugo committed
782
	if (eel_strlen (proxy_text) > 0 && eel_strlen (port_text) > 0) {
783 784 785 786
		proxy_url = g_strdup_printf ("http://%s:%s", proxy_text, port_text);
		set_http_proxy (proxy_url);
		g_free (proxy_url);
	}
787 788 789
	
	/* now, go back to the offer update page or finish, depending on the user's selection */
	if (last_proxy_choice == 1) {
790
		gnome_druid_set_page (druid, GNOME_DRUID_PAGE (pages[OFFER_UPDATE_PAGE]));
791
	} else {
792
		gnome_druid_set_page (druid, GNOME_DRUID_PAGE (finish_page));
793 794 795 796 797
	}
	
	return TRUE;
}

798
#ifdef TRANSITIONAL_NAUTILUS
799

800 801
static gint
convert_gmc_desktop_icons (gpointer unused_data)
802 803
{
	const char *home_dir;
804
	char *gmc_desktop_dir, *nautilus_desktop_dir, *link_path;
805 806
	DIR *dir;
	struct dirent *dirent;
807 808
	GnomeDesktopEntry *gmc_link;
	
809 810
	home_dir = g_get_home_dir ();
	if (home_dir == NULL) {
811
		return FALSE;
812 813
	}
		
814 815
	gmc_desktop_dir = g_strdup_printf ("%s/.gnome-desktop", home_dir);
	
816 817 818
	dir = opendir (gmc_desktop_dir);
	if (dir == NULL) {
		g_free (gmc_desktop_dir);
819
		return FALSE;
820 821
	}

822 823
	nautilus_desktop_dir = nautilus_get_desktop_directory ();

824
	/* Iterate all the files here and indentify the GMC links. */
825
	for (dirent = readdir (dir); dirent != NULL; dirent = readdir (dir)) {
826 827 828
		if (strcmp (dirent->d_name, ".") == 0 || strcmp (dirent->d_name, "..") == 0) {
			continue;
		}
829 830 831 832 833 834 835 836 837
		
		link_path = g_strdup_printf ("%s/%s", gmc_desktop_dir, dirent->d_name);
		gmc_link = gnome_desktop_entry_load_unconditional (link_path);
		g_free (link_path);
		
		if (gmc_link != NULL) {
			nautilus_link_local_create_from_gnome_entry (gmc_link, nautilus_desktop_dir, NULL);
			gnome_desktop_entry_free (gmc_link);
		}
838
	}
839 840 841

	closedir (dir);
	
842 843 844
	g_free (gmc_desktop_dir);
	g_free (nautilus_desktop_dir);	

845
	return FALSE;
846 847 848 849 850 851 852
}

/* handle the "next" signal for the update feedback page to skip the error page */
static gboolean
transition_value_changed (GtkWidget *checkbox, gboolean *value)
{	
	*value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
853

854 855 856 857 858 859 860
	return TRUE;
}

/* set up the "GMC to Nautilus Transition" page */
static void
set_up_gmc_transition_page (NautilusDruidPageEazel *page)
{
861 862 863
	GtkWidget *checkbox, *label;
	GtkWidget *container, *main_box, *hbox;

864
	draw_desktop = TRUE;
865 866
	add_to_session = TRUE;
	transfer_gmc_icons = TRUE;
867 868 869 870 871 872 873 874

	container = set_up_background (page, "rgb:ffff/ffff/ffff:h");

	/* allocate a vbox to hold the description and the widgets */
	main_box = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (main_box);
	gtk_container_add (GTK_CONTAINER (container), main_box);
	
875 876 877 878 879 880 881 882 883 884 885 886
	/* allocate a descriptive label */
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (main_box), hbox, FALSE, FALSE, 0);

	label = new_body_label (_("If you have been using the GNOME Midnight Commander\n"
				  "these settings move your desktop icons to Nautilus and\n"
				  "make Nautilus the default desktop.\n"));

	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

	checkbox = gtk_check_button_new_with_label (_("Use Nautilus to draw the desktop."));
887
	gtk_box_pack_start (GTK_BOX (main_box), checkbox, FALSE, FALSE, 0);
888
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), draw_desktop);
889
	gtk_signal_connect (GTK_OBJECT (checkbox), "toggled", GTK_SIGNAL_FUNC (transition_value_changed), &draw_desktop);
890
	draw_desktop_checkbox_widget = checkbox;
891

892
	checkbox = gtk_check_button_new_with_label (_("Move existing desktop icons to the Nautilus desktop."));
893
	gtk_box_pack_start (GTK_BOX (main_box), checkbox, FALSE, FALSE, 0);
894
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), transfer_gmc_icons);	
895 896
	gtk_signal_connect (GTK_OBJECT (checkbox), "toggled", GTK_SIGNAL_FUNC (transition_value_changed), &transfer_gmc_icons);

897 898 899
#if 0
	/* This option is currently disabled, per bugzilla.eazel.com 7557 */

900
	checkbox = gtk_check_button_new_with_label (_("Launch Nautilus when GNOME starts up."));
901
	gtk_box_pack_start (GTK_BOX (main_box), checkbox, FALSE, FALSE, 0);
902
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), add_to_session);
903
	gtk_signal_connect (GTK_OBJECT (checkbox), "toggled", GTK_SIGNAL_FUNC (transition_value_changed), &add_to_session);