nautilus-3.6.3/src/nautilus-mime-actions.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found nautilus-mime-actions.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
   1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
   2 
   3 /* nautilus-mime-actions.c - uri-specific versions of mime action functions
   4 
   5    Copyright (C) 2000, 2001 Eazel, Inc.
   6 
   7    The Gnome Library is free software; you can redistribute it and/or
   8    modify it under the terms of the GNU Library General Public License as
   9    published by the Free Software Foundation; either version 2 of the
  10    License, or (at your option) any later version.
  11 
  12    The Gnome Library is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15    Library General Public License for more details.
  16 
  17    You should have received a copy of the GNU Library General Public
  18    License along with the Gnome Library; see the file COPYING.LIB.  If not,
  19    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20    Boston, MA 02111-1307, USA.
  21 
  22    Authors: Maciej Stachowiak <mjs@eazel.com>
  23 */
  24 
  25 #include <config.h>
  26 
  27 #include "nautilus-mime-actions.h"
  28 
  29 #include "nautilus-window-slot.h"
  30 
  31 #include <eel/eel-glib-extensions.h>
  32 #include <eel/eel-stock-dialogs.h>
  33 #include <eel/eel-string.h>
  34 #include <glib/gi18n.h>
  35 #include <glib/gstdio.h>
  36 #include <string.h>
  37 #include <gdk/gdkx.h>
  38 
  39 #include <libnautilus-private/nautilus-file-attributes.h>
  40 #include <libnautilus-private/nautilus-file.h>
  41 #include <libnautilus-private/nautilus-file-operations.h>
  42 #include <libnautilus-private/nautilus-metadata.h>
  43 #include <libnautilus-private/nautilus-program-choosing.h>
  44 #include <libnautilus-private/nautilus-desktop-icon-file.h>
  45 #include <libnautilus-private/nautilus-global-preferences.h>
  46 #include <libnautilus-private/nautilus-signaller.h>
  47 
  48 #define DEBUG_FLAG NAUTILUS_DEBUG_MIME
  49 #include <libnautilus-private/nautilus-debug.h>
  50 
  51 typedef enum {
  52 	ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE,
  53 	ACTIVATION_ACTION_ASK,
  54 	ACTIVATION_ACTION_LAUNCH,
  55 	ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
  56 	ACTIVATION_ACTION_OPEN_IN_VIEW,
  57 	ACTIVATION_ACTION_OPEN_IN_APPLICATION,
  58 	ACTIVATION_ACTION_DO_NOTHING,
  59 } ActivationAction;
  60 
  61 typedef struct {
  62 	NautilusFile *file;
  63 	char *uri;
  64 } LaunchLocation;
  65 
  66 typedef struct {
  67 	GAppInfo *application;
  68 	GList *uris;
  69 } ApplicationLaunchParameters;
  70 
  71 typedef struct {
  72 	NautilusWindowSlot *slot;
  73 	gpointer window;
  74 	GtkWindow *parent_window;
  75 	GCancellable *cancellable;
  76 	GList *locations;
  77 	GList *mountables;
  78 	GList *start_mountables;
  79 	GList *not_mounted;
  80 	NautilusWindowOpenFlags flags;
  81 	char *timed_wait_prompt;
  82 	gboolean timed_wait_active;
  83 	NautilusFileListHandle *files_handle;
  84 	gboolean tried_mounting;
  85 	char *activation_directory;
  86 	gboolean user_confirmation;
  87 } ActivateParameters;
  88 
  89 /* Number of seconds until cancel dialog shows up */
  90 #define DELAY_UNTIL_CANCEL_MSECS 5000
  91 
  92 #define RESPONSE_RUN 1000
  93 #define RESPONSE_DISPLAY 1001
  94 #define RESPONSE_RUN_IN_TERMINAL 1002
  95 #define RESPONSE_MARK_TRUSTED 1003
  96 
  97 #define SILENT_WINDOW_OPEN_LIMIT 5
  98 #define SILENT_OPEN_LIMIT 5
  99 
 100 /* This number controls a maximum character count for a URL that is
 101  * displayed as part of a dialog. It's fairly arbitrary -- big enough
 102  * to allow most "normal" URIs to display in full, but small enough to
 103  * prevent the dialog from getting insanely wide.
 104  */
 105 #define MAX_URI_IN_DIALOG_LENGTH 60
 106 
 107 static void cancel_activate_callback                (gpointer            callback_data);
 108 static void activate_activation_uris_ready_callback (GList              *files,
 109 						     gpointer            callback_data);
 110 static void activation_mount_mountables             (ActivateParameters *parameters);
 111 static void activation_start_mountables             (ActivateParameters *parameters);
 112 static void activate_callback                       (GList              *files,
 113 						     gpointer            callback_data);
 114 static void activation_mount_not_mounted            (ActivateParameters *parameters);
 115 
 116 
 117 static void
 118 launch_location_free (LaunchLocation *location)
 119 {
 120 	nautilus_file_unref (location->file);
 121 	g_free (location->uri);
 122 	g_free (location);
 123 }
 124 
 125 static void
 126 launch_location_list_free (GList *list)
 127 {
 128 	g_list_foreach (list, (GFunc)launch_location_free, NULL);
 129 	g_list_free (list);
 130 }
 131 
 132 static GList *
 133 get_file_list_for_launch_locations (GList *locations)
 134 {
 135 	GList *files, *l;
 136 	LaunchLocation *location;
 137 
 138 	files = NULL;
 139 	for (l = locations; l != NULL; l = l->next) {
 140 		location = l->data;
 141 
 142 		files = g_list_prepend (files,
 143 					nautilus_file_ref (location->file));
 144 	}
 145 	return g_list_reverse (files);
 146 }
 147 
 148 
 149 static LaunchLocation *
 150 launch_location_from_file (NautilusFile *file)
 151 {
 152 	LaunchLocation *location;
 153 	location = g_new (LaunchLocation, 1);
 154 	location->file = nautilus_file_ref (file);
 155 	location->uri = nautilus_file_get_uri (file);
 156 	
 157 	return location;
 158 }
 159 
 160 static void
 161 launch_location_update_from_file (LaunchLocation *location,
 162 				  NautilusFile *file)
 163 {
 164 	nautilus_file_unref (location->file);
 165 	g_free (location->uri);
 166 	location->file = nautilus_file_ref (file);
 167 	location->uri = nautilus_file_get_uri (file);
 168 }
 169 
 170 static void
 171 launch_location_update_from_uri (LaunchLocation *location,
 172 				 const char *uri)
 173 {
 174 	nautilus_file_unref (location->file);
 175 	g_free (location->uri);
 176 	location->file = nautilus_file_get_by_uri (uri);
 177 	location->uri = g_strdup (uri);
 178 }
 179 
 180 static LaunchLocation *
 181 find_launch_location_for_file (GList *list,
 182 			       NautilusFile *file)
 183 {
 184 	LaunchLocation *location;
 185 	GList *l;
 186 
 187 	for (l = list; l != NULL; l = l->next) {
 188 		location = l->data;
 189 
 190 		if (location->file == file) {
 191 			return location;
 192 		}
 193 	}
 194 	return NULL;
 195 }
 196 
 197 static GList *
 198 launch_locations_from_file_list (GList *list)
 199 {
 200 	GList *new;
 201 
 202 	new = NULL;
 203 	while (list) {
 204 		new = g_list_prepend (new,
 205 				      launch_location_from_file (list->data));
 206 		list = list->next;
 207 	}
 208 	new = g_list_reverse (new);
 209 	return new;
 210 }
 211 
 212 static ApplicationLaunchParameters *
 213 application_launch_parameters_new (GAppInfo *application,
 214 			      	   GList *uris)
 215 {
 216 	ApplicationLaunchParameters *result;
 217 
 218 	result = g_new0 (ApplicationLaunchParameters, 1);
 219 	result->application = g_object_ref (application);
 220 	result->uris = eel_g_str_list_copy (uris);
 221 
 222 	return result;
 223 }
 224 
 225 static void
 226 application_launch_parameters_free (ApplicationLaunchParameters *parameters)
 227 {
 228 	g_object_unref (parameters->application);
 229 	g_list_free_full (parameters->uris, g_free);
 230 
 231 	g_free (parameters);
 232 }			      
 233 
 234 static GList*
 235 filter_nautilus_handler (GList *apps)
 236 {
 237 	GList *l, *next;
 238 	GAppInfo *application;
 239 	const char *id;
 240 
 241 	l = apps;
 242 	while (l != NULL) {
 243 		application = (GAppInfo *) l->data;
 244 		next = l->next;
 245 
 246 		id = g_app_info_get_id (application);
 247 		if (id != NULL &&
 248 		    strcmp (id,
 249 			    "nautilus.desktop") == 0) {
 250 			g_object_unref (application);
 251 			apps = g_list_delete_link (apps, l); 
 252 		}
 253 
 254 		l = next;
 255 	}
 256 
 257 	return apps;
 258 }
 259 
 260 static GList*
 261 filter_non_uri_apps (GList *apps,
 262 		     gboolean accept_files)
 263 {
 264 	GList *l, *next;
 265 	GAppInfo *app;
 266 
 267 	for (l = apps; l != NULL; l = next) {
 268 		gboolean support;
 269 
 270 		app = l->data;
 271 		next = l->next;
 272 		support = g_app_info_supports_uris (app);
 273 		if (accept_files) {
 274 			support |= g_app_info_supports_files (app);
 275 		}
 276 		if (!support) {
 277 			apps = g_list_delete_link (apps, l);
 278 			g_object_unref (app);
 279 		}
 280 	}
 281 	return apps;
 282 }
 283 
 284 static gboolean
 285 nautilus_mime_actions_check_if_required_attributes_ready (NautilusFile *file)
 286 {
 287 	NautilusFileAttributes attributes;
 288 	gboolean ready;
 289 
 290 	attributes = nautilus_mime_actions_get_required_file_attributes ();
 291 	ready = nautilus_file_check_if_ready (file, attributes);
 292 
 293 	return ready;
 294 }
 295 
 296 NautilusFileAttributes 
 297 nautilus_mime_actions_get_required_file_attributes (void)
 298 {
 299 	return NAUTILUS_FILE_ATTRIBUTE_INFO |
 300 		NAUTILUS_FILE_ATTRIBUTE_LINK_INFO;
 301 }
 302 
 303 static gboolean
 304 file_has_local_path (NautilusFile *file)
 305 {
 306 	GFile *location;
 307 	char *path;
 308 	gboolean res;
 309 
 310 	
 311 	/* Don't only check _is_native, because we want to support
 312 	   using the fuse path */
 313 	location = nautilus_file_get_location (file);
 314 	if (g_file_is_native (location)) {
 315 		res = TRUE;
 316 	} else {
 317 		path = g_file_get_path (location);
 318 		
 319 		res = path != NULL;
 320 		
 321 		g_free (path);
 322 	}
 323 	g_object_unref (location);
 324 	
 325 	return res;
 326 }
 327 
 328 GAppInfo *
 329 nautilus_mime_get_default_application_for_file (NautilusFile *file)
 330 {
 331 	GAppInfo *app;
 332 	char *mime_type;
 333 	char *uri_scheme;
 334 
 335 	if (!nautilus_mime_actions_check_if_required_attributes_ready (file)) {
 336 		return NULL;
 337 	}
 338 
 339 	mime_type = nautilus_file_get_mime_type (file);
 340 	app = g_app_info_get_default_for_type (mime_type, !file_has_local_path (file));
 341 	g_free (mime_type);
 342 
 343 	if (app == NULL) {
 344 		uri_scheme = nautilus_file_get_uri_scheme (file);
 345 		if (uri_scheme != NULL) {
 346 			app = g_app_info_get_default_for_uri_scheme (uri_scheme);
 347 			g_free (uri_scheme);
 348 		}
 349 	}
 350 	
 351 	return app;
 352 }
 353 
 354 static int
 355 file_compare_by_mime_type (NautilusFile *file_a,
 356 			   NautilusFile *file_b)
 357 {
 358 	char *mime_type_a, *mime_type_b;
 359 	int ret;
 360 	
 361 	mime_type_a = nautilus_file_get_mime_type (file_a);
 362 	mime_type_b = nautilus_file_get_mime_type (file_b);
 363 	
 364 	ret = strcmp (mime_type_a, mime_type_b);
 365 	
 366 	g_free (mime_type_a);
 367 	g_free (mime_type_b);
 368 	
 369 	return ret;
 370 }
 371 
 372 static int
 373 file_compare_by_parent_uri (NautilusFile *file_a,
 374 			    NautilusFile *file_b) {
 375 	char *parent_uri_a, *parent_uri_b;
 376 	int ret;
 377 
 378 	parent_uri_a = nautilus_file_get_parent_uri (file_a);
 379 	parent_uri_b = nautilus_file_get_parent_uri (file_b);
 380 
 381 	ret = strcmp (parent_uri_a, parent_uri_b);
 382 
 383 	g_free (parent_uri_a);
 384 	g_free (parent_uri_b);
 385 
 386 	return ret;
 387 }
 388 
 389 static int
 390 application_compare_by_name (const GAppInfo *app_a,
 391 			     const GAppInfo *app_b)
 392 {
 393 	return g_utf8_collate (g_app_info_get_display_name ((GAppInfo *)app_a),
 394 			       g_app_info_get_display_name ((GAppInfo *)app_b));
 395 }
 396 
 397 static int
 398 application_compare_by_id (const GAppInfo *app_a,
 399 			   const GAppInfo *app_b)
 400 {
 401 	const char *id_a, *id_b;
 402 
 403 	id_a = g_app_info_get_id ((GAppInfo *)app_a);
 404 	id_b = g_app_info_get_id ((GAppInfo *)app_b);
 405 
 406 	if (id_a == NULL && id_b == NULL) {
 407 		if (g_app_info_equal ((GAppInfo *)app_a, (GAppInfo *)app_b)) {
 408 			return 0;
 409 		}
 410 		if ((gsize)app_a < (gsize) app_b) {
 411 			return -1;
 412 		}
 413 		return 1;
 414 	}
 415 
 416 	if (id_a == NULL) {
 417 		return -1;
 418 	}
 419 	
 420 	if (id_b == NULL) {
 421 		return 1;
 422 	}
 423 	
 424 	
 425 	return strcmp (id_a, id_b);
 426 }
 427 
 428 GList *
 429 nautilus_mime_get_applications_for_file (NautilusFile *file)
 430 {
 431 	char *mime_type;
 432 	char *uri_scheme;
 433 	GList *result;
 434 	GAppInfo *uri_handler;
 435 
 436 	if (!nautilus_mime_actions_check_if_required_attributes_ready (file)) {
 437 		return NULL;
 438 	}
 439 	mime_type = nautilus_file_get_mime_type (file);
 440 	result = g_app_info_get_all_for_type (mime_type);
 441 
 442 	uri_scheme = nautilus_file_get_uri_scheme (file);
 443 	if (uri_scheme != NULL) {
 444 		uri_handler = g_app_info_get_default_for_uri_scheme (uri_scheme);
 445 		if (uri_handler) {
 446 			result = g_list_prepend (result, uri_handler);
 447 		}
 448 		g_free (uri_scheme);
 449 	}
 450 
 451 	/* Filter out non-uri supporting apps */
 452 	result = filter_non_uri_apps (result, file_has_local_path (file));
 453 
 454 	result = g_list_sort (result, (GCompareFunc) application_compare_by_name);
 455 	g_free (mime_type);
 456 
 457 	return filter_nautilus_handler (result);
 458 }
 459 
 460 GAppInfo *
 461 nautilus_mime_get_default_application_for_files (GList *files)
 462 {
 463 	GList *l, *sorted_files;
 464 	NautilusFile *file;
 465 	GAppInfo *app, *one_app;
 466 
 467 	g_assert (files != NULL);
 468 
 469 	sorted_files = g_list_sort (g_list_copy (files), (GCompareFunc) file_compare_by_mime_type);
 470 
 471 	app = NULL;
 472 	for (l = sorted_files; l != NULL; l = l->next) {
 473 		file = l->data;
 474 
 475 		if (l->prev &&
 476 		    file_compare_by_mime_type (file, l->prev->data) == 0 &&
 477 		    file_compare_by_parent_uri (file, l->prev->data) == 0) {
 478 			continue;
 479 		}
 480 
 481 		one_app = nautilus_mime_get_default_application_for_file (file);
 482 		if (one_app == NULL || (app != NULL && !g_app_info_equal (app, one_app))) {
 483 			if (app) {
 484 				g_object_unref (app);
 485 			}
 486 			if (one_app) {
 487 				g_object_unref (one_app);
 488 			}
 489 			app = NULL;
 490 			break;
 491 		}
 492 
 493 		if (app == NULL) {
 494 			app = one_app;
 495 		} else {
 496 			g_object_unref (one_app);
 497 		}
 498 	}
 499 
 500 	g_list_free (sorted_files);
 501 
 502 	return app;
 503 }
 504 
 505 /* returns an intersection of two mime application lists,
 506  * and returns a new list, freeing a, b and all applications
 507  * that are not in the intersection set.
 508  * The lists are assumed to be pre-sorted by their IDs */
 509 static GList *
 510 intersect_application_lists (GList *a,
 511 			     GList *b)
 512 {
 513 	GList *l, *m;
 514 	GList *ret;
 515 	GAppInfo *a_app, *b_app;
 516 	int cmp;
 517 
 518 	ret = NULL;
 519 
 520 	l = a;
 521 	m = b;
 522 
 523 	while (l != NULL && m != NULL) {
 524 		a_app = (GAppInfo *) l->data;
 525 		b_app = (GAppInfo *) m->data;
 526 
 527 		cmp = application_compare_by_id (a_app, b_app);
 528 		if (cmp > 0) {
 529 			g_object_unref (b_app);
 530 			m = m->next;
 531 		} else if (cmp < 0) {
 532 			g_object_unref (a_app);
 533 			l = l->next;
 534 		} else {
 535 			g_object_unref (b_app);
 536 			ret = g_list_prepend (ret, a_app);
 537 			l = l->next;
 538 			m = m->next;
 539 		}
 540 	}
 541 
 542 	g_list_foreach (l, (GFunc) g_object_unref, NULL);
 543 	g_list_foreach (m, (GFunc) g_object_unref, NULL);
 544 
 545 	g_list_free (a);
 546 	g_list_free (b);
 547 
 548 	return g_list_reverse (ret);
 549 }
 550 
 551 GList *
 552 nautilus_mime_get_applications_for_files (GList *files)
 553 {
 554 	GList *l, *sorted_files;
 555 	NautilusFile *file;
 556 	GList *one_ret, *ret;
 557 
 558 	g_assert (files != NULL);
 559 
 560 	sorted_files = g_list_sort (g_list_copy (files), (GCompareFunc) file_compare_by_mime_type);
 561 
 562 	ret = NULL;
 563 	for (l = sorted_files; l != NULL; l = l->next) {
 564 		file = l->data;
 565 
 566 		if (l->prev &&
 567 		    file_compare_by_mime_type (file, l->prev->data) == 0 &&
 568 		    file_compare_by_parent_uri (file, l->prev->data) == 0) {
 569 			continue;
 570 		}
 571 
 572 		one_ret = nautilus_mime_get_applications_for_file (file);
 573 		one_ret = g_list_sort (one_ret, (GCompareFunc) application_compare_by_id);
 574 		if (ret != NULL) {
 575 			ret = intersect_application_lists (ret, one_ret);
 576 		} else {
 577 			ret = one_ret;
 578 		}
 579 
 580 		if (ret == NULL) {
 581 			break;
 582 		}
 583 	}
 584 
 585 	g_list_free (sorted_files);
 586 
 587 	ret = g_list_sort (ret, (GCompareFunc) application_compare_by_name);
 588 	
 589 	return ret;
 590 }
 591 
 592 static void
 593 trash_or_delete_files (GtkWindow *parent_window,
 594 		       const GList *files,
 595 		       gboolean delete_if_all_already_in_trash)
 596 {
 597 	GList *locations;
 598 	const GList *node;
 599 	
 600 	locations = NULL;
 601 	for (node = files; node != NULL; node = node->next) {
 602 		locations = g_list_prepend (locations,
 603 					    nautilus_file_get_location ((NautilusFile *) node->data));
 604 	}
 605 	
 606 	locations = g_list_reverse (locations);
 607 
 608 	nautilus_file_operations_trash_or_delete (locations,
 609 						  parent_window,
 610 						  NULL, NULL);
 611 	g_list_free_full (locations, g_object_unref);
 612 }
 613 
 614 static void
 615 report_broken_symbolic_link (GtkWindow *parent_window, NautilusFile *file)
 616 {
 617 	char *target_path;
 618 	char *display_name;
 619 	char *prompt;
 620 	char *detail;
 621 	GtkDialog *dialog;
 622 	GList file_as_list;
 623 	int response;
 624 	gboolean can_trash;
 625 
 626 	g_assert (nautilus_file_is_broken_symbolic_link (file));
 627 
 628 	display_name = nautilus_file_get_display_name (file);
 629 	can_trash = nautilus_file_can_trash (file) && !nautilus_file_is_in_trash (file);
 630 
 631 	if (can_trash) {
 632 		prompt = g_strdup_printf (_("The link ā€œ%sā€ is broken. Move it to Trash?"), display_name);
 633 	} else {
 634 		prompt = g_strdup_printf (_("The link ā€œ%sā€ is broken."), display_name);
 635 	}
 636 	g_free (display_name);
 637 
 638 	target_path = nautilus_file_get_symbolic_link_target_path (file);
 639 	if (target_path == NULL) {
 640 		detail = g_strdup (_("This link cannot be used because it has no target."));
 641 	} else {
 642 		detail = g_strdup_printf (_("This link cannot be used because its target "
 643 					    "ā€œ%sā€ doesn't exist."), target_path);
 644 	}
 645 	
 646 	if (!can_trash) {
 647 		eel_run_simple_dialog (GTK_WIDGET (parent_window), FALSE, GTK_MESSAGE_WARNING,
 648 				       prompt, detail, GTK_STOCK_CANCEL, NULL);
 649 		goto out;
 650 	}
 651 
 652 	dialog = eel_show_yes_no_dialog (prompt, detail, _("Mo_ve to Trash"), GTK_STOCK_CANCEL,
 653 					 parent_window);
 654 
 655 	gtk_dialog_set_default_response (dialog, GTK_RESPONSE_CANCEL);
 656 
 657 	/* Make this modal to avoid problems with reffing the view & file
 658 	 * to keep them around in case the view changes, which would then
 659 	 * cause the old view not to be destroyed, which would cause its
 660 	 * merged Bonobo items not to be un-merged. Maybe we need to unmerge
 661 	 * explicitly when disconnecting views instead of relying on the
 662 	 * unmerge in Destroy. But since BonoboUIHandler is probably going
 663 	 * to change wildly, I don't want to mess with this now.
 664 	 */
 665 
 666 	response = gtk_dialog_run (dialog);
 667 	gtk_widget_destroy (GTK_WIDGET (dialog));
 668 
 669 	if (response == GTK_RESPONSE_YES) {
 670 		file_as_list.data = file;
 671 		file_as_list.next = NULL;
 672 		file_as_list.prev = NULL;
 673 	        trash_or_delete_files (parent_window, &file_as_list, TRUE);
 674 	}
 675 
 676 out:
 677 	g_free (prompt);
 678 	g_free (target_path);
 679 	g_free (detail);
 680 }
 681 
 682 static ActivationAction
 683 get_executable_text_file_action (GtkWindow *parent_window, NautilusFile *file)
 684 {
 685 	GtkDialog *dialog;
 686 	char *file_name;
 687 	char *prompt;
 688 	char *detail;
 689 	int preferences_value;
 690 	int response;
 691 
 692 	g_assert (nautilus_file_contains_text (file));
 693 
 694 	preferences_value = g_settings_get_enum	(nautilus_preferences,
 695 						 NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
 696 	switch (preferences_value) {
 697 	case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
 698 		return ACTIVATION_ACTION_LAUNCH;
 699 	case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
 700 		return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
 701 	case NAUTILUS_EXECUTABLE_TEXT_ASK:
 702 		break;
 703 	default:
 704 		/* Complain non-fatally, since preference data can't be trusted */
 705 		g_warning ("Unknown value %d for NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION",
 706 			   preferences_value);
 707 		
 708 	}
 709 
 710 
 711 	file_name = nautilus_file_get_display_name (file);
 712 	prompt = g_strdup_printf (_("Do you want to run ā€œ%sā€, or display its contents?"), 
 713 	                            file_name);
 714 	detail = g_strdup_printf (_("ā€œ%sā€ is an executable text file."),
 715 				    file_name);
 716 	g_free (file_name);
 717 
 718 	dialog = eel_create_question_dialog (prompt,
 719 					     detail,
 720 					     _("Run in _Terminal"), RESPONSE_RUN_IN_TERMINAL,
 721      					     _("_Display"), RESPONSE_DISPLAY,
 722 					     parent_window);
 723 	gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
 724 	gtk_dialog_add_button (dialog, _("_Run"), RESPONSE_RUN);
 725 	gtk_dialog_set_default_response (dialog, GTK_RESPONSE_CANCEL);
 726 	gtk_widget_show (GTK_WIDGET (dialog));
 727 	
 728 	g_free (prompt);
 729 	g_free (detail);
 730 
 731 	response = gtk_dialog_run (dialog);
 732 	gtk_widget_destroy (GTK_WIDGET (dialog));
 733 	
 734 	switch (response) {
 735 	case RESPONSE_RUN:
 736 		return ACTIVATION_ACTION_LAUNCH;
 737 	case RESPONSE_RUN_IN_TERMINAL:
 738 		return ACTIVATION_ACTION_LAUNCH_IN_TERMINAL;
 739 	case RESPONSE_DISPLAY:
 740 		return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
 741 	default:
 742 		return ACTIVATION_ACTION_DO_NOTHING;
 743 	}
 744 }
 745 
 746 static ActivationAction
 747 get_default_executable_text_file_action (void)
 748 {
 749 	int preferences_value;
 750 
 751 	preferences_value = g_settings_get_enum	(nautilus_preferences,
 752 						 NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
 753 	switch (preferences_value) {
 754 	case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
 755 		return ACTIVATION_ACTION_LAUNCH;
 756 	case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
 757 		return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
 758 	case NAUTILUS_EXECUTABLE_TEXT_ASK:
 759 	default:
 760 		return ACTIVATION_ACTION_ASK;
 761 	}
 762 }
 763 
 764 gboolean
 765 nautilus_mime_file_opens_in_view (NautilusFile *file)
 766 {
 767   return (nautilus_file_is_directory (file) ||
 768 	  NAUTILUS_IS_DESKTOP_ICON_FILE (file));
 769 }
 770 
 771 static ActivationAction
 772 get_activation_action (NautilusFile *file)
 773 {
 774 	ActivationAction action;
 775 	char *activation_uri;
 776 
 777 	if (nautilus_file_is_nautilus_link (file)) {
 778 		return ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE;
 779 	}
 780 	
 781 	activation_uri = nautilus_file_get_activation_uri (file);
 782 	if (activation_uri == NULL) {
 783 		activation_uri = nautilus_file_get_uri (file);
 784 	}
 785 
 786 	action = ACTIVATION_ACTION_DO_NOTHING;
 787 	if (nautilus_file_is_launchable (file)) {
 788 		char *executable_path;
 789 		
 790 		action = ACTIVATION_ACTION_LAUNCH;
 791 		
 792 		executable_path = g_filename_from_uri (activation_uri, NULL, NULL);
 793 		if (!executable_path) {
 794 			action = ACTIVATION_ACTION_DO_NOTHING;
 795 		} else if (nautilus_file_contains_text (file)) {
 796 			action = get_default_executable_text_file_action ();
 797 		}
 798 		g_free (executable_path);
 799 	} 
 800 
 801 	if (action == ACTIVATION_ACTION_DO_NOTHING) {
 802 		if (nautilus_mime_file_opens_in_view (file)) {
 803 			action = ACTIVATION_ACTION_OPEN_IN_VIEW;
 804 		} else {
 805 			action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
 806 		}
 807 	}
 808 	g_free (activation_uri);
 809 
 810 	return action;
 811 }
 812 
 813 gboolean
 814 nautilus_mime_file_opens_in_external_app (NautilusFile *file)
 815 {
 816   ActivationAction activation_action;
 817   
 818   activation_action = get_activation_action (file);
 819   
 820   return (activation_action == ACTIVATION_ACTION_OPEN_IN_APPLICATION);
 821 }
 822 
 823 
 824 static unsigned int
 825 mime_application_hash (GAppInfo *app)
 826 {
 827 	const char *id;
 828 
 829 	id = g_app_info_get_id (app);
 830 
 831 	if (id == NULL) {
 832 		return GPOINTER_TO_UINT(app);
 833 	}
 834 
 835 	return g_str_hash (id);
 836 }
 837 
 838 static void
 839 list_to_parameters_foreach (GAppInfo *application,
 840 			    GList *uris,
 841 			    GList **ret)
 842 {
 843 	ApplicationLaunchParameters *parameters;
 844 
 845 	uris = g_list_reverse (uris);
 846 
 847 	parameters = application_launch_parameters_new
 848 		(application, uris);
 849 	*ret = g_list_prepend (*ret, parameters);
 850 }
 851 
 852 
 853 /**
 854  * make_activation_parameters
 855  *
 856  * Construct a list of ApplicationLaunchParameters from a list of NautilusFiles,
 857  * where files that have the same default application are put into the same
 858  * launch parameter, and others are put into the unhandled_files list.
 859  *
 860  * @files: Files to use for construction.
 861  * @unhandled_files: Files without any default application will be put here.
 862  * 
 863  * Return value: Newly allocated list of ApplicationLaunchParameters.
 864  **/
 865 static GList *
 866 make_activation_parameters (GList *uris,
 867 			    GList **unhandled_uris)
 868 {
 869 	GList *ret, *l, *app_uris;
 870 	NautilusFile *file;
 871 	GAppInfo *app, *old_app;
 872 	GHashTable *app_table;
 873 	char *uri;
 874 
 875 	ret = NULL;
 876 	*unhandled_uris = NULL;
 877 
 878 	app_table = g_hash_table_new_full
 879 		((GHashFunc) mime_application_hash,
 880 		 (GEqualFunc) g_app_info_equal,
 881 		 (GDestroyNotify) g_object_unref,
 882 		 (GDestroyNotify) g_list_free);
 883 
 884 	for (l = uris; l != NULL; l = l->next) {
 885 		uri = l->data;
 886 		file = nautilus_file_get_by_uri (uri);
 887 
 888 		app = nautilus_mime_get_default_application_for_file (file);
 889 		if (app != NULL) {
 890 			app_uris = NULL;
 891 
 892 			if (g_hash_table_lookup_extended (app_table, app,
 893 							  (gpointer *) &old_app,
 894 							  (gpointer *) &app_uris)) {
 895 				g_hash_table_steal (app_table, old_app);
 896 
 897 				app_uris = g_list_prepend (app_uris, uri);
 898 
 899 				g_object_unref (app);
 900 				app = old_app;
 901 			} else {
 902 				app_uris = g_list_prepend (NULL, uri);
 903 			}
 904 
 905 			g_hash_table_insert (app_table, app, app_uris);
 906 		} else {
 907 			*unhandled_uris = g_list_prepend (*unhandled_uris, uri);
 908 		}
 909 		nautilus_file_unref (file);
 910 	}
 911 
 912 	g_hash_table_foreach (app_table,
 913 			      (GHFunc) list_to_parameters_foreach,
 914 			      &ret);
 915 
 916 	g_hash_table_destroy (app_table);
 917 
 918 	*unhandled_uris = g_list_reverse (*unhandled_uris);
 919 
 920 	return g_list_reverse (ret);
 921 }
 922 
 923 static gboolean
 924 file_was_cancelled (NautilusFile *file)
 925 {
 926 	GError *error;
 927 	
 928 	error = nautilus_file_get_file_info_error (file);
 929 	return
 930 		error != NULL &&
 931 		error->domain == G_IO_ERROR &&
 932 		error->code == G_IO_ERROR_CANCELLED;
 933 }
 934 
 935 static gboolean
 936 file_was_not_mounted (NautilusFile *file)
 937 {
 938 	GError *error;
 939 	
 940 	error = nautilus_file_get_file_info_error (file);
 941 	return
 942 		error != NULL &&
 943 		error->domain == G_IO_ERROR &&
 944 		error->code == G_IO_ERROR_NOT_MOUNTED;
 945 }
 946 
 947 static void
 948 activation_parameters_free (ActivateParameters *parameters)
 949 {
 950 	if (parameters->timed_wait_active) {
 951 		eel_timed_wait_stop (cancel_activate_callback, parameters);
 952 	}
 953 	
 954 	if (parameters->slot) {
 955 		g_object_remove_weak_pointer (G_OBJECT (parameters->slot), (gpointer *)&parameters->slot);
 956 	}
 957 	if (parameters->parent_window) {
 958 		g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
 959 	}
 960 	g_object_unref (parameters->cancellable);
 961 	launch_location_list_free (parameters->locations);
 962 	nautilus_file_list_free (parameters->mountables);
 963 	nautilus_file_list_free (parameters->start_mountables);
 964 	nautilus_file_list_free (parameters->not_mounted);
 965 	g_free (parameters->activation_directory);
 966 	g_free (parameters->timed_wait_prompt);
 967 	g_assert (parameters->files_handle == NULL);
 968 	g_free (parameters);
 969 }
 970 
 971 static void
 972 cancel_activate_callback (gpointer callback_data)
 973 {
 974 	ActivateParameters *parameters = callback_data;
 975 
 976 	parameters->timed_wait_active = FALSE;
 977 	
 978 	g_cancellable_cancel (parameters->cancellable);
 979 
 980 	if (parameters->files_handle) {
 981 		nautilus_file_list_cancel_call_when_ready (parameters->files_handle);
 982 		parameters->files_handle = NULL;
 983 		activation_parameters_free (parameters);
 984 	}
 985 }
 986 
 987 static void
 988 activation_start_timed_cancel (ActivateParameters *parameters)
 989 {
 990 	parameters->timed_wait_active = TRUE;
 991 	eel_timed_wait_start_with_duration
 992 		(DELAY_UNTIL_CANCEL_MSECS,
 993 		 cancel_activate_callback,
 994 		 parameters,
 995 		 parameters->timed_wait_prompt,
 996 		 parameters->parent_window);
 997 }
 998 
 999 static void
1000 pause_activation_timed_cancel (ActivateParameters *parameters)
1001 {
1002 	if (parameters->timed_wait_active) {
1003 		eel_timed_wait_stop (cancel_activate_callback, parameters);
1004 		parameters->timed_wait_active = FALSE;
1005 	}
1006 }
1007 
1008 static void
1009 unpause_activation_timed_cancel (ActivateParameters *parameters)
1010 {
1011 	if (!parameters->timed_wait_active) {
1012 		activation_start_timed_cancel (parameters);
1013 	}
1014 }
1015 
1016 
1017 static void
1018 activate_mount_op_active (GtkMountOperation *operation,
1019 			  GParamSpec *pspec,
1020 			  ActivateParameters *parameters)
1021 {
1022 	gboolean is_active;
1023 
1024 	g_object_get (operation, "is-showing", &is_active, NULL);
1025 
1026 	if (is_active) {
1027 		pause_activation_timed_cancel (parameters);
1028 	} else {
1029 		unpause_activation_timed_cancel (parameters);
1030 	}
1031 }
1032 
1033 static gboolean
1034 confirm_multiple_windows (GtkWindow *parent_window,
1035 			  int count,
1036 			  gboolean use_tabs)
1037 {
1038 	GtkDialog *dialog;
1039 	char *prompt;
1040 	char *detail;
1041 	int response;
1042 
1043 	if (count <= SILENT_WINDOW_OPEN_LIMIT) {
1044 		return TRUE;
1045 	}
1046 
1047 	prompt = _("Are you sure you want to open all files?");
1048 	if (use_tabs) {
1049 		detail = g_strdup_printf (ngettext("This will open %d separate tab.",
1050 						   "This will open %d separate tabs.", count), count);
1051 	} else {
1052 		detail = g_strdup_printf (ngettext("This will open %d separate window.",
1053 						   "This will open %d separate windows.", count), count);
1054 	}
1055 	dialog = eel_show_yes_no_dialog (prompt, detail, 
1056 					 GTK_STOCK_OK, GTK_STOCK_CANCEL,
1057 					 parent_window);
1058 	g_free (detail);
1059 
1060 	response = gtk_dialog_run (dialog);
1061 	gtk_widget_destroy (GTK_WIDGET (dialog));
1062 
1063 	return response == GTK_RESPONSE_YES;
1064 }
1065 
1066 typedef struct {
1067 	NautilusWindowSlot *slot;
1068 	GtkWindow *parent_window;
1069 	NautilusFile *file;
1070 	GList *files;
1071 	NautilusWindowOpenFlags flags;
1072 	char *activation_directory;
1073 	gboolean user_confirmation;
1074 	char *uri;
1075 	GDBusProxy *proxy;
1076 	GtkWidget *dialog;
1077 } ActivateParametersInstall;
1078 
1079 static void
1080 activate_parameters_install_free (ActivateParametersInstall *parameters_install)
1081 {
1082 	if (parameters_install->slot) {
1083 		g_object_remove_weak_pointer (G_OBJECT (parameters_install->slot), (gpointer *)&parameters_install->slot);
1084 	}
1085 	if (parameters_install->parent_window) {
1086 		g_object_remove_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *)&parameters_install->parent_window);
1087 	}
1088 
1089 	if (parameters_install->proxy != NULL) {
1090 	        g_object_unref (parameters_install->proxy);
1091 	}
1092 
1093 	nautilus_file_unref (parameters_install->file);
1094 	nautilus_file_list_free (parameters_install->files);
1095 	g_free (parameters_install->activation_directory);
1096 	g_free (parameters_install->uri);
1097 	g_free (parameters_install);
1098 }
1099 
1100 static char *
1101 get_application_no_mime_type_handler_message (NautilusFile *file, char *uri)
1102 {
1103 	char *uri_for_display;
1104 	char *name;
1105 	char *error_message;
1106 
1107 	name = nautilus_file_get_display_name (file);
1108 
1109 	/* Truncate the URI so it doesn't get insanely wide. Note that even
1110 	 * though the dialog uses wrapped text, if the URI doesn't contain
1111 	 * white space then the text-wrapping code is too stupid to wrap it.
1112 	 */
1113 	uri_for_display = eel_str_middle_truncate (name, MAX_URI_IN_DIALOG_LENGTH);
1114 	error_message = g_strdup_printf (_("Could not display ā€œ%sā€."), uri_for_display);
1115 	g_free (uri_for_display);
1116 	g_free (name);
1117 
1118 	return error_message;
1119 }
1120 
1121 static void
1122 open_with_response_cb (GtkDialog *dialog,
1123 		       gint response_id,
1124 		       gpointer user_data)
1125 {
1126 	GtkWindow *parent_window;
1127 	NautilusFile *file;
1128 	GList files;
1129 	GAppInfo *info;
1130 	ActivateParametersInstall *parameters = user_data;
1131 	
1132 	if (response_id != GTK_RESPONSE_OK) {
1133 		gtk_widget_destroy (GTK_WIDGET (dialog));
1134 		return;
1135 	}
1136 
1137 	parent_window = parameters->parent_window;
1138 	file = g_object_get_data (G_OBJECT (dialog), "mime-action:file");
1139 	info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
1140 
1141 	gtk_widget_destroy (GTK_WIDGET (dialog));
1142 
1143 	g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
1144 
1145 	files.next = NULL;
1146 	files.prev = NULL;
1147 	files.data = file;
1148 	nautilus_launch_application (info, &files, parent_window);
1149 
1150 	g_object_unref (info);
1151 
1152 	activate_parameters_install_free (parameters);
1153 }
1154 
1155 static void
1156 choose_program (GtkDialog *message_dialog, int response, gpointer callback_data)
1157 {
1158 	GtkWidget *dialog;
1159 	NautilusFile *file;
1160 	GFile *location;
1161 	ActivateParametersInstall *parameters = callback_data;
1162 
1163 	if (response != GTK_RESPONSE_ACCEPT){
1164 		gtk_widget_destroy (GTK_WIDGET (message_dialog));
1165 		activate_parameters_install_free (parameters);
1166 		return;
1167 	}
1168 
1169 	file = g_object_get_data (G_OBJECT (message_dialog), "mime-action:file");
1170 
1171 	g_assert (NAUTILUS_IS_FILE (file));
1172 
1173 	location = nautilus_file_get_location (file);
1174 	nautilus_file_ref (file);
1175 
1176 	/* Destroy the message dialog after ref:ing the file */
1177 	gtk_widget_destroy (GTK_WIDGET (message_dialog));
1178 
1179 	dialog = gtk_app_chooser_dialog_new (parameters->parent_window,
1180 					     0, location);
1181 	g_object_set_data_full (G_OBJECT (dialog), 
1182 				"mime-action:file",
1183 				nautilus_file_ref (file),
1184 				(GDestroyNotify)nautilus_file_unref);
1185 
1186 	gtk_widget_show (dialog);
1187 
1188 	g_signal_connect (dialog, 
1189 			  "response", 
1190 			  G_CALLBACK (open_with_response_cb),
1191 			  parameters);
1192 
1193 	g_object_unref (location);
1194 	nautilus_file_unref (file);	
1195 }
1196 
1197 static void
1198 show_unhandled_type_error (ActivateParametersInstall *parameters)
1199 {
1200 	GtkWidget *dialog;
1201 
1202 	char *mime_type = nautilus_file_get_mime_type (parameters->file);
1203 	char *error_message = get_application_no_mime_type_handler_message (parameters->file, parameters->uri);
1204 	if (g_content_type_is_unknown (mime_type)) {
1205 		dialog = gtk_message_dialog_new (parameters->parent_window,
1206 						 GTK_DIALOG_DESTROY_WITH_PARENT,
1207 						 GTK_MESSAGE_ERROR,
1208 						 0,
1209 						 NULL);
1210 		g_object_set (dialog,
1211 			      "text", error_message,
1212 			      "secondary-text", _("The file is of an unknown type"),
1213 			      NULL);
1214 	} else {
1215 		char *text;
1216 		text = g_strdup_printf (_("There is no application installed for ā€œ%sā€ files"), g_content_type_get_description (mime_type));
1217 
1218 		dialog = gtk_message_dialog_new (parameters->parent_window,
1219 						 GTK_DIALOG_DESTROY_WITH_PARENT,
1220 						 GTK_MESSAGE_ERROR,
1221 						 0,
1222 						 NULL);
1223 		g_object_set (dialog,
1224 			      "text", error_message,
1225 			      "secondary-text", text,
1226 			      NULL);
1227 
1228 		g_free (text);
1229 	}
1230 
1231 	gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Select Application"), GTK_RESPONSE_ACCEPT);
1232 
1233 	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);
1234 
1235 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
1236 
1237 	g_object_set_data_full (G_OBJECT (dialog), 
1238 				"mime-action:file",
1239 				nautilus_file_ref (parameters->file),
1240 				(GDestroyNotify)nautilus_file_unref);
1241 
1242 	gtk_widget_show (GTK_WIDGET (dialog));
1243 	
1244 	g_signal_connect (dialog, "response",
1245 			  G_CALLBACK (choose_program), parameters);
1246 
1247 	g_free (error_message);
1248 	g_free (mime_type);
1249 }
1250 
1251 static void
1252 search_for_application_dbus_call_notify_cb (GDBusProxy   *proxy,
1253 					    GAsyncResult *result,
1254 					    gpointer      user_data)
1255 {
1256 	ActivateParametersInstall *parameters_install = user_data;
1257 	GVariant *variant;
1258 	GError *error = NULL;
1259 
1260 	variant = g_dbus_proxy_call_finish (proxy, result, &error);
1261 	if (variant == NULL) {
1262 		if (!g_dbus_error_is_remote_error (error) ||
1263 		    g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Failed") == 0) {
1264 			    char *message;
1265 
1266 			    message = g_strdup_printf ("%s\n%s",
1267 						       _("There was an internal error trying to search for applications:"),
1268 						       error->message);
1269 			    eel_show_error_dialog (_("Unable to search for application"), message,
1270 			                           parameters_install->parent_window);
1271 			    g_free (message);
1272 		    }
1273 
1274 		g_error_free (error);
1275 		activate_parameters_install_free (parameters_install);
1276 		return;
1277 	}
1278 
1279 	g_variant_unref (variant);
1280 
1281 	/* activate the file again */
1282 	nautilus_mime_activate_files (parameters_install->parent_window,
1283 	                              parameters_install->slot,
1284 	                              parameters_install->files,
1285 	                              parameters_install->activation_directory,
1286 	                              parameters_install->flags,
1287 	                              parameters_install->user_confirmation);
1288 
1289 	activate_parameters_install_free (parameters_install);
1290 }
1291 
1292 static void
1293 search_for_application_mime_type (ActivateParametersInstall *parameters_install, const gchar *mime_type)
1294 {
1295 	GdkWindow *window;
1296 	guint xid = 0;
1297 	const char *mime_types[2];
1298 
1299 	g_assert (parameters_install->proxy != NULL);	
1300 
1301 	/* get XID from parent window */
1302 	window = gtk_widget_get_window (GTK_WIDGET (parameters_install->parent_window));
1303 	if (window != NULL) {
1304 		xid = GDK_WINDOW_XID (window);
1305 	}
1306 
1307 	mime_types[0] = mime_type;
1308 	mime_types[1] = NULL;
1309 
1310 	g_dbus_proxy_call (parameters_install->proxy,
1311 			   "InstallMimeTypes",
1312 			   g_variant_new ("(u^ass)",
1313 					  xid,
1314 					  mime_types,
1315 					  "hide-confirm-search"),
1316 			   G_DBUS_CALL_FLAGS_NONE,
1317 			   G_MAXINT /* no timeout */,
1318 			   NULL /* cancellable */,
1319 			   (GAsyncReadyCallback) search_for_application_dbus_call_notify_cb,
1320 			   parameters_install);
1321 
1322 	DEBUG ("InstallMimeType method invoked for %s", mime_type);
1323 }
1324 
1325 static void
1326 application_unhandled_file_install (GtkDialog *dialog,
1327                                     gint response_id,
1328                                     ActivateParametersInstall *parameters_install)
1329 {
1330 	char *mime_type;
1331 
1332 	gtk_widget_destroy (GTK_WIDGET (dialog));
1333 	parameters_install->dialog = NULL;
1334 
1335 	if (response_id == GTK_RESPONSE_YES) {
1336 		mime_type = nautilus_file_get_mime_type (parameters_install->file);
1337 		search_for_application_mime_type (parameters_install, mime_type);
1338 		g_free (mime_type);
1339 	} else {
1340 		/* free as we're not going to get the async dbus callback */
1341 		activate_parameters_install_free (parameters_install);
1342 	}
1343 }
1344 
1345 static gboolean
1346 delete_cb (GtkDialog *dialog)
1347 {
1348 	gtk_dialog_response (dialog, GTK_RESPONSE_DELETE_EVENT);
1349 	return TRUE;
1350 }
1351 
1352 static void
1353 pk_proxy_appeared_cb (GObject *source,
1354 		      GAsyncResult *res,
1355 		      gpointer user_data)
1356 {
1357         ActivateParametersInstall *parameters_install = user_data;
1358 	char *mime_type;
1359 	char *error_message;
1360 	GtkWidget *dialog;
1361         GDBusProxy *proxy;
1362 	GError *error = NULL;
1363 
1364 	proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
1365 
1366 	if (error != NULL) {
1367 		g_warning ("Couldn't call Modify on the PackageKit interface: %s",
1368 			   error->message);
1369 		g_error_free (error);
1370 
1371 		/* show an unhelpful dialog */
1372 		show_unhandled_type_error (parameters_install);
1373 		/* The callback wasn't started, so we have to free the parameters */
1374 		activate_parameters_install_free (parameters_install);
1375 
1376 		return;
1377 	}
1378 
1379 	mime_type = nautilus_file_get_mime_type (parameters_install->file);
1380 	error_message = get_application_no_mime_type_handler_message (parameters_install->file,
1381 	                                                              parameters_install->uri);
1382 	/* use a custom dialog to prompt the user to install new software */
1383 	dialog = gtk_message_dialog_new (parameters_install->parent_window, 0,
1384 	                                 GTK_MESSAGE_ERROR,
1385 	                                 GTK_BUTTONS_YES_NO,
1386 	                                 "%s", error_message);
1387 	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1388 	                                          _("There is no application installed for ā€œ%sā€ files.\n"
1389 	                                            "Do you want to search for an application to open this file?"),
1390 	                                          g_content_type_get_description (mime_type));
1391 	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
1392 
1393 	parameters_install->dialog = dialog;
1394 	parameters_install->proxy = proxy;
1395 
1396 	g_signal_connect (dialog, "response",
1397 	                  G_CALLBACK (application_unhandled_file_install),
1398 	                  parameters_install);
1399 	g_signal_connect (dialog, "delete-event",
1400 	                  G_CALLBACK (delete_cb), NULL);
1401 	gtk_widget_show_all (dialog);
1402 	g_free (mime_type);
1403 }
1404 
1405 static void
1406 application_unhandled_uri (ActivateParameters *parameters, char *uri)
1407 {
1408 	gboolean show_install_mime;
1409 	char *mime_type;
1410 	NautilusFile *file;
1411 	ActivateParametersInstall *parameters_install;
1412 
1413 	file = nautilus_file_get_by_uri (uri);
1414 
1415 	mime_type = nautilus_file_get_mime_type (file);
1416 
1417 	/* copy the parts of parameters we are interested in as the orignal will be unref'd */
1418 	parameters_install = g_new0 (ActivateParametersInstall, 1);
1419 	parameters_install->slot = parameters->slot;
1420 	g_object_add_weak_pointer (G_OBJECT (parameters_install->slot), (gpointer *)&parameters_install->slot);
1421 	if (parameters->parent_window) {
1422 		parameters_install->parent_window = parameters->parent_window;
1423 		g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *)&parameters_install->parent_window);
1424 	}
1425 	parameters_install->activation_directory = g_strdup (parameters->activation_directory);
1426 	parameters_install->file = file;
1427 	parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
1428 	parameters_install->flags = parameters->flags;
1429 	parameters_install->user_confirmation = parameters->user_confirmation;
1430 	parameters_install->uri = g_strdup(uri);
1431 
1432 #ifdef ENABLE_PACKAGEKIT
1433 	/* allow an admin to disable the PackageKit search functionality */
1434 	show_install_mime = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_INSTALL_MIME_ACTIVATION);
1435 #else
1436 	/* we have no install functionality */
1437 	show_install_mime = FALSE;
1438 #endif
1439 	/* There is no use trying to look for handlers of application/octet-stream */
1440 	if (g_content_type_is_unknown (mime_type)) {
1441 		show_install_mime = FALSE;
1442 	}
1443 
1444 	g_free (mime_type);
1445 
1446 	if (!show_install_mime) {
1447 		goto out;
1448 	}
1449 
1450 	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
1451 				  G_DBUS_PROXY_FLAGS_NONE,
1452 				  NULL,
1453 				  "org.freedesktop.PackageKit",
1454 				  "/org/freedesktop/PackageKit",
1455 				  "org.freedesktop.PackageKit.Modify",
1456 				  NULL,
1457 				  pk_proxy_appeared_cb,
1458 				  parameters_install);
1459 
1460 	return;
1461 
1462 out:
1463         /* show an unhelpful dialog */
1464         show_unhandled_type_error (parameters_install);
1465 }
1466 
1467 typedef struct {
1468 	GtkWindow *parent_window;
1469 	NautilusFile *file;
1470 } ActivateParametersDesktop;
1471 
1472 static void
1473 activate_parameters_desktop_free (ActivateParametersDesktop *parameters_desktop)
1474 {
1475 	if (parameters_desktop->parent_window) {
1476 		g_object_remove_weak_pointer (G_OBJECT (parameters_desktop->parent_window), (gpointer *)&parameters_desktop->parent_window);
1477 	}
1478 	nautilus_file_unref (parameters_desktop->file);
1479 	g_free (parameters_desktop);
1480 }
1481 
1482 static void
1483 untrusted_launcher_response_callback (GtkDialog *dialog,
1484 				      int response_id,
1485 				      ActivateParametersDesktop *parameters)
1486 {
1487 	GdkScreen *screen;
1488 	char *uri;
1489 	GFile *file;
1490 	
1491 	switch (response_id) {
1492 	case RESPONSE_RUN:
1493 		screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
1494 		uri = nautilus_file_get_uri (parameters->file);
1495 		DEBUG ("Launching untrusted launcher %s", uri);
1496 		nautilus_launch_desktop_file (screen, uri, NULL,
1497 					      parameters->parent_window);
1498 		g_free (uri);
1499 		break;
1500 	case RESPONSE_MARK_TRUSTED:
1501 		file = nautilus_file_get_location (parameters->file);
1502 		nautilus_file_mark_desktop_file_trusted (file,
1503 							 parameters->parent_window,
1504 							 TRUE, 
1505 							 NULL, NULL);
1506 		g_object_unref (file);
1507 		break;
1508 	default:
1509 		/* Just destroy dialog */
1510 		break;
1511 	}
1512 	
1513 	gtk_widget_destroy (GTK_WIDGET (dialog));
1514 	activate_parameters_desktop_free (parameters);
1515 }
1516 
1517 static void
1518 activate_desktop_file (ActivateParameters *parameters,
1519 		       NautilusFile *file)
1520 {
1521 	ActivateParametersDesktop *parameters_desktop;
1522 	char *primary, *secondary, *display_name;
1523 	GtkWidget *dialog;
1524 	GdkScreen *screen;
1525 	char *uri;
1526 	
1527 	screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
1528 
1529 	if (!nautilus_file_is_trusted_link (file)) {
1530 		/* copy the parts of parameters we are interested in as the orignal will be freed */
1531 		parameters_desktop = g_new0 (ActivateParametersDesktop, 1);
1532 		if (parameters->parent_window) {
1533 			parameters_desktop->parent_window = parameters->parent_window;
1534 			g_object_add_weak_pointer (G_OBJECT (parameters_desktop->parent_window), (gpointer *)&parameters_desktop->parent_window);
1535 		}
1536 		parameters_desktop->file = nautilus_file_ref (file);
1537 
1538 		primary = _("Untrusted application launcher");
1539 		display_name = nautilus_file_get_display_name (file);
1540 		secondary =
1541 			g_strdup_printf (_("The application launcher ā€œ%sā€ has not been marked as trusted. "
1542 					   "If you do not know the source of this file, launching it may be unsafe."
1543 					   ),
1544 					 display_name);
1545 		
1546 		dialog = gtk_message_dialog_new (parameters->parent_window,
1547 						 0,
1548 						 GTK_MESSAGE_WARNING,
1549 						 GTK_BUTTONS_NONE,
1550 						 NULL);
1551 		g_object_set (dialog,
1552 			      "text", primary,
1553 			      "secondary-text", secondary,
1554 			      NULL);
1555 		gtk_dialog_add_button (GTK_DIALOG (dialog),
1556 				       _("_Launch Anyway"), RESPONSE_RUN);
1557 		if (nautilus_file_can_set_permissions (file)) {
1558 			gtk_dialog_add_button (GTK_DIALOG (dialog),
1559 					       _("Mark as _Trusted"), RESPONSE_MARK_TRUSTED);
1560 		}
1561 		gtk_dialog_add_button (GTK_DIALOG (dialog),
1562 				       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1563 		gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
1564 
1565 		g_signal_connect (dialog, "response",
1566 				  G_CALLBACK (untrusted_launcher_response_callback),
1567 				  parameters_desktop);
1568 		gtk_widget_show (dialog);
1569 		
1570 		g_free (display_name);
1571 		g_free (secondary);
1572 		return;
1573 	}
1574 	
1575 	uri = nautilus_file_get_uri (file);
1576 	DEBUG ("Launching trusted launcher %s", uri);
1577 	nautilus_launch_desktop_file (screen, uri, NULL,
1578 				      parameters->parent_window);
1579 	g_free (uri);
1580 }
1581 
1582 static void
1583 activate_files (ActivateParameters *parameters)
1584 {
1585 	NautilusWindow *window;
1586 	NautilusWindowOpenFlags flags;
1587 	NautilusFile *file;
1588 	GList *launch_desktop_files;
1589 	GList *launch_files;
1590 	GList *launch_in_terminal_files;
1591 	GList *open_in_app_uris;
1592 	GList *open_in_app_parameters;
1593 	GList *unhandled_open_in_app_uris;
1594 	ApplicationLaunchParameters *one_parameters;
1595 	GList *open_in_view_files;
1596 	GList *l;
1597 	int count;
1598 	char *uri;
1599 	char *executable_path, *quoted_path;
1600 	char *old_working_dir;
1601 	ActivationAction action;
1602 	GdkScreen *screen;
1603 	LaunchLocation *location;
1604 	gint num_apps;
1605 	gint num_unhandled;
1606 	gint num_files;
1607 	gboolean open_files;
1608 	
1609 	screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
1610 
1611 	launch_desktop_files = NULL;
1612 	launch_files = NULL;
1613 	launch_in_terminal_files = NULL;
1614 	open_in_app_uris = NULL;
1615 	open_in_view_files = NULL;
1616 
1617 	for (l = parameters->locations; l != NULL; l = l->next) {
1618 		location = l->data;
1619 		file = location->file;
1620 
1621 		if (file_was_cancelled (file)) {
1622 			continue;
1623 		}
1624 
1625 		action = get_activation_action (file);
1626 		if (action == ACTIVATION_ACTION_ASK) {
1627 			/* Special case for executable text files, since it might be
1628 			 * dangerous & unexpected to launch these.
1629 			 */
1630 			pause_activation_timed_cancel (parameters);
1631 			action = get_executable_text_file_action (parameters->parent_window, file);
1632 			unpause_activation_timed_cancel (parameters);
1633 		}
1634 
1635 		switch (action) {
1636 		case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
1637 			launch_desktop_files = g_list_prepend (launch_desktop_files, file);
1638 			break;
1639 		case ACTIVATION_ACTION_LAUNCH :
1640 			launch_files = g_list_prepend (launch_files, file);
1641 			break;
1642 		case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL :
1643 			launch_in_terminal_files = g_list_prepend (launch_in_terminal_files, file);
1644 			break;
1645 		case ACTIVATION_ACTION_OPEN_IN_VIEW :
1646 			open_in_view_files = g_list_prepend (open_in_view_files, file);
1647 			break;
1648 		case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
1649 			open_in_app_uris = g_list_prepend (open_in_app_uris, location->uri);
1650 			break;
1651 		case ACTIVATION_ACTION_DO_NOTHING :
1652 			break;
1653 		case ACTIVATION_ACTION_ASK :
1654 			g_assert_not_reached ();
1655 			break;
1656 		}
1657 	}
1658 
1659 	launch_desktop_files = g_list_reverse (launch_desktop_files);
1660 	for (l = launch_desktop_files; l != NULL; l = l->next) {
1661 		file = NAUTILUS_FILE (l->data);
1662 
1663 		activate_desktop_file (parameters, file);
1664 	}
1665 
1666 	old_working_dir = NULL;
1667 	if (parameters->activation_directory &&
1668 	    (launch_files != NULL || launch_in_terminal_files != NULL)) {
1669 		old_working_dir = g_get_current_dir ();
1670 		g_chdir (parameters->activation_directory);
1671 		
1672 	}
1673 
1674 	launch_files = g_list_reverse (launch_files);
1675 	for (l = launch_files; l != NULL; l = l->next) {
1676 		file = NAUTILUS_FILE (l->data);
1677 
1678 		uri = nautilus_file_get_activation_uri (file);
1679 		executable_path = g_filename_from_uri (uri, NULL, NULL);
1680 		quoted_path = g_shell_quote (executable_path);
1681 
1682 		DEBUG ("Launching file path %s", quoted_path);
1683 
1684 		nautilus_launch_application_from_command (screen, quoted_path, FALSE, NULL);
1685 		g_free (quoted_path);
1686 		g_free (executable_path);
1687 		g_free (uri);
1688 			
1689 	}
1690 
1691 	launch_in_terminal_files = g_list_reverse (launch_in_terminal_files);
1692 	for (l = launch_in_terminal_files; l != NULL; l = l->next) {
1693 		file = NAUTILUS_FILE (l->data);
1694 
1695 		uri = nautilus_file_get_activation_uri (file);
1696 		executable_path = g_filename_from_uri (uri, NULL, NULL);
1697 		quoted_path = g_shell_quote (executable_path);
1698 
1699 		DEBUG ("Launching in terminal file quoted path %s", quoted_path);
1700 
1701 		nautilus_launch_application_from_command (screen, quoted_path, TRUE, NULL);
1702 
1703 		g_free (quoted_path);
1704 		g_free (executable_path);
1705 		g_free (uri);
1706 	}
1707 
1708 	if (old_working_dir != NULL) {
1709 		g_chdir (old_working_dir);
1710 		g_free (old_working_dir);
1711 	}
1712 
1713 	open_in_view_files = g_list_reverse (open_in_view_files);
1714 	count = g_list_length (open_in_view_files);
1715 
1716 	flags = parameters->flags;
1717 	if (count > 1) {
1718 		if ((parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0) {
1719 			flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
1720 		} else {
1721 			flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
1722 		}
1723 	}
1724 
1725 	if (parameters->slot != NULL &&
1726 	    (!parameters->user_confirmation ||
1727 	     confirm_multiple_windows (parameters->parent_window, count,
1728 				       (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0))) {
1729 
1730 		if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0 &&
1731 		    g_settings_get_enum (nautilus_preferences, NAUTILUS_PREFERENCES_NEW_TAB_POSITION) ==
1732 		    NAUTILUS_NEW_TAB_POSITION_AFTER_CURRENT_TAB) {
1733 			/* When inserting N tabs after the current one,
1734 			 * we first open tab N, then tab N-1, ..., then tab 0.
1735 			 * Each of them is appended to the current tab, i.e.
1736 			 * prepended to the list of tabs to open.
1737 			 */
1738 			open_in_view_files = g_list_reverse (open_in_view_files);
1739 		}
1740 
1741 
1742 		for (l = open_in_view_files; l != NULL; l = l->next) {
1743 			GFile *f;
1744 			/* The ui should ask for navigation or object windows
1745 			 * depending on what the current one is */
1746 			file = NAUTILUS_FILE (l->data);
1747 
1748 			uri = nautilus_file_get_activation_uri (file);
1749 			f = g_file_new_for_uri (uri);
1750 			nautilus_window_slot_open_location (parameters->slot, f, flags);
1751 			g_object_unref (f);
1752 			g_free (uri);
1753 		}
1754 	}
1755 
1756 	open_in_app_parameters = NULL;
1757 	unhandled_open_in_app_uris = NULL;
1758 
1759 	if (open_in_app_uris != NULL) {
1760 		open_in_app_uris = g_list_reverse (open_in_app_uris);
1761 
1762 		open_in_app_parameters = make_activation_parameters
1763 			(open_in_app_uris, &unhandled_open_in_app_uris);
1764 	}
1765 
1766 	num_apps = g_list_length (open_in_app_parameters);
1767 	num_unhandled = g_list_length (unhandled_open_in_app_uris);
1768 	num_files = g_list_length (open_in_app_uris);
1769 	open_files = TRUE;
1770 
1771 	if (open_in_app_uris != NULL &&
1772 	    (!parameters->user_confirmation ||
1773 	     num_files + num_unhandled > SILENT_OPEN_LIMIT) &&
1774 	     num_apps > 1) {
1775 		GtkDialog *dialog;
1776 		char *prompt;
1777 		char *detail;
1778 		int response;
1779 
1780 		pause_activation_timed_cancel (parameters);
1781 
1782 		prompt = _("Are you sure you want to open all files?");
1783 		detail = g_strdup_printf (ngettext ("This will open %d separate application.",
1784 						    "This will open %d separate applications.", num_apps), num_apps);
1785 		dialog = eel_show_yes_no_dialog (prompt, detail,
1786 						 GTK_STOCK_OK, GTK_STOCK_CANCEL,
1787 						 parameters->parent_window);
1788 		g_free (detail);
1789 
1790 		response = gtk_dialog_run (dialog);
1791 		gtk_widget_destroy (GTK_WIDGET (dialog));
1792 
1793 		unpause_activation_timed_cancel (parameters);
1794 
1795 		if (response != GTK_RESPONSE_YES) {
1796 			open_files = FALSE;
1797 		}
1798 	}
1799 
1800 	if (open_files) {
1801 		for (l = open_in_app_parameters; l != NULL; l = l->next) {
1802 			one_parameters = l->data;
1803 
1804 			nautilus_launch_application_by_uri (one_parameters->application,
1805 							    one_parameters->uris,
1806 							    parameters->parent_window);
1807 			application_launch_parameters_free (one_parameters);
1808 		}
1809 
1810 		for (l = unhandled_open_in_app_uris; l != NULL; l = l->next) {
1811 			uri = l->data;
1812 
1813 			/* this does not block */
1814 			application_unhandled_uri (parameters, uri);
1815 		}
1816 	}
1817 
1818 	window = NULL;
1819 	if (parameters->slot != NULL) {
1820 		window = nautilus_window_slot_get_window (parameters->slot);
1821 	}
1822 
1823 	if (open_in_app_parameters != NULL ||
1824 	    unhandled_open_in_app_uris != NULL) {
1825 		if ((parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0 &&
1826 		    window != NULL) {
1827 			nautilus_window_close (window);
1828 		}
1829 	}
1830 
1831 	g_list_free (launch_desktop_files);
1832 	g_list_free (launch_files);
1833 	g_list_free (launch_in_terminal_files);
1834 	g_list_free (open_in_view_files);
1835 	g_list_free (open_in_app_uris);
1836 	g_list_free (open_in_app_parameters);
1837 	g_list_free (unhandled_open_in_app_uris);
1838 	
1839 	activation_parameters_free (parameters);
1840 }
1841 
1842 static void 
1843 activation_mount_not_mounted_callback (GObject *source_object,
1844 				       GAsyncResult *res,
1845 				       gpointer user_data)
1846 {
1847 	ActivateParameters *parameters = user_data;
1848 	GError *error;
1849 	NautilusFile *file;
1850 	LaunchLocation *loc;
1851 
1852 	file = parameters->not_mounted->data;
1853 		
1854 	error = NULL;
1855 	if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error)) {
1856 		if (error->domain != G_IO_ERROR ||
1857 		    (error->code != G_IO_ERROR_CANCELLED &&
1858 		     error->code != G_IO_ERROR_FAILED_HANDLED &&
1859 		     error->code != G_IO_ERROR_ALREADY_MOUNTED)) {
1860 			eel_show_error_dialog (_("Unable to access location"), error->message, parameters->parent_window);
1861 		}
1862 
1863 		if (error->domain != G_IO_ERROR ||
1864 		    error->code != G_IO_ERROR_ALREADY_MOUNTED) {
1865 			loc = find_launch_location_for_file (parameters->locations,
1866 							     file);
1867 			if (loc) {
1868 				parameters->locations =
1869 					g_list_remove (parameters->locations, loc); 
1870 				launch_location_free (loc);
1871 			}
1872 		}
1873 
1874 		g_error_free (error);
1875 	} 
1876 	
1877 	parameters->not_mounted = g_list_delete_link (parameters->not_mounted,
1878 						      parameters->not_mounted);
1879 	nautilus_file_unref (file);
1880 
1881 	activation_mount_not_mounted (parameters);
1882 }
1883 
1884 static void
1885 activation_mount_not_mounted (ActivateParameters *parameters)
1886 {
1887 	NautilusFile *file;
1888 	GFile *location;
1889 	LaunchLocation *loc;
1890 	GMountOperation *mount_op;
1891 	GList *l, *next, *files;
1892 
1893 	if (parameters->not_mounted != NULL) {
1894 		file = parameters->not_mounted->data;
1895 		mount_op = gtk_mount_operation_new (parameters->parent_window);
1896 		g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
1897 		g_signal_connect (mount_op, "notify::is-showing",
1898 				  G_CALLBACK (activate_mount_op_active), parameters);
1899 		location = nautilus_file_get_location (file);
1900 		g_file_mount_enclosing_volume (location, 0, mount_op, parameters->cancellable,
1901 					       activation_mount_not_mounted_callback, parameters);
1902 		g_object_unref (location);
1903 		/* unref mount_op here - g_file_mount_enclosing_volume() does ref for itself */
1904 		g_object_unref (mount_op);
1905 		return;
1906 	}
1907 
1908 	parameters->tried_mounting = TRUE;
1909 
1910 	if (parameters->locations == NULL) {
1911 		activation_parameters_free (parameters);
1912 		return;
1913 	}
1914 	
1915 	/*  once the mount is finished, refresh all attributes        */
1916 	/*  - fixes new windows not appearing after successful mount  */
1917 	for (l = parameters->locations; l != NULL; l = next) {
1918 		loc = l->data;
1919 		next = l->next;
1920 		nautilus_file_invalidate_all_attributes (loc->file);
1921 	}
1922 	
1923 	files = get_file_list_for_launch_locations (parameters->locations);
1924 	nautilus_file_list_call_when_ready
1925 		(files,
1926 		 nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
1927 		 &parameters->files_handle,
1928 		 activate_callback, parameters);
1929 	nautilus_file_list_free (files);
1930 }
1931 
1932 
1933 static void
1934 activate_callback (GList *files, gpointer callback_data)
1935 {
1936 	ActivateParameters *parameters = callback_data;
1937 	GList *l, *next;
1938 	NautilusFile *file;
1939 	LaunchLocation *location;
1940 
1941 	parameters->files_handle = NULL;
1942 
1943 	for (l = parameters->locations; l != NULL; l = next) {
1944 		location = l->data;
1945 		file = location->file;
1946 		next = l->next;
1947 
1948 		if (file_was_cancelled (file)) {
1949 			launch_location_free (location);
1950 			parameters->locations = g_list_delete_link (parameters->locations, l);
1951 			continue;
1952 		}
1953 
1954 		if (file_was_not_mounted (file)) {
1955 			if (parameters->tried_mounting) {
1956 				launch_location_free (location);
1957 				parameters->locations = g_list_delete_link (parameters->locations, l);
1958 			} else {
1959 				parameters->not_mounted = g_list_prepend (parameters->not_mounted,
1960 									  nautilus_file_ref (file));
1961 			}
1962 			continue;
1963 		}
1964 	}
1965 
1966 
1967 	if (parameters->not_mounted != NULL) {
1968 		activation_mount_not_mounted (parameters);
1969 	} else {
1970 		activate_files (parameters);
1971 	}
1972 }
1973 
1974 static void
1975 activate_activation_uris_ready_callback (GList *files_ignore,
1976 					 gpointer callback_data)
1977 {
1978 	ActivateParameters *parameters = callback_data;
1979 	GList *l, *next, *files;
1980 	NautilusFile *file;
1981 	LaunchLocation *location;
1982 
1983 	parameters->files_handle = NULL;
1984 	
1985 	for (l = parameters->locations; l != NULL; l = next) {
1986 		location = l->data;
1987 		file = location->file;
1988 		next = l->next;
1989 
1990 		if (file_was_cancelled (file)) {
1991 			launch_location_free (location);
1992 			parameters->locations = g_list_delete_link (parameters->locations, l);
1993 			continue;
1994 		}
1995 
1996 		if (nautilus_file_is_broken_symbolic_link (file)) {
1997 			launch_location_free (location);
1998 			parameters->locations = g_list_delete_link (parameters->locations, l);
1999 			pause_activation_timed_cancel (parameters);
2000 			report_broken_symbolic_link (parameters->parent_window, file);
2001 			unpause_activation_timed_cancel (parameters);
2002 			continue;
2003 		}
2004 
2005 		if (nautilus_file_get_file_type (file) == G_FILE_TYPE_MOUNTABLE &&
2006 		    !nautilus_file_has_activation_uri (file)) {
2007 			/* Don't launch these... There is nothing we
2008 			   can do */
2009 			launch_location_free (location);
2010 			parameters->locations = g_list_delete_link (parameters->locations, l);
2011 			continue;
2012 		}
2013 		
2014 	}
2015 
2016 	if (parameters->locations == NULL) {
2017 		activation_parameters_free (parameters);
2018 		return;
2019 	}
2020 
2021 	/* Convert the files to the actual activation uri files */
2022 	for (l = parameters->locations; l != NULL; l = l->next) {
2023 		char *uri = NULL;
2024 
2025 		location = l->data;
2026 
2027 		/* We want the file for the activation URI since we care
2028 		 * about the attributes for that, not for the original file.
2029 		 */
2030 		if (nautilus_file_is_symbolic_link (location->file)) {
2031 			uri = nautilus_file_get_symbolic_link_target_uri (location->file);
2032 		}
2033 
2034 		if (uri == NULL) {
2035 			uri = nautilus_file_get_activation_uri (location->file);
2036 		}
2037 
2038 		if (uri != NULL) {
2039 			launch_location_update_from_uri (location, uri);
2040 		}
2041 		g_free (uri);
2042 	}
2043 
2044 
2045 	/* get the parameters for the actual files */	
2046 	files = get_file_list_for_launch_locations (parameters->locations);
2047 	nautilus_file_list_call_when_ready
2048 		(files,
2049 		 nautilus_mime_actions_get_required_file_attributes () | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
2050 		 &parameters->files_handle,
2051 		 activate_callback, parameters);
2052 	nautilus_file_list_free (files);
2053 }
2054 
2055 static void
2056 activation_get_activation_uris (ActivateParameters *parameters)
2057 {
2058 	GList *l, *files;
2059 	NautilusFile *file;
2060 	LaunchLocation *location;
2061 
2062 	/* link target info might be stale, re-read it */
2063 	for (l = parameters->locations; l != NULL; l = l->next) {
2064 		location = l->data;
2065 		file = location->file;
2066 
2067 		if (file_was_cancelled (file)) {
2068 			launch_location_free (location);
2069 			parameters->locations = g_list_delete_link (parameters->locations, l);
2070 			continue;
2071 		}
2072 	}
2073 
2074 	if (parameters->locations == NULL) {
2075 		activation_parameters_free (parameters);
2076 		return;
2077 	}
2078 
2079 	files = get_file_list_for_launch_locations (parameters->locations);
2080 	nautilus_file_list_call_when_ready
2081 		(files,
2082 		 NAUTILUS_FILE_ATTRIBUTE_INFO |
2083 		 NAUTILUS_FILE_ATTRIBUTE_LINK_INFO,
2084 		 &parameters->files_handle,
2085 		 activate_activation_uris_ready_callback, parameters);
2086 	nautilus_file_list_free (files);
2087 }
2088 
2089 static void
2090 activation_mountable_mounted (NautilusFile  *file,
2091 			      GFile         *result_location,
2092 			      GError        *error,
2093 			      gpointer       callback_data)
2094 {
2095 	ActivateParameters *parameters = callback_data;
2096 	NautilusFile *target_file;
2097 	LaunchLocation *location;
2098 
2099 	/* Remove from list of files that have to be mounted */
2100 	parameters->mountables = g_list_remove (parameters->mountables, file); 
2101 	nautilus_file_unref (file);
2102 
2103 	
2104 	if (error == NULL) {
2105 		/* Replace file with the result of the mount */
2106 		target_file = nautilus_file_get (result_location);
2107 
2108 		location = find_launch_location_for_file (parameters->locations,
2109 							  file);
2110 		if (location) {
2111 			launch_location_update_from_file (location, target_file);
2112 		}
2113 		nautilus_file_unref (target_file);
2114 	} else {
2115 		/* Remove failed file */
2116 		
2117 		if (error->domain != G_IO_ERROR ||
2118 		    (error->code != G_IO_ERROR_FAILED_HANDLED &&
2119 		     error->code != G_IO_ERROR_ALREADY_MOUNTED)) {
2120 			location = find_launch_location_for_file (parameters->locations,
2121 								  file);
2122 			if (location) {
2123 				parameters->locations =
2124 					g_list_remove (parameters->locations,
2125 						       location); 
2126 				launch_location_free (location);
2127 			}
2128 		}
2129 		
2130 		if (error->domain != G_IO_ERROR ||
2131 		    (error->code != G_IO_ERROR_CANCELLED &&
2132 		     error->code != G_IO_ERROR_FAILED_HANDLED &&
2133 		     error->code != G_IO_ERROR_ALREADY_MOUNTED)) {
2134 			eel_show_error_dialog (_("Unable to access location"),
2135 					       error->message, parameters->parent_window);
2136 		}
2137 
2138 		if (error->code == G_IO_ERROR_CANCELLED) {
2139 			activation_parameters_free (parameters);
2140 			return;
2141 		}
2142 	}
2143 
2144 	/* Mount more mountables */
2145 	activation_mount_mountables (parameters);
2146 }
2147 
2148 
2149 static void
2150 activation_mount_mountables (ActivateParameters *parameters)
2151 {
2152 	NautilusFile *file;
2153 	GMountOperation *mount_op;
2154 
2155 	if (parameters->mountables != NULL) {
2156 		file = parameters->mountables->data;
2157 		mount_op = gtk_mount_operation_new (parameters->parent_window);
2158 		g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
2159 		g_signal_connect (mount_op, "notify::is-showing",
2160 				  G_CALLBACK (activate_mount_op_active), parameters);
2161 		nautilus_file_mount (file,
2162 				     mount_op,
2163 				     parameters->cancellable,
2164 				     activation_mountable_mounted,
2165 				     parameters);
2166 		g_object_unref (mount_op);
2167 		return;
2168 	}
2169 
2170 	if (parameters->mountables == NULL && parameters->start_mountables == NULL)
2171 		activation_get_activation_uris (parameters);
2172 }
2173 
2174 
2175 static void
2176 activation_mountable_started (NautilusFile  *file,
2177 			      GFile         *gfile_of_file,
2178 			      GError        *error,
2179 			      gpointer       callback_data)
2180 {
2181 	ActivateParameters *parameters = callback_data;
2182 	LaunchLocation *location;
2183 
2184 	/* Remove from list of files that have to be mounted */
2185 	parameters->start_mountables = g_list_remove (parameters->start_mountables, file);
2186 	nautilus_file_unref (file);
2187 
2188 	if (error == NULL) {
2189 		/* Remove file */
2190 		location = find_launch_location_for_file (parameters->locations, file);
2191 		if (location != NULL) {
2192 			parameters->locations = g_list_remove (parameters->locations, location);
2193 			launch_location_free (location);
2194 		}
2195 
2196 	} else {
2197 		/* Remove failed file */
2198 		if (error->domain != G_IO_ERROR ||
2199 		    (error->code != G_IO_ERROR_FAILED_HANDLED)) {
2200 			location = find_launch_location_for_file (parameters->locations,
2201 								  file);
2202 			if (location) {
2203 				parameters->locations =
2204 					g_list_remove (parameters->locations,
2205 						       location);
2206 				launch_location_free (location);
2207 			}
2208 		}
2209 
2210 		if (error->domain != G_IO_ERROR ||
2211 		    (error->code != G_IO_ERROR_CANCELLED &&
2212 		     error->code != G_IO_ERROR_FAILED_HANDLED)) {
2213 			eel_show_error_dialog (_("Unable to start location"),
2214 					       error->message, NULL);
2215 		}
2216 
2217 		if (error->code == G_IO_ERROR_CANCELLED) {
2218 			activation_parameters_free (parameters);
2219 			return;
2220 		}
2221 	}
2222 
2223 	/* Start more mountables */
2224 	activation_start_mountables (parameters);
2225 }
2226 
2227 static void
2228 activation_start_mountables (ActivateParameters *parameters)
2229 {
2230 	NautilusFile *file;
2231 	GMountOperation *start_op;
2232 
2233 	if (parameters->start_mountables != NULL) {
2234 		file = parameters->start_mountables->data;
2235 		start_op = gtk_mount_operation_new (parameters->parent_window);
2236 		g_signal_connect (start_op, "notify::is-showing",
2237 				  G_CALLBACK (activate_mount_op_active), parameters);
2238 		nautilus_file_start (file,
2239 				     start_op,
2240 				     parameters->cancellable,
2241 				     activation_mountable_started,
2242 				     parameters);
2243 		g_object_unref (start_op);
2244 		return;
2245 	}
2246 
2247 	if (parameters->mountables == NULL && parameters->start_mountables == NULL)
2248 		activation_get_activation_uris (parameters);
2249 }
2250 
2251 /**
2252  * nautilus_mime_activate_files:
2253  * 
2254  * Activate a list of files. Each one might launch with an application or
2255  * with a component. This is normally called only by subclasses.
2256  * @view: FMDirectoryView in question.
2257  * @files: A GList of NautilusFiles to activate.
2258  * 
2259  **/
2260 void
2261 nautilus_mime_activate_files (GtkWindow *parent_window,
2262 			      NautilusWindowSlot *slot,
2263 			      GList *files,
2264 			      const char *launch_directory,
2265 			      NautilusWindowOpenFlags flags,
2266 			      gboolean user_confirmation)
2267 {
2268 	ActivateParameters *parameters;
2269 	char *file_name;
2270 	int file_count;
2271 	GList *l, *next;
2272 	NautilusFile *file;
2273 	LaunchLocation *location;
2274 
2275 	if (files == NULL) {
2276 		return;
2277 	}
2278 
2279 	DEBUG_FILES (files, "Calling activate_files() with files:");
2280 
2281 	parameters = g_new0 (ActivateParameters, 1);
2282 	parameters->slot = slot;
2283 	g_object_add_weak_pointer (G_OBJECT (parameters->slot), (gpointer *)&parameters->slot);
2284 	if (parent_window) {
2285 		parameters->parent_window = parent_window;
2286 		g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
2287 	}
2288 	parameters->cancellable = g_cancellable_new ();
2289 	parameters->activation_directory = g_strdup (launch_directory);
2290 	parameters->locations = launch_locations_from_file_list (files);
2291 	parameters->flags = flags;
2292 	parameters->user_confirmation = user_confirmation;
2293 
2294 	file_count = g_list_length (files);
2295 	if (file_count == 1) {
2296 		file_name = nautilus_file_get_display_name (files->data);
2297 		parameters->timed_wait_prompt = g_strdup_printf (_("Opening ā€œ%sā€."), file_name);
2298 		g_free (file_name);
2299 	} else {
2300 		parameters->timed_wait_prompt = g_strdup_printf (ngettext ("Opening %d item.",
2301 									   "Opening %d items.",
2302 									   file_count),
2303 								 file_count);
2304 	}
2305 
2306 	
2307 	for (l = parameters->locations; l != NULL; l = next) {
2308 		location = l->data;
2309 		file = location->file;
2310 		next = l->next;
2311 		
2312 		if (nautilus_file_can_mount (file)) {
2313 			parameters->mountables = g_list_prepend (parameters->mountables,
2314 								 nautilus_file_ref (file));
2315 		}
2316 
2317 		if (nautilus_file_can_start (file)) {
2318 			parameters->start_mountables = g_list_prepend (parameters->start_mountables,
2319 								       nautilus_file_ref (file));
2320 		}
2321 	}
2322 	
2323 	activation_start_timed_cancel (parameters);
2324 	if (parameters->mountables != NULL)
2325 		activation_mount_mountables (parameters);
2326 	if (parameters->start_mountables != NULL)
2327 		activation_start_mountables (parameters);
2328 	if (parameters->mountables == NULL && parameters->start_mountables == NULL)
2329 		activation_get_activation_uris (parameters);
2330 }
2331 
2332 /**
2333  * nautilus_mime_activate_file:
2334  * 
2335  * Activate a file in this view. This might involve switching the displayed
2336  * location for the current window, or launching an application.
2337  * @view: FMDirectoryView in question.
2338  * @file: A NautilusFile representing the file in this view to activate.
2339  * @use_new_window: Should this item be opened in a new window?
2340  * 
2341  **/
2342 
2343 void
2344 nautilus_mime_activate_file (GtkWindow *parent_window,
2345 			     NautilusWindowSlot *slot,
2346 			     NautilusFile *file,
2347 			     const char *launch_directory,
2348 			     NautilusWindowOpenFlags flags)
2349 {
2350 	GList *files;
2351 
2352 	g_return_if_fail (NAUTILUS_IS_FILE (file));
2353 
2354 	files = g_list_prepend (NULL, file);
2355 	nautilus_mime_activate_files (parent_window, slot, files, launch_directory, flags, FALSE);
2356 	g_list_free (files);
2357 }