nautilus-3.6.3/src/nautilus-canvas-view.c

No issues found

   1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
   2 
   3 /* fm-canvas-view.c - implementation of canvas view of directory.
   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: John Sullivan <sullivan@eazel.com>
  23 */
  24 
  25 #include <config.h>
  26 
  27 #include "nautilus-canvas-view.h"
  28 
  29 #include "nautilus-actions.h"
  30 #include "nautilus-canvas-view-container.h"
  31 #include "nautilus-desktop-canvas-view.h"
  32 #include "nautilus-error-reporting.h"
  33 #include "nautilus-view-dnd.h"
  34 #include "nautilus-view-factory.h"
  35 
  36 #include <stdlib.h>
  37 #include <eel/eel-vfs-extensions.h>
  38 #include <errno.h>
  39 #include <fcntl.h>
  40 #include <gtk/gtk.h>
  41 #include <glib/gi18n.h>
  42 #include <gio/gio.h>
  43 #include <libnautilus-private/nautilus-clipboard-monitor.h>
  44 #include <libnautilus-private/nautilus-directory.h>
  45 #include <libnautilus-private/nautilus-dnd.h>
  46 #include <libnautilus-private/nautilus-file-dnd.h>
  47 #include <libnautilus-private/nautilus-file-utilities.h>
  48 #include <libnautilus-private/nautilus-ui-utilities.h>
  49 #include <libnautilus-private/nautilus-global-preferences.h>
  50 #include <libnautilus-private/nautilus-canvas-container.h>
  51 #include <libnautilus-private/nautilus-canvas-dnd.h>
  52 #include <libnautilus-private/nautilus-link.h>
  53 #include <libnautilus-private/nautilus-metadata.h>
  54 #include <libnautilus-private/nautilus-clipboard.h>
  55 #include <libnautilus-private/nautilus-desktop-icon-file.h>
  56 
  57 #define DEBUG_FLAG NAUTILUS_DEBUG_CANVAS_VIEW
  58 #include <libnautilus-private/nautilus-debug.h>
  59 
  60 #include <locale.h>
  61 #include <signal.h>
  62 #include <stdio.h>
  63 #include <sys/types.h>
  64 #include <sys/wait.h>
  65 #include <unistd.h>
  66 
  67 enum 
  68 {
  69 	PROP_SUPPORTS_AUTO_LAYOUT = 1,
  70 	PROP_SUPPORTS_SCALING,
  71 	PROP_SUPPORTS_KEEP_ALIGNED,
  72 	PROP_SUPPORTS_MANUAL_LAYOUT,
  73 	NUM_PROPERTIES
  74 };
  75 
  76 static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
  77 
  78 typedef struct {
  79 	const NautilusFileSortType sort_type;
  80 	const char *metadata_text;
  81 	const char *action;
  82 } SortCriterion;
  83 
  84 typedef enum {
  85 	MENU_ITEM_TYPE_STANDARD,
  86 	MENU_ITEM_TYPE_CHECK,
  87 	MENU_ITEM_TYPE_RADIO,
  88 	MENU_ITEM_TYPE_TREE
  89 } MenuItemType;
  90 
  91 struct NautilusCanvasViewDetails
  92 {
  93 	GList *icons_not_positioned;
  94 
  95 	guint react_to_canvas_change_idle_id;
  96 
  97 	const SortCriterion *sort;
  98 	gboolean sort_reversed;
  99 
 100 	GtkActionGroup *canvas_action_group;
 101 	guint canvas_merge_id;
 102 	
 103 	gboolean filter_by_screen;
 104 	int num_screens;
 105 
 106 	gulong clipboard_handler_id;
 107 
 108 	GtkWidget *canvas_container;
 109 
 110 	gboolean supports_auto_layout;
 111 	gboolean supports_manual_layout;
 112 	gboolean supports_scaling;
 113 	gboolean supports_keep_aligned;
 114 };
 115 
 116 
 117 /* Note that the first item in this list is the default sort,
 118  * and that the items show up in the menu in the order they
 119  * appear in this list.
 120  */
 121 static const SortCriterion sort_criteria[] = {
 122 	{
 123 		NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
 124 		"name",
 125 		"Sort by Name"
 126 	},
 127 	{
 128 		NAUTILUS_FILE_SORT_BY_SIZE,
 129 		"size",
 130 		"Sort by Size"
 131 	},
 132 	{
 133 		NAUTILUS_FILE_SORT_BY_TYPE,
 134 		"type",
 135 		"Sort by Type"
 136 	},
 137 	{
 138 		NAUTILUS_FILE_SORT_BY_MTIME,
 139 		"modification date",
 140 		"Sort by Modification Date"
 141 	},
 142 	{
 143 		NAUTILUS_FILE_SORT_BY_TRASHED_TIME,
 144 		"trashed",
 145 		NAUTILUS_ACTION_SORT_TRASH_TIME
 146 	},
 147 	{
 148 		NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE,
 149 		NULL,
 150 		NAUTILUS_ACTION_SORT_SEARCH_RELEVANCE,
 151 	}
 152 };
 153 
 154 static void                 nautilus_canvas_view_set_directory_sort_by        (NautilusCanvasView           *canvas_view,
 155 									     NautilusFile         *file,
 156 									     const char           *sort_by);
 157 static void                 nautilus_canvas_view_set_zoom_level               (NautilusCanvasView           *view,
 158 									     NautilusZoomLevel     new_level,
 159 									     gboolean              always_emit);
 160 static void                 nautilus_canvas_view_update_click_mode            (NautilusCanvasView           *canvas_view);
 161 static gboolean             nautilus_canvas_view_supports_scaling	      (NautilusCanvasView           *canvas_view);
 162 static void                 nautilus_canvas_view_reveal_selection       (NautilusView               *view);
 163 static const SortCriterion *get_sort_criterion_by_sort_type           (NautilusFileSortType  sort_type);
 164 static void                 set_sort_criterion_by_sort_type           (NautilusCanvasView           *canvas_view,
 165 								       NautilusFileSortType  sort_type);
 166 static gboolean             set_sort_reversed                         (NautilusCanvasView     *canvas_view,
 167 								       gboolean              new_value,
 168 								       gboolean              set_metadata);
 169 static void                 switch_to_manual_layout                   (NautilusCanvasView     *view);
 170 static void                 update_layout_menus                       (NautilusCanvasView     *view);
 171 static NautilusFileSortType get_default_sort_order                    (NautilusFile         *file,
 172 								       gboolean             *reversed);
 173 static void                 nautilus_canvas_view_clear                  (NautilusView         *view);
 174 
 175 G_DEFINE_TYPE (NautilusCanvasView, nautilus_canvas_view, NAUTILUS_TYPE_VIEW);
 176 
 177 static void
 178 nautilus_canvas_view_destroy (GtkWidget *object)
 179 {
 180 	NautilusCanvasView *canvas_view;
 181 
 182 	canvas_view = NAUTILUS_CANVAS_VIEW (object);
 183 
 184 	nautilus_canvas_view_clear (NAUTILUS_VIEW (object));
 185 
 186         if (canvas_view->details->react_to_canvas_change_idle_id != 0) {
 187                 g_source_remove (canvas_view->details->react_to_canvas_change_idle_id);
 188 		canvas_view->details->react_to_canvas_change_idle_id = 0;
 189         }
 190 
 191 	if (canvas_view->details->clipboard_handler_id != 0) {
 192 		g_signal_handler_disconnect (nautilus_clipboard_monitor_get (),
 193 					     canvas_view->details->clipboard_handler_id);
 194 		canvas_view->details->clipboard_handler_id = 0;
 195 	}
 196 
 197 	if (canvas_view->details->icons_not_positioned) {
 198 		nautilus_file_list_free (canvas_view->details->icons_not_positioned);
 199 		canvas_view->details->icons_not_positioned = NULL;
 200 	}
 201 
 202 	GTK_WIDGET_CLASS (nautilus_canvas_view_parent_class)->destroy (object);
 203 }
 204 
 205 static NautilusCanvasContainer *
 206 get_canvas_container (NautilusCanvasView *canvas_view)
 207 {
 208 	return NAUTILUS_CANVAS_CONTAINER (canvas_view->details->canvas_container);
 209 }
 210 
 211 NautilusCanvasContainer *
 212 nautilus_canvas_view_get_canvas_container (NautilusCanvasView *canvas_view)
 213 {
 214 	return get_canvas_container (canvas_view);
 215 }
 216 
 217 static gboolean
 218 nautilus_canvas_view_supports_manual_layout (NautilusCanvasView *view)
 219 {
 220 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
 221 
 222 	return view->details->supports_manual_layout;
 223 }
 224 
 225 static gboolean
 226 get_stored_icon_position_callback (NautilusCanvasContainer *container,
 227 				   NautilusFile *file,
 228 				   NautilusCanvasPosition *position,
 229 				   NautilusCanvasView *canvas_view)
 230 {
 231 	char *position_string, *scale_string;
 232 	gboolean position_good;
 233 	char c;
 234 
 235 	g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
 236 	g_assert (NAUTILUS_IS_FILE (file));
 237 	g_assert (position != NULL);
 238 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
 239 
 240 	if (!nautilus_canvas_view_supports_manual_layout (canvas_view)) {
 241 		return FALSE;
 242 	}
 243 
 244 	/* Get the current position of this canvas from the metadata. */
 245 	position_string = nautilus_file_get_metadata
 246 		(file, NAUTILUS_METADATA_KEY_ICON_POSITION, "");
 247 	position_good = sscanf
 248 		(position_string, " %d , %d %c",
 249 		 &position->x, &position->y, &c) == 2;
 250 	g_free (position_string);
 251 
 252 	/* If it is the desktop directory, maybe the gnome-libs metadata has information about it */
 253 
 254 	/* Disable scaling if not on the desktop */
 255 	if (nautilus_canvas_view_supports_scaling (canvas_view)) {
 256 		/* Get the scale of the canvas from the metadata. */
 257 		scale_string = nautilus_file_get_metadata
 258 			(file, NAUTILUS_METADATA_KEY_ICON_SCALE, "1");
 259 		position->scale = g_ascii_strtod (scale_string, NULL);
 260 		if (errno != 0) {
 261 			position->scale = 1.0;
 262 		}
 263 
 264 		g_free (scale_string);
 265 	} else {
 266 		position->scale = 1.0;
 267 	}
 268 	
 269 	return position_good;
 270 }
 271 
 272 static void
 273 real_set_sort_criterion (NautilusCanvasView *canvas_view,
 274                          const SortCriterion *sort,
 275                          gboolean clear,
 276 			 gboolean set_metadata)
 277 {
 278 	NautilusFile *file;
 279 
 280 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
 281 
 282 	if (clear) {
 283 		nautilus_file_set_metadata (file,
 284 					    NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY, NULL, NULL);
 285 		nautilus_file_set_metadata (file,
 286 					    NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED, NULL, NULL);
 287 		canvas_view->details->sort =
 288 			get_sort_criterion_by_sort_type	(get_default_sort_order
 289 							 (file, &canvas_view->details->sort_reversed));
 290 	} else if (set_metadata) {
 291 		/* Store the new sort setting. */
 292 		nautilus_canvas_view_set_directory_sort_by (canvas_view,
 293 						    file,
 294 						    sort->metadata_text);
 295 	}
 296 
 297 	/* Update the layout menus to match the new sort setting. */
 298 	update_layout_menus (canvas_view);
 299 }
 300 
 301 static void
 302 set_sort_criterion (NautilusCanvasView *canvas_view,
 303 		    const SortCriterion *sort,
 304 		    gboolean set_metadata)
 305 {
 306 	if (sort == NULL ||
 307 	    canvas_view->details->sort == sort) {
 308 		return;
 309 	}
 310 
 311 	canvas_view->details->sort = sort;
 312 
 313         real_set_sort_criterion (canvas_view, sort, FALSE, set_metadata);
 314 }
 315 
 316 static void
 317 clear_sort_criterion (NautilusCanvasView *canvas_view)
 318 {
 319 	real_set_sort_criterion (canvas_view, NULL, TRUE, TRUE);
 320 }
 321 
 322 void
 323 nautilus_canvas_view_clean_up_by_name (NautilusCanvasView *canvas_view)
 324 {
 325 	NautilusCanvasContainer *canvas_container;
 326 	gboolean saved_sort_reversed;
 327 
 328 	canvas_container = get_canvas_container (canvas_view);
 329 
 330 	/* Hardwire Clean Up to always be by name, in forward order */
 331 	saved_sort_reversed = canvas_view->details->sort_reversed;
 332 	
 333 	set_sort_reversed (canvas_view, FALSE, FALSE);
 334 	set_sort_criterion (canvas_view, &sort_criteria[0], FALSE);
 335 
 336 	nautilus_canvas_container_sort (canvas_container);
 337 	nautilus_canvas_container_freeze_icon_positions (canvas_container);
 338 
 339 	set_sort_reversed (canvas_view, saved_sort_reversed, FALSE);
 340 }
 341 
 342 static gboolean
 343 nautilus_canvas_view_using_auto_layout (NautilusCanvasView *canvas_view)
 344 {
 345 	return nautilus_canvas_container_is_auto_layout 
 346 		(get_canvas_container (canvas_view));
 347 }
 348 
 349 static void
 350 action_sort_radio_callback (GtkAction *action,
 351 			    GtkRadioAction *current,
 352 			    NautilusCanvasView *view)
 353 {
 354 	NautilusFileSortType sort_type;
 355 	
 356 	sort_type = gtk_radio_action_get_current_value (current);
 357 	
 358 	/* Note that id might be a toggle item.
 359 	 * Ignore non-sort ids so that they don't cause sorting.
 360 	 */
 361 	if (sort_type == NAUTILUS_FILE_SORT_NONE) {
 362 		switch_to_manual_layout (view);
 363 	} else {
 364 		set_sort_criterion_by_sort_type (view, sort_type);
 365 	}
 366 }
 367 
 368 static void
 369 list_covers (NautilusCanvasIconData *data, gpointer callback_data)
 370 {
 371 	GSList **file_list;
 372 
 373 	file_list = callback_data;
 374 
 375 	*file_list = g_slist_prepend (*file_list, data);
 376 }
 377 
 378 static void
 379 unref_cover (NautilusCanvasIconData *data, gpointer callback_data)
 380 {
 381 	nautilus_file_unref (NAUTILUS_FILE (data));
 382 }
 383 
 384 static void
 385 nautilus_canvas_view_clear (NautilusView *view)
 386 {
 387 	NautilusCanvasContainer *canvas_container;
 388 	GSList *file_list;
 389 	
 390 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
 391 
 392 	canvas_container = get_canvas_container (NAUTILUS_CANVAS_VIEW (view));
 393 	if (!canvas_container)
 394 		return;
 395 
 396 	/* Clear away the existing icons. */
 397 	file_list = NULL;
 398 	nautilus_canvas_container_for_each (canvas_container, list_covers, &file_list);
 399 	nautilus_canvas_container_clear (canvas_container);
 400 	g_slist_foreach (file_list, (GFunc)unref_cover, NULL);
 401 	g_slist_free (file_list);
 402 }
 403 
 404 static gboolean
 405 should_show_file_on_screen (NautilusView *view, NautilusFile *file)
 406 {
 407 	char *screen_string;
 408 	int screen_num;
 409 	NautilusCanvasView *canvas_view;
 410 	GdkScreen *screen;
 411 
 412 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 413 
 414 	if (!nautilus_view_should_show_file (view, file)) {
 415 		return FALSE;
 416 	}
 417 	
 418 	/* Get the screen for this canvas from the metadata. */
 419 	screen_string = nautilus_file_get_metadata
 420 		(file, NAUTILUS_METADATA_KEY_SCREEN, "0");
 421 	screen_num = atoi (screen_string);
 422 	g_free (screen_string);
 423 	screen = gtk_widget_get_screen (GTK_WIDGET (view));
 424 
 425 	if (screen_num != gdk_screen_get_number (screen) &&
 426 	    (screen_num < canvas_view->details->num_screens ||
 427 	     gdk_screen_get_number (screen) > 0)) {
 428 		return FALSE;
 429 	}
 430 
 431 	return TRUE;
 432 }
 433 
 434 static void
 435 nautilus_canvas_view_remove_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
 436 {
 437 	NautilusCanvasView *canvas_view;
 438 
 439 	/* This used to assert that 'directory == nautilus_view_get_model (view)', but that
 440 	 * resulted in a lot of crash reports (bug #352592). I don't see how that trace happens.
 441 	 * It seems that somehow we get a files_changed event sent to the view from a directory
 442 	 * that isn't the model, but the code disables the monitor and signal callback handlers when
 443 	 * changing directories. Maybe we can get some more information when this happens.
 444 	 * Further discussion in bug #368178.
 445 	 */
 446 	if (directory != nautilus_view_get_model (view)) {
 447 		char *file_uri, *dir_uri, *model_uri;
 448 		file_uri = nautilus_file_get_uri (file);
 449 		dir_uri = nautilus_directory_get_uri (directory);
 450 		model_uri = nautilus_directory_get_uri (nautilus_view_get_model (view));
 451 		g_warning ("nautilus_canvas_view_remove_file() - directory not canvas view model, shouldn't happen.\n"
 452 			   "file: %p:%s, dir: %p:%s, model: %p:%s, view loading: %d\n"
 453 			   "If you see this, please add this info to http://bugzilla.gnome.org/show_bug.cgi?id=368178",
 454 			   file, file_uri, directory, dir_uri, nautilus_view_get_model (view), model_uri, nautilus_view_get_loading (view));
 455 		g_free (file_uri);
 456 		g_free (dir_uri);
 457 		g_free (model_uri);
 458 	}
 459 	
 460 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 461 
 462 	if (nautilus_canvas_container_remove (get_canvas_container (canvas_view),
 463 					      NAUTILUS_CANVAS_ICON_DATA (file))) {
 464 		nautilus_file_unref (file);
 465 	}
 466 }
 467 
 468 static void
 469 nautilus_canvas_view_add_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
 470 {
 471 	NautilusCanvasView *canvas_view;
 472 	NautilusCanvasContainer *canvas_container;
 473 
 474 	g_assert (directory == nautilus_view_get_model (view));
 475 	
 476 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 477 	canvas_container = get_canvas_container (canvas_view);
 478 
 479 	if (canvas_view->details->filter_by_screen &&
 480 	    !should_show_file_on_screen (view, file)) {
 481 		return;
 482 	}
 483 
 484 	/* Reset scroll region for the first canvas added when loading a directory. */
 485 	if (nautilus_view_get_loading (view) && nautilus_canvas_container_is_empty (canvas_container)) {
 486 		nautilus_canvas_container_reset_scroll_region (canvas_container);
 487 	}
 488 
 489 	if (nautilus_canvas_container_add (canvas_container,
 490 					 NAUTILUS_CANVAS_ICON_DATA (file))) {
 491 		nautilus_file_ref (file);
 492 	}
 493 }
 494 
 495 static void
 496 nautilus_canvas_view_file_changed (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
 497 {
 498 	NautilusCanvasView *canvas_view;
 499 
 500 	g_assert (directory == nautilus_view_get_model (view));
 501 	
 502 	g_return_if_fail (view != NULL);
 503 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 504 
 505 	if (!canvas_view->details->filter_by_screen) {
 506 		nautilus_canvas_container_request_update
 507 			(get_canvas_container (canvas_view),
 508 			 NAUTILUS_CANVAS_ICON_DATA (file));
 509 		return;
 510 	}
 511 	
 512 	if (!should_show_file_on_screen (view, file)) {
 513 		nautilus_canvas_view_remove_file (view, file, directory);
 514 	} else {
 515 
 516 		nautilus_canvas_container_request_update
 517 			(get_canvas_container (canvas_view),
 518 			 NAUTILUS_CANVAS_ICON_DATA (file));
 519 	}
 520 }
 521 
 522 static gboolean
 523 nautilus_canvas_view_supports_auto_layout (NautilusCanvasView *view)
 524 {
 525 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
 526 
 527 	return view->details->supports_auto_layout;
 528 }
 529 
 530 static gboolean
 531 nautilus_canvas_view_supports_scaling (NautilusCanvasView *view)
 532 {
 533 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
 534 
 535 	return view->details->supports_scaling;
 536 }
 537 
 538 static gboolean
 539 nautilus_canvas_view_supports_keep_aligned (NautilusCanvasView *view)
 540 {
 541 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
 542 
 543 	return view->details->supports_keep_aligned;
 544 }
 545 
 546 static void
 547 update_layout_menus (NautilusCanvasView *view)
 548 {
 549 	gboolean is_auto_layout;
 550 	GtkAction *action;
 551 	const char *action_name;
 552 	NautilusFile *file;
 553 
 554 	if (view->details->canvas_action_group == NULL) {
 555 		return;
 556 	}
 557 
 558 	is_auto_layout = nautilus_canvas_view_using_auto_layout (view);
 559 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (view));
 560 
 561 	if (nautilus_canvas_view_supports_auto_layout (view)) {
 562 		/* Mark sort criterion. */
 563 		action_name = is_auto_layout ? view->details->sort->action : NAUTILUS_ACTION_MANUAL_LAYOUT;
 564 		action = gtk_action_group_get_action (view->details->canvas_action_group,
 565 						      action_name);
 566 		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
 567 
 568 		action = gtk_action_group_get_action (view->details->canvas_action_group,
 569 						      NAUTILUS_ACTION_REVERSED_ORDER);
 570 		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
 571 					      view->details->sort_reversed);
 572 		gtk_action_set_sensitive (action, is_auto_layout);
 573 
 574 		action = gtk_action_group_get_action (view->details->canvas_action_group,
 575 		                                      NAUTILUS_ACTION_SORT_TRASH_TIME);
 576 
 577 		if (file != NULL && nautilus_file_is_in_trash (file)) {
 578 			gtk_action_set_visible (action, TRUE);
 579 		} else {
 580 			gtk_action_set_visible (action, FALSE);
 581 		}
 582 
 583 		action = gtk_action_group_get_action (view->details->canvas_action_group,
 584 		                                      NAUTILUS_ACTION_SORT_SEARCH_RELEVANCE);
 585 
 586 		if (file != NULL && nautilus_file_is_in_search (file)) {
 587 			gtk_action_set_visible (action, TRUE);
 588 		} else {
 589 			gtk_action_set_visible (action, FALSE);
 590 		}
 591 	}
 592 
 593 	action = gtk_action_group_get_action (view->details->canvas_action_group,
 594 					      NAUTILUS_ACTION_MANUAL_LAYOUT);
 595 	gtk_action_set_visible (action,
 596 				nautilus_canvas_view_supports_manual_layout (view));
 597 
 598 	action = gtk_action_group_get_action (view->details->canvas_action_group,
 599 					      NAUTILUS_ACTION_KEEP_ALIGNED);
 600 	gtk_action_set_visible (action,
 601 				nautilus_canvas_view_supports_keep_aligned (view));
 602 	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
 603 				      nautilus_canvas_container_is_keep_aligned (get_canvas_container (view)));
 604 	gtk_action_set_sensitive (action, !is_auto_layout);
 605 }
 606 
 607 
 608 static char *
 609 nautilus_canvas_view_get_directory_sort_by (NautilusCanvasView *canvas_view,
 610 					  NautilusFile *file)
 611 {
 612 	const SortCriterion *default_sort_criterion;
 613 
 614 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view)) {
 615 		return g_strdup ("name");
 616 	}
 617 
 618 	default_sort_criterion = get_sort_criterion_by_sort_type (get_default_sort_order (file, NULL));
 619 	g_return_val_if_fail (default_sort_criterion != NULL, NULL);
 620 
 621 	return nautilus_file_get_metadata
 622 		(file, NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
 623 		 default_sort_criterion->metadata_text);
 624 }
 625 
 626 static NautilusFileSortType
 627 get_default_sort_order (NautilusFile *file, gboolean *reversed)
 628 {
 629 	NautilusFileSortType retval, default_sort_order;
 630 	gboolean default_sort_in_reverse_order;
 631 
 632 	default_sort_order = g_settings_get_enum (nautilus_preferences,
 633 						  NAUTILUS_PREFERENCES_DEFAULT_SORT_ORDER);
 634 	default_sort_in_reverse_order = g_settings_get_boolean (nautilus_preferences,
 635 								NAUTILUS_PREFERENCES_DEFAULT_SORT_IN_REVERSE_ORDER);
 636 
 637 	retval = nautilus_file_get_default_sort_type (file, reversed);
 638 
 639 	if (retval == NAUTILUS_FILE_SORT_NONE) {
 640 
 641 		if (reversed != NULL) {
 642 			*reversed = default_sort_in_reverse_order;
 643 		}
 644 
 645 		retval = CLAMP (default_sort_order, NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
 646 				NAUTILUS_FILE_SORT_BY_MTIME);
 647 	}
 648 
 649 	return retval;
 650 }
 651 
 652 static void
 653 nautilus_canvas_view_set_directory_sort_by (NautilusCanvasView *canvas_view, 
 654 					  NautilusFile *file, 
 655 					  const char *sort_by)
 656 {
 657 	const SortCriterion *default_sort_criterion;
 658 
 659 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view)) {
 660 		return;
 661 	}
 662 
 663 	default_sort_criterion = get_sort_criterion_by_sort_type (get_default_sort_order (file, NULL));
 664 	g_return_if_fail (default_sort_criterion != NULL);
 665 
 666 	nautilus_file_set_metadata
 667 		(file, NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
 668 		 default_sort_criterion->metadata_text,
 669 		 sort_by);
 670 }
 671 
 672 static gboolean
 673 nautilus_canvas_view_get_directory_sort_reversed (NautilusCanvasView *canvas_view,
 674 						NautilusFile *file)
 675 {
 676 	gboolean reversed;
 677 
 678 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view)) {
 679 		return FALSE;
 680 	}
 681 
 682 	get_default_sort_order (file, &reversed);
 683 	return nautilus_file_get_boolean_metadata
 684 		(file,
 685 		 NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
 686 		 reversed);
 687 }
 688 
 689 static void
 690 nautilus_canvas_view_set_directory_sort_reversed (NautilusCanvasView *canvas_view,
 691 						NautilusFile *file,
 692 						gboolean sort_reversed)
 693 {
 694 	gboolean reversed;
 695 
 696 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view)) {
 697 		return;
 698 	}
 699 
 700 	get_default_sort_order (file, &reversed);
 701 	nautilus_file_set_boolean_metadata
 702 		(file,
 703 		 NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
 704 		 reversed, sort_reversed);
 705 }
 706 
 707 static gboolean
 708 get_default_directory_keep_aligned (void)
 709 {
 710 	return TRUE;
 711 }
 712 
 713 static gboolean
 714 nautilus_canvas_view_get_directory_keep_aligned (NautilusCanvasView *canvas_view,
 715 					       NautilusFile *file)
 716 {
 717 	if (!nautilus_canvas_view_supports_keep_aligned (canvas_view)) {
 718 		return FALSE;
 719 	}
 720 	
 721 	return  nautilus_file_get_boolean_metadata
 722 		(file,
 723 		 NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED,
 724 		 get_default_directory_keep_aligned ());
 725 }
 726 
 727 static void
 728 nautilus_canvas_view_set_directory_keep_aligned (NautilusCanvasView *canvas_view,
 729 					       NautilusFile *file,
 730 					       gboolean keep_aligned)
 731 {
 732 	if (!nautilus_canvas_view_supports_keep_aligned (canvas_view)) {
 733 		return;
 734 	}
 735 
 736 	nautilus_file_set_boolean_metadata
 737 		(file, NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED,
 738 		 get_default_directory_keep_aligned (),
 739 		 keep_aligned);
 740 }
 741 
 742 static gboolean
 743 nautilus_canvas_view_get_directory_auto_layout (NautilusCanvasView *canvas_view,
 744 					      NautilusFile *file)
 745 {
 746 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view)) {
 747 		return FALSE;
 748 	}
 749 
 750 	if (!nautilus_canvas_view_supports_manual_layout (canvas_view)) {
 751 		return TRUE;
 752 	}
 753 
 754 	return nautilus_file_get_boolean_metadata
 755 		(file, NAUTILUS_METADATA_KEY_ICON_VIEW_AUTO_LAYOUT, TRUE);
 756 }
 757 
 758 static void
 759 nautilus_canvas_view_set_directory_auto_layout (NautilusCanvasView *canvas_view,
 760 					      NautilusFile *file,
 761 					gboolean auto_layout)
 762 {
 763 	if (!nautilus_canvas_view_supports_auto_layout (canvas_view) ||
 764 	    !nautilus_canvas_view_supports_manual_layout (canvas_view)) {
 765 		return;
 766 	}
 767 
 768 	nautilus_file_set_boolean_metadata
 769 		(file, NAUTILUS_METADATA_KEY_ICON_VIEW_AUTO_LAYOUT,
 770 		 TRUE,
 771 		 auto_layout);
 772 }
 773 
 774 static gboolean
 775 set_sort_reversed (NautilusCanvasView *canvas_view,
 776 		   gboolean new_value,
 777 		   gboolean set_metadata)
 778 {
 779 	if (canvas_view->details->sort_reversed == new_value) {
 780 		return FALSE;
 781 	}
 782 	canvas_view->details->sort_reversed = new_value;
 783 
 784 	if (set_metadata) {
 785 		/* Store the new sort setting. */
 786 		nautilus_canvas_view_set_directory_sort_reversed (canvas_view, nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view)), new_value);
 787 	}
 788 	
 789 	/* Update the layout menus to match the new sort-order setting. */
 790 	update_layout_menus (canvas_view);
 791 
 792 	return TRUE;
 793 }
 794 
 795 static const SortCriterion *
 796 get_sort_criterion_by_metadata_text (const char *metadata_text)
 797 {
 798 	guint i;
 799 
 800 	/* Figure out what the new sort setting should be. */
 801 	for (i = 0; i < G_N_ELEMENTS (sort_criteria); i++) {
 802 		if (g_strcmp0 (sort_criteria[i].metadata_text, metadata_text) == 0) {
 803 			return &sort_criteria[i];
 804 		}
 805 	}
 806 	return NULL;
 807 }
 808 
 809 static const SortCriterion *
 810 get_sort_criterion_by_sort_type (NautilusFileSortType sort_type)
 811 {
 812 	guint i;
 813 
 814 	/* Figure out what the new sort setting should be. */
 815 	for (i = 0; i < G_N_ELEMENTS (sort_criteria); i++) {
 816 		if (sort_type == sort_criteria[i].sort_type) {
 817 			return &sort_criteria[i];
 818 		}
 819 	}
 820 
 821 	return &sort_criteria[0];
 822 }
 823 
 824 #define DEFAULT_ZOOM_LEVEL(canvas_view) default_zoom_level
 825 
 826 static NautilusZoomLevel
 827 get_default_zoom_level (NautilusCanvasView *canvas_view)
 828 {
 829 	NautilusZoomLevel default_zoom_level;
 830 
 831 	default_zoom_level = g_settings_get_enum (nautilus_icon_view_preferences,
 832 						  NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL);
 833 
 834 	return CLAMP (DEFAULT_ZOOM_LEVEL(canvas_view), NAUTILUS_ZOOM_LEVEL_SMALLEST, NAUTILUS_ZOOM_LEVEL_LARGEST);
 835 }
 836 
 837 static void
 838 nautilus_canvas_view_begin_loading (NautilusView *view)
 839 {
 840 	NautilusCanvasView *canvas_view;
 841 	GtkWidget *canvas_container;
 842 	NautilusFile *file;
 843 	char *sort_name, *uri;
 844 
 845 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
 846 
 847 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 848 	file = nautilus_view_get_directory_as_file (view);
 849 	uri = nautilus_file_get_uri (file);
 850 	canvas_container = GTK_WIDGET (get_canvas_container (canvas_view));
 851 
 852 	nautilus_canvas_container_begin_loading (NAUTILUS_CANVAS_CONTAINER (canvas_container));
 853 
 854 	nautilus_canvas_container_set_allow_moves (NAUTILUS_CANVAS_CONTAINER (canvas_container),
 855 						 !eel_uri_is_search (uri));
 856 
 857 	g_free (uri);
 858 
 859 	/* Set the sort mode.
 860 	 * It's OK not to resort the icons because the
 861 	 * container doesn't have any icons at this point.
 862 	 */
 863 	sort_name = nautilus_canvas_view_get_directory_sort_by (canvas_view, file);
 864 	set_sort_criterion (canvas_view, get_sort_criterion_by_metadata_text (sort_name), FALSE);
 865 	g_free (sort_name);
 866 
 867 	/* Set the sort direction from the metadata. */
 868 	set_sort_reversed (canvas_view, nautilus_canvas_view_get_directory_sort_reversed (canvas_view, file), FALSE);
 869 
 870 	nautilus_canvas_container_set_keep_aligned
 871 		(get_canvas_container (canvas_view), 
 872 		 nautilus_canvas_view_get_directory_keep_aligned (canvas_view, file));
 873 
 874 	/* We must set auto-layout last, because it invokes the layout_changed 
 875 	 * callback, which works incorrectly if the other layout criteria are
 876 	 * not already set up properly (see bug 6500, e.g.)
 877 	 */
 878 	nautilus_canvas_container_set_auto_layout
 879 		(get_canvas_container (canvas_view), 
 880 		 nautilus_canvas_view_get_directory_auto_layout (canvas_view, file));
 881 
 882 	/* e.g. keep aligned may have changed */
 883 	update_layout_menus (canvas_view);
 884 }
 885 
 886 static void
 887 canvas_view_notify_clipboard_info (NautilusClipboardMonitor *monitor,
 888                                  NautilusClipboardInfo *info,
 889                                  NautilusCanvasView *canvas_view)
 890 {
 891 	GList *icon_data;
 892 
 893 	icon_data = NULL;
 894 	if (info && info->cut) {
 895 		icon_data = info->files;
 896 	}
 897 
 898 	nautilus_canvas_container_set_highlighted_for_clipboard (
 899 							       get_canvas_container (canvas_view), icon_data);
 900 }
 901 
 902 static void
 903 nautilus_canvas_view_end_loading (NautilusView *view,
 904 			  gboolean all_files_seen)
 905 {
 906 	NautilusCanvasView *canvas_view;
 907 	GtkWidget *canvas_container;
 908 	NautilusClipboardMonitor *monitor;
 909 	NautilusClipboardInfo *info;
 910 
 911 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 912 
 913 	canvas_container = GTK_WIDGET (get_canvas_container (canvas_view));
 914 	nautilus_canvas_container_end_loading (NAUTILUS_CANVAS_CONTAINER (canvas_container), all_files_seen);
 915 
 916 	monitor = nautilus_clipboard_monitor_get ();
 917 	info = nautilus_clipboard_monitor_get_clipboard_info (monitor);
 918 
 919 	canvas_view_notify_clipboard_info (monitor, info, canvas_view);
 920 }
 921 
 922 static NautilusZoomLevel
 923 nautilus_canvas_view_get_zoom_level (NautilusView *view)
 924 {
 925 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NAUTILUS_ZOOM_LEVEL_STANDARD);
 926 	
 927 	return nautilus_canvas_container_get_zoom_level (get_canvas_container (NAUTILUS_CANVAS_VIEW (view)));
 928 }
 929 
 930 static void
 931 nautilus_canvas_view_set_zoom_level (NautilusCanvasView *view,
 932 				   NautilusZoomLevel new_level,
 933 				   gboolean always_emit)
 934 {
 935 	NautilusCanvasContainer *canvas_container;
 936 
 937 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
 938 	g_return_if_fail (new_level >= NAUTILUS_ZOOM_LEVEL_SMALLEST &&
 939 			  new_level <= NAUTILUS_ZOOM_LEVEL_LARGEST);
 940 
 941 	canvas_container = get_canvas_container (view);
 942 	if (nautilus_canvas_container_get_zoom_level (canvas_container) == new_level) {
 943 		if (always_emit) {
 944 			g_signal_emit_by_name (view, "zoom_level_changed");
 945 		}
 946 		return;
 947 	}
 948 
 949 	nautilus_canvas_container_set_zoom_level (canvas_container, new_level);
 950 
 951 	g_signal_emit_by_name (view, "zoom_level_changed");
 952 	
 953 	if (nautilus_view_get_active (NAUTILUS_VIEW (view))) {
 954 		nautilus_view_update_menus (NAUTILUS_VIEW (view));
 955 	}
 956 }
 957 
 958 static void
 959 nautilus_canvas_view_bump_zoom_level (NautilusView *view, int zoom_increment)
 960 {
 961 	NautilusZoomLevel new_level;
 962 
 963 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
 964 
 965 	new_level = nautilus_canvas_view_get_zoom_level (view) + zoom_increment;
 966 
 967 	if (new_level >= NAUTILUS_ZOOM_LEVEL_SMALLEST &&
 968 	    new_level <= NAUTILUS_ZOOM_LEVEL_LARGEST) {
 969 		nautilus_view_zoom_to_level (view, new_level);
 970 	}
 971 }
 972 
 973 static void
 974 nautilus_canvas_view_zoom_to_level (NautilusView *view,
 975 			    NautilusZoomLevel zoom_level)
 976 {
 977 	NautilusCanvasView *canvas_view;
 978 
 979 	g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
 980 
 981 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 982 	nautilus_canvas_view_set_zoom_level (canvas_view, zoom_level, FALSE);
 983 }
 984 
 985 static void
 986 nautilus_canvas_view_restore_default_zoom_level (NautilusView *view)
 987 {
 988 	NautilusCanvasView *canvas_view;
 989 
 990 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
 991 
 992 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
 993 	nautilus_view_zoom_to_level
 994 		(view, get_default_zoom_level (canvas_view));
 995 }
 996 
 997 static gboolean 
 998 nautilus_canvas_view_can_zoom_in (NautilusView *view) 
 999 {
1000 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
1001 
1002 	return nautilus_canvas_view_get_zoom_level (view) 
1003 		< NAUTILUS_ZOOM_LEVEL_LARGEST;
1004 }
1005 
1006 static gboolean 
1007 nautilus_canvas_view_can_zoom_out (NautilusView *view) 
1008 {
1009 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
1010 
1011 	return nautilus_canvas_view_get_zoom_level (view) 
1012 		> NAUTILUS_ZOOM_LEVEL_SMALLEST;
1013 }
1014 
1015 static gboolean
1016 nautilus_canvas_view_is_empty (NautilusView *view)
1017 {
1018 	g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
1019 
1020 	return nautilus_canvas_container_is_empty 
1021 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)));
1022 }
1023 
1024 static GList *
1025 nautilus_canvas_view_get_selection (NautilusView *view)
1026 {
1027 	GList *list;
1028 
1029 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
1030 
1031 	list = nautilus_canvas_container_get_selection
1032 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)));
1033 	nautilus_file_list_ref (list);
1034 	return list;
1035 }
1036 
1037 static void
1038 set_sort_criterion_by_sort_type (NautilusCanvasView *canvas_view,
1039 				 NautilusFileSortType  sort_type)
1040 {
1041 	const SortCriterion *sort;
1042 
1043 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1044 
1045 	sort = get_sort_criterion_by_sort_type (sort_type);
1046 	g_return_if_fail (sort != NULL);
1047 	
1048 	if (sort == canvas_view->details->sort
1049 	    && nautilus_canvas_view_using_auto_layout (canvas_view)) {
1050 		return;
1051 	}
1052 
1053 	set_sort_criterion (canvas_view, sort, TRUE);
1054 	nautilus_canvas_container_sort (get_canvas_container (canvas_view));
1055 	nautilus_canvas_view_reveal_selection (NAUTILUS_VIEW (canvas_view));
1056 }
1057 
1058 
1059 static void
1060 action_reversed_order_callback (GtkAction *action,
1061 				gpointer user_data)
1062 {
1063 	NautilusCanvasView *canvas_view;
1064 
1065 	canvas_view = NAUTILUS_CANVAS_VIEW (user_data);
1066 
1067 	if (set_sort_reversed (canvas_view,
1068 			       gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
1069 			       TRUE)) {
1070 		nautilus_canvas_container_sort (get_canvas_container (canvas_view));
1071 		nautilus_canvas_view_reveal_selection (NAUTILUS_VIEW (canvas_view));
1072 	}
1073 }
1074 
1075 static void
1076 action_keep_aligned_callback (GtkAction *action,
1077 			      gpointer user_data)
1078 {
1079 	NautilusCanvasView *canvas_view;
1080 	NautilusFile *file;
1081 	gboolean keep_aligned;
1082 
1083 	canvas_view = NAUTILUS_CANVAS_VIEW (user_data);
1084 
1085 	keep_aligned = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1086 
1087 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
1088 	nautilus_canvas_view_set_directory_keep_aligned (canvas_view,
1089 						 file,
1090 						 keep_aligned);
1091 						      
1092 	nautilus_canvas_container_set_keep_aligned (get_canvas_container (canvas_view),
1093 						  keep_aligned);
1094 }
1095 
1096 static void
1097 switch_to_manual_layout (NautilusCanvasView *canvas_view)
1098 {
1099 	if (!nautilus_canvas_view_using_auto_layout (canvas_view)) {
1100 		return;
1101 	}
1102 
1103 	canvas_view->details->sort = &sort_criteria[0];
1104 	
1105 	nautilus_canvas_container_set_auto_layout
1106 		(get_canvas_container (canvas_view), FALSE);
1107 }
1108 
1109 static void
1110 layout_changed_callback (NautilusCanvasContainer *container,
1111 			 NautilusCanvasView *canvas_view)
1112 {
1113 	NautilusFile *file;
1114 
1115 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1116 	g_assert (container == get_canvas_container (canvas_view));
1117 
1118 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
1119 
1120 	if (file != NULL) {
1121 		nautilus_canvas_view_set_directory_auto_layout
1122 			(canvas_view,
1123 			 file,
1124 			 nautilus_canvas_view_using_auto_layout (canvas_view));
1125 	}
1126 
1127 	update_layout_menus (canvas_view);
1128 }
1129 
1130 static gboolean
1131 nautilus_canvas_view_can_rename_file (NautilusView *view, NautilusFile *file)
1132 {
1133 	if (!(nautilus_canvas_view_get_zoom_level (view) > NAUTILUS_ZOOM_LEVEL_SMALLEST)) {
1134 		return FALSE;
1135 	}
1136 
1137 	return NAUTILUS_VIEW_CLASS(nautilus_canvas_view_parent_class)->can_rename_file (view, file);
1138 }
1139 
1140 static void
1141 nautilus_canvas_view_start_renaming_file (NautilusView *view,
1142 				  NautilusFile *file,
1143 				  gboolean select_all)
1144 {
1145 	/* call parent class to make sure the right canvas is selected */
1146 	NAUTILUS_VIEW_CLASS(nautilus_canvas_view_parent_class)->start_renaming_file (view, file, select_all);
1147 	
1148 	/* start renaming */
1149 	nautilus_canvas_container_start_renaming_selected_item
1150 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)), select_all);
1151 }
1152 
1153 static const GtkToggleActionEntry canvas_view_toggle_entries[] = {
1154   /* name, stock id */      { "Reversed Order", NULL,
1155   /* label, accelerator */    N_("Re_versed Order"), NULL,
1156   /* tooltip */               N_("Display icons in the opposite order"),
1157                               G_CALLBACK (action_reversed_order_callback),
1158                               0 },
1159   /* name, stock id */      { "Keep Aligned", NULL,
1160   /* label, accelerator */    N_("_Keep Aligned"), NULL,
1161   /* tooltip */               N_("Keep icons lined up on a grid"),
1162                               G_CALLBACK (action_keep_aligned_callback),
1163                               0 },
1164 };
1165 
1166 static const GtkRadioActionEntry arrange_radio_entries[] = {
1167   { NAUTILUS_ACTION_MANUAL_LAYOUT, NULL,
1168     N_("_Manually"), NULL,
1169     N_("Leave icons wherever they are dropped"),
1170     NAUTILUS_FILE_SORT_NONE },
1171   { "Sort by Name", NULL,
1172     N_("By _Name"), NULL,
1173     N_("Keep icons sorted by name in rows"),
1174     NAUTILUS_FILE_SORT_BY_DISPLAY_NAME },
1175   { "Sort by Size", NULL,
1176     N_("By _Size"), NULL,
1177     N_("Keep icons sorted by size in rows"),
1178     NAUTILUS_FILE_SORT_BY_SIZE },
1179   { "Sort by Type", NULL,
1180     N_("By _Type"), NULL,
1181     N_("Keep icons sorted by type in rows"),
1182     NAUTILUS_FILE_SORT_BY_TYPE },
1183   { "Sort by Modification Date", NULL,
1184     N_("By Modification _Date"), NULL,
1185     N_("Keep icons sorted by modification date in rows"),
1186     NAUTILUS_FILE_SORT_BY_MTIME },
1187   { NAUTILUS_ACTION_SORT_TRASH_TIME, NULL,
1188     N_("By T_rash Time"), NULL,
1189     N_("Keep icons sorted by trash time in rows"),
1190     NAUTILUS_FILE_SORT_BY_TRASHED_TIME },
1191   { NAUTILUS_ACTION_SORT_SEARCH_RELEVANCE, NULL,
1192     N_("By Search Relevance"), NULL,
1193     N_("Keep icons sorted by search relevance in rows"),
1194     NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE },
1195 };
1196 
1197 static void
1198 nautilus_canvas_view_merge_menus (NautilusView *view)
1199 {
1200 	NautilusCanvasView *canvas_view;
1201 	GtkUIManager *ui_manager;
1202 	GtkActionGroup *action_group;
1203 	
1204         g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
1205 
1206 	NAUTILUS_VIEW_CLASS (nautilus_canvas_view_parent_class)->merge_menus (view);
1207 
1208 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
1209 
1210 	ui_manager = nautilus_view_get_ui_manager (NAUTILUS_VIEW (canvas_view));
1211 
1212 	action_group = gtk_action_group_new ("CanvasViewActions");
1213 	gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1214 	canvas_view->details->canvas_action_group = action_group;
1215 	gtk_action_group_add_toggle_actions (action_group, 
1216 					     canvas_view_toggle_entries, G_N_ELEMENTS (canvas_view_toggle_entries),
1217 					     canvas_view);
1218 	gtk_action_group_add_radio_actions (action_group,
1219 					    arrange_radio_entries,
1220 					    G_N_ELEMENTS (arrange_radio_entries),
1221 					    -1,
1222 					    G_CALLBACK (action_sort_radio_callback),
1223 					    canvas_view);
1224  
1225 	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
1226 	g_object_unref (action_group); /* owned by ui manager */
1227 
1228 	canvas_view->details->canvas_merge_id =
1229 		gtk_ui_manager_add_ui_from_resource (ui_manager, "/org/gnome/nautilus/nautilus-canvas-view-ui.xml", NULL);
1230 
1231 	update_layout_menus (canvas_view);
1232 }
1233 
1234 static void
1235 nautilus_canvas_view_unmerge_menus (NautilusView *view)
1236 {
1237 	NautilusCanvasView *canvas_view;
1238 	GtkUIManager *ui_manager;
1239 
1240 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
1241 
1242 	NAUTILUS_VIEW_CLASS (nautilus_canvas_view_parent_class)->unmerge_menus (view);
1243 
1244 	ui_manager = nautilus_view_get_ui_manager (view);
1245 	if (ui_manager != NULL) {
1246 		nautilus_ui_unmerge_ui (ui_manager,
1247 					&canvas_view->details->canvas_merge_id,
1248 					&canvas_view->details->canvas_action_group);
1249 	}
1250 }
1251 
1252 static void
1253 nautilus_canvas_view_update_menus (NautilusView *view)
1254 {
1255 	NautilusCanvasView *canvas_view;
1256 	GtkAction *action;
1257 	gboolean editable;
1258 
1259         canvas_view = NAUTILUS_CANVAS_VIEW (view);
1260 
1261 	NAUTILUS_VIEW_CLASS (nautilus_canvas_view_parent_class)->update_menus(view);
1262 
1263 	editable = nautilus_view_is_editable (view);
1264 	action = gtk_action_group_get_action (canvas_view->details->canvas_action_group,
1265 					      NAUTILUS_ACTION_MANUAL_LAYOUT);
1266 	gtk_action_set_sensitive (action, editable);
1267 }
1268 
1269 static void
1270 nautilus_canvas_view_reset_to_defaults (NautilusView *view)
1271 {
1272 	NautilusCanvasContainer *canvas_container;
1273 	NautilusCanvasView *canvas_view;
1274 
1275 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
1276 	canvas_container = get_canvas_container (canvas_view);
1277 
1278 	clear_sort_criterion (canvas_view);
1279 	nautilus_canvas_container_set_keep_aligned 
1280 		(canvas_container, get_default_directory_keep_aligned ());
1281 
1282 	nautilus_canvas_container_sort (canvas_container);
1283 
1284 	update_layout_menus (canvas_view);
1285 
1286 	nautilus_canvas_view_restore_default_zoom_level (view);
1287 }
1288 
1289 static void
1290 nautilus_canvas_view_select_all (NautilusView *view)
1291 {
1292 	NautilusCanvasContainer *canvas_container;
1293 
1294 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
1295 
1296 	canvas_container = get_canvas_container (NAUTILUS_CANVAS_VIEW (view));
1297         nautilus_canvas_container_select_all (canvas_container);
1298 }
1299 
1300 static void
1301 nautilus_canvas_view_select_first (NautilusView *view)
1302 {
1303 	NautilusCanvasContainer *canvas_container;
1304 
1305 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
1306 
1307 	canvas_container = get_canvas_container (NAUTILUS_CANVAS_VIEW (view));
1308         nautilus_canvas_container_select_first (canvas_container);
1309 }
1310 
1311 static void
1312 nautilus_canvas_view_reveal_selection (NautilusView *view)
1313 {
1314 	GList *selection;
1315 
1316 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
1317 
1318         selection = nautilus_view_get_selection (view);
1319 
1320 	/* Make sure at least one of the selected items is scrolled into view */
1321 	if (selection != NULL) {
1322 		nautilus_canvas_container_reveal 
1323 			(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)), 
1324 			 selection->data);
1325 	}
1326 
1327         nautilus_file_list_free (selection);
1328 }
1329 
1330 static GArray *
1331 nautilus_canvas_view_get_selected_icon_locations (NautilusView *view)
1332 {
1333 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
1334 
1335 	return nautilus_canvas_container_get_selected_icon_locations
1336 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)));
1337 }
1338 
1339 
1340 static void
1341 nautilus_canvas_view_set_selection (NautilusView *view, GList *selection)
1342 {
1343 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
1344 
1345 	nautilus_canvas_container_set_selection
1346 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)), selection);
1347 }
1348 
1349 static void
1350 nautilus_canvas_view_invert_selection (NautilusView *view)
1351 {
1352 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (view));
1353 
1354 	nautilus_canvas_container_invert_selection
1355 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)));
1356 }
1357 
1358 static gboolean
1359 nautilus_canvas_view_using_manual_layout (NautilusView *view)
1360 {
1361 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), FALSE);
1362 
1363 	return !nautilus_canvas_view_using_auto_layout (NAUTILUS_CANVAS_VIEW (view));
1364 }
1365 
1366 static void
1367 nautilus_canvas_view_widget_to_file_operation_position (NautilusView *view,
1368 						GdkPoint *position)
1369 {
1370 	g_assert (NAUTILUS_IS_CANVAS_VIEW (view));
1371 
1372 	nautilus_canvas_container_widget_to_file_operation_position
1373 		(get_canvas_container (NAUTILUS_CANVAS_VIEW (view)), position);
1374 }
1375 
1376 static void
1377 canvas_container_activate_callback (NautilusCanvasContainer *container,
1378 				  GList *file_list,
1379 				  NautilusCanvasView *canvas_view)
1380 {
1381 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1382 	g_assert (container == get_canvas_container (canvas_view));
1383 
1384 	nautilus_view_activate_files (NAUTILUS_VIEW (canvas_view),
1385 				      file_list, 
1386 				      0, TRUE);
1387 }
1388 
1389 static void
1390 canvas_container_activate_previewer_callback (NautilusCanvasContainer *container,
1391 					    GList *file_list,
1392 					    GArray *locations,
1393 					    NautilusCanvasView *canvas_view)
1394 {
1395 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1396 	g_assert (container == get_canvas_container (canvas_view));
1397 
1398 	nautilus_view_preview_files (NAUTILUS_VIEW (canvas_view),
1399 				     file_list, locations);
1400 }
1401 
1402 /* this is called in one of these cases:
1403  * - we activate with enter holding shift
1404  * - we activate with space holding shift
1405  * - we double click an canvas holding shift
1406  * - we middle click an canvas
1407  *
1408  * If we don't open in new windows by default, the behavior should be
1409  * - middle click, shift + activate -> open in new tab
1410  * - shift + double click -> open in new window
1411  *
1412  * If we open in new windows by default, the behaviour should be
1413  * - middle click, or shift + activate, or shift + double-click -> close parent
1414  */
1415 static void
1416 canvas_container_activate_alternate_callback (NautilusCanvasContainer *container,
1417 					    GList *file_list,
1418 					    NautilusCanvasView *canvas_view)
1419 {
1420 	GdkEvent *event;
1421 	GdkEventButton *button_event;
1422 	GdkEventKey *key_event;
1423 	gboolean open_in_tab, open_in_window, close_behind;
1424 	NautilusWindowOpenFlags flags;
1425 
1426 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1427 	g_assert (container == get_canvas_container (canvas_view));
1428 
1429 	flags = 0;
1430 	event = gtk_get_current_event ();
1431 	open_in_tab = FALSE;
1432 	open_in_window = FALSE;
1433 	close_behind = FALSE;
1434 
1435 	if (event->type == GDK_BUTTON_PRESS ||
1436 	    event->type == GDK_BUTTON_RELEASE ||
1437 	    event->type == GDK_2BUTTON_PRESS ||
1438 	    event->type == GDK_3BUTTON_PRESS) {
1439 		button_event = (GdkEventButton *) event;
1440 		open_in_window = ((button_event->state & GDK_SHIFT_MASK) != 0);
1441 		open_in_tab = !open_in_window;
1442 	} else if (event->type == GDK_KEY_PRESS ||
1443 		   event->type == GDK_KEY_RELEASE) {
1444 		key_event = (GdkEventKey *) event;
1445 		open_in_tab = ((key_event->state & GDK_SHIFT_MASK) != 0);
1446 	}
1447 
1448 	if (open_in_tab) {
1449 		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
1450 	}
1451 
1452 	if (open_in_window) {
1453 		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
1454 	}
1455 
1456 	if (close_behind) {
1457 		flags |= NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
1458 	}
1459 
1460 	DEBUG ("Activate alternate, open in tab %d, close behind %d, new window %d\n",
1461 	       open_in_tab, close_behind, open_in_window);
1462 
1463 	nautilus_view_activate_files (NAUTILUS_VIEW (canvas_view), 
1464 				      file_list, 
1465 				      flags,
1466 				      TRUE);
1467 }
1468 
1469 static void
1470 band_select_started_callback (NautilusCanvasContainer *container,
1471 			      NautilusCanvasView *canvas_view)
1472 {
1473 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1474 	g_assert (container == get_canvas_container (canvas_view));
1475 
1476 	nautilus_view_start_batching_selection_changes (NAUTILUS_VIEW (canvas_view));
1477 }
1478 
1479 static void
1480 band_select_ended_callback (NautilusCanvasContainer *container,
1481 			    NautilusCanvasView *canvas_view)
1482 {
1483 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1484 	g_assert (container == get_canvas_container (canvas_view));
1485 
1486 	nautilus_view_stop_batching_selection_changes (NAUTILUS_VIEW (canvas_view));
1487 }
1488 
1489 int
1490 nautilus_canvas_view_compare_files (NautilusCanvasView   *canvas_view,
1491 				  NautilusFile *a,
1492 				  NautilusFile *b)
1493 {
1494 	return nautilus_file_compare_for_sort
1495 		(a, b, canvas_view->details->sort->sort_type,
1496 		 /* Use type-unsafe cast for performance */
1497 		 nautilus_view_should_sort_directories_first ((NautilusView *)canvas_view),
1498 		 canvas_view->details->sort_reversed);
1499 }
1500 
1501 static int
1502 compare_files (NautilusView   *canvas_view,
1503 	       NautilusFile *a,
1504 	       NautilusFile *b)
1505 {
1506 	return nautilus_canvas_view_compare_files ((NautilusCanvasView *)canvas_view, a, b);
1507 }
1508 
1509 
1510 void
1511 nautilus_canvas_view_filter_by_screen (NautilusCanvasView *canvas_view,
1512 				     gboolean filter)
1513 {
1514 	canvas_view->details->filter_by_screen = filter;
1515 	canvas_view->details->num_screens = gdk_display_get_n_screens (gtk_widget_get_display (GTK_WIDGET (canvas_view)));
1516 }
1517 
1518 static void
1519 nautilus_canvas_view_screen_changed (GtkWidget *widget,
1520 				   GdkScreen *previous_screen)
1521 {
1522 	NautilusView *view;
1523 	GList *files, *l;
1524 	NautilusFile *file;
1525 	NautilusDirectory *directory;
1526 	NautilusCanvasContainer *canvas_container;
1527 
1528 	if (GTK_WIDGET_CLASS (nautilus_canvas_view_parent_class)->screen_changed) {
1529 		GTK_WIDGET_CLASS (nautilus_canvas_view_parent_class)->screen_changed (widget, previous_screen);
1530 	}
1531 
1532 	view = NAUTILUS_VIEW (widget);
1533 	if (NAUTILUS_CANVAS_VIEW (view)->details->filter_by_screen) {
1534 		canvas_container = get_canvas_container (NAUTILUS_CANVAS_VIEW (view));
1535 
1536 		directory = nautilus_view_get_model (view);
1537 		files = nautilus_directory_get_file_list (directory);
1538 
1539 		for (l = files; l != NULL; l = l->next) {
1540 			file = l->data;
1541 			
1542 			if (!should_show_file_on_screen (view, file)) {
1543 				nautilus_canvas_view_remove_file (view, file, directory);
1544 			} else {
1545 				if (nautilus_canvas_container_add (canvas_container,
1546 								 NAUTILUS_CANVAS_ICON_DATA (file))) {
1547 					nautilus_file_ref (file);
1548 				}
1549 			}
1550 		}
1551 		
1552 		nautilus_file_list_unref (files);
1553 		g_list_free (files);
1554 	}
1555 }
1556 
1557 static void
1558 selection_changed_callback (NautilusCanvasContainer *container,
1559 			    NautilusCanvasView *canvas_view)
1560 {
1561 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1562 	g_assert (container == get_canvas_container (canvas_view));
1563 
1564 	nautilus_view_notify_selection_changed (NAUTILUS_VIEW (canvas_view));
1565 }
1566 
1567 static void
1568 canvas_container_context_click_selection_callback (NautilusCanvasContainer *container,
1569 						 GdkEventButton *event,
1570 						 NautilusCanvasView *canvas_view)
1571 {
1572 	g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
1573 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1574 
1575 	nautilus_view_pop_up_selection_context_menu 
1576 		(NAUTILUS_VIEW (canvas_view), event);
1577 }
1578 
1579 static void
1580 canvas_container_context_click_background_callback (NautilusCanvasContainer *container,
1581 						  GdkEventButton *event,
1582 						  NautilusCanvasView *canvas_view)
1583 {
1584 	g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
1585 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1586 
1587 	nautilus_view_pop_up_background_context_menu 
1588 		(NAUTILUS_VIEW (canvas_view), event);
1589 }
1590 
1591 static gboolean
1592 nautilus_canvas_view_react_to_canvas_change_idle_callback (gpointer data) 
1593 {        
1594         NautilusCanvasView *canvas_view;
1595         
1596         g_assert (NAUTILUS_IS_CANVAS_VIEW (data));
1597         
1598         canvas_view = NAUTILUS_CANVAS_VIEW (data);
1599         canvas_view->details->react_to_canvas_change_idle_id = 0;
1600         
1601 	/* Rebuild the menus since some of them (e.g. Restore Stretched Icons)
1602 	 * may be different now.
1603 	 */
1604 	nautilus_view_update_menus (NAUTILUS_VIEW (canvas_view));
1605 
1606         /* Don't call this again (unless rescheduled) */
1607         return FALSE;
1608 }
1609 
1610 static void
1611 icon_position_changed_callback (NautilusCanvasContainer *container,
1612 				NautilusFile *file,
1613 				const NautilusCanvasPosition *position,
1614 				NautilusCanvasView *canvas_view)
1615 {
1616 	char *position_string;
1617 	char scale_string[G_ASCII_DTOSTR_BUF_SIZE];
1618 
1619 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1620 	g_assert (container == get_canvas_container (canvas_view));
1621 	g_assert (NAUTILUS_IS_FILE (file));
1622 
1623 	/* Schedule updating menus for the next idle. Doing it directly here
1624 	 * noticeably slows down canvas stretching.  The other work here to
1625 	 * store the canvas position and scale does not seem to noticeably
1626 	 * slow down canvas stretching. It would be trickier to move to an
1627 	 * idle call, because we'd have to keep track of potentially multiple
1628 	 * sets of file/geometry info.
1629 	 */
1630 	if (nautilus_view_get_active (NAUTILUS_VIEW (canvas_view)) &&
1631 	    canvas_view->details->react_to_canvas_change_idle_id == 0) {
1632                 canvas_view->details->react_to_canvas_change_idle_id
1633                         = g_idle_add (nautilus_canvas_view_react_to_canvas_change_idle_callback,
1634 				      canvas_view);
1635 	}
1636 
1637 	/* Store the new position of the canvas in the metadata. */
1638 	if (!nautilus_canvas_view_using_auto_layout (canvas_view)) {
1639 		position_string = g_strdup_printf
1640 			("%d,%d", position->x, position->y);
1641 		nautilus_file_set_metadata
1642 			(file, NAUTILUS_METADATA_KEY_ICON_POSITION, 
1643 			 NULL, position_string);
1644 		g_free (position_string);
1645 	}
1646 
1647 
1648 	g_ascii_dtostr (scale_string, sizeof (scale_string), position->scale);
1649 	nautilus_file_set_metadata
1650 		(file, NAUTILUS_METADATA_KEY_ICON_SCALE,
1651 		 "1.0", scale_string);
1652 }
1653 
1654 /* Attempt to change the filename to the new text.  Notify user if operation fails. */
1655 static void
1656 icon_rename_ended_cb (NautilusCanvasContainer *container,
1657 		      NautilusFile *file,				    
1658 		      const char *new_name,
1659 		      NautilusCanvasView *canvas_view)
1660 {
1661 	g_assert (NAUTILUS_IS_FILE (file));
1662 
1663 	nautilus_view_set_is_renaming (NAUTILUS_VIEW (canvas_view), FALSE);
1664 
1665 	/* Don't allow a rename with an empty string. Revert to original 
1666 	 * without notifying the user.
1667 	 */
1668 	if ((new_name == NULL) || (new_name[0] == '\0')) {
1669 		return;
1670 	}
1671 
1672 	nautilus_rename_file (file, new_name, NULL, NULL);
1673 }
1674 
1675 static void
1676 icon_rename_started_cb (NautilusCanvasContainer *container,
1677 			GtkWidget *widget,
1678 			gpointer callback_data)
1679 {
1680 	NautilusView *directory_view;
1681 
1682 	directory_view = NAUTILUS_VIEW (callback_data);
1683 	nautilus_clipboard_set_up_editable
1684 		(GTK_EDITABLE (widget),
1685 		 nautilus_view_get_ui_manager (directory_view),
1686 		 FALSE);
1687 }
1688 
1689 static char *
1690 get_icon_uri_callback (NautilusCanvasContainer *container,
1691 		       NautilusFile *file,
1692 		       NautilusCanvasView *canvas_view)
1693 {
1694 	g_assert (NAUTILUS_IS_CANVAS_CONTAINER (container));
1695 	g_assert (NAUTILUS_IS_FILE (file));
1696 	g_assert (NAUTILUS_IS_CANVAS_VIEW (canvas_view));
1697 
1698 	return nautilus_file_get_uri (file);
1699 }
1700 
1701 static char *
1702 get_icon_drop_target_uri_callback (NautilusCanvasContainer *container,
1703 		       		   NautilusFile *file,
1704 		       		   NautilusCanvasView *canvas_view)
1705 {
1706 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_CONTAINER (container), NULL);
1707 	g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
1708 	g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (canvas_view), NULL);
1709 
1710 	return nautilus_file_get_drop_target_uri (file);
1711 }
1712 
1713 /* Preferences changed callbacks */
1714 static void
1715 nautilus_canvas_view_click_policy_changed (NautilusView *directory_view)
1716 {
1717 	g_assert (NAUTILUS_IS_CANVAS_VIEW (directory_view));
1718 
1719 	nautilus_canvas_view_update_click_mode (NAUTILUS_CANVAS_VIEW (directory_view));
1720 }
1721 
1722 static void
1723 image_display_policy_changed_callback (gpointer callback_data)
1724 {
1725 	NautilusCanvasView *canvas_view;
1726 
1727 	canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
1728 
1729 	nautilus_canvas_container_request_update_all (get_canvas_container (canvas_view));
1730 }
1731 
1732 static void
1733 text_attribute_names_changed_callback (gpointer callback_data)
1734 {
1735 	NautilusCanvasView *canvas_view;
1736 
1737 	canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
1738 
1739 	nautilus_canvas_container_request_update_all (get_canvas_container (canvas_view));
1740 }
1741 
1742 static void
1743 default_sort_order_changed_callback (gpointer callback_data)
1744 {
1745 	NautilusCanvasView *canvas_view;
1746 	NautilusFile *file;
1747 	char *sort_name;
1748 	NautilusCanvasContainer *canvas_container;
1749 
1750 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (callback_data));
1751 
1752 	canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
1753 
1754 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
1755 	sort_name = nautilus_canvas_view_get_directory_sort_by (canvas_view, file);
1756 	set_sort_criterion (canvas_view, get_sort_criterion_by_metadata_text (sort_name), FALSE);
1757 	g_free (sort_name);
1758 
1759 	canvas_container = get_canvas_container (canvas_view);
1760 	g_return_if_fail (NAUTILUS_IS_CANVAS_CONTAINER (canvas_container));
1761 
1762 	nautilus_canvas_container_request_update_all (canvas_container);
1763 }
1764 
1765 static void
1766 default_sort_in_reverse_order_changed_callback (gpointer callback_data)
1767 {
1768 	NautilusCanvasView *canvas_view;
1769 	NautilusFile *file;
1770 	NautilusCanvasContainer *canvas_container;
1771 
1772 	g_return_if_fail (NAUTILUS_IS_CANVAS_VIEW (callback_data));
1773 
1774 	canvas_view = NAUTILUS_CANVAS_VIEW (callback_data);
1775 
1776 	file = nautilus_view_get_directory_as_file (NAUTILUS_VIEW (canvas_view));
1777 	set_sort_reversed (canvas_view, nautilus_canvas_view_get_directory_sort_reversed (canvas_view, file), FALSE);
1778 	canvas_container = get_canvas_container (canvas_view);
1779 	g_return_if_fail (NAUTILUS_IS_CANVAS_CONTAINER (canvas_container));
1780 
1781 	nautilus_canvas_container_request_update_all (canvas_container);
1782 }
1783 
1784 static void
1785 nautilus_canvas_view_sort_directories_first_changed (NautilusView *directory_view)
1786 {
1787 	NautilusCanvasView *canvas_view;
1788 
1789 	canvas_view = NAUTILUS_CANVAS_VIEW (directory_view);
1790 
1791 	if (nautilus_canvas_view_using_auto_layout (canvas_view)) {
1792 		nautilus_canvas_container_sort 
1793 			(get_canvas_container (canvas_view));
1794 	}
1795 }
1796 
1797 static gboolean
1798 canvas_view_can_accept_item (NautilusCanvasContainer *container,
1799 			   NautilusFile *target_item,
1800 			   const char *item_uri,
1801 			   NautilusView *view)
1802 {
1803 	return nautilus_drag_can_accept_item (target_item, item_uri);
1804 }
1805 
1806 static char *
1807 canvas_view_get_container_uri (NautilusCanvasContainer *container,
1808 			     NautilusView *view)
1809 {
1810 	return nautilus_view_get_uri (view);
1811 }
1812 
1813 static void
1814 canvas_view_move_copy_items (NautilusCanvasContainer *container,
1815 			   const GList *item_uris,
1816 			   GArray *relative_item_points,
1817 			   const char *target_dir,
1818 			   int copy_action,
1819 			   int x, int y,
1820 			   NautilusView *view)
1821 {
1822 	nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
1823 						    item_uris,
1824 						    nautilus_view_get_copied_files_atom (view));
1825 	nautilus_view_move_copy_items (view, item_uris, relative_item_points, target_dir,
1826 				       copy_action, x, y);
1827 }
1828 
1829 static void
1830 nautilus_canvas_view_update_click_mode (NautilusCanvasView *canvas_view)
1831 {
1832 	NautilusCanvasContainer	*canvas_container;
1833 	int			click_mode;
1834 
1835 	canvas_container = get_canvas_container (canvas_view);
1836 	g_assert (canvas_container != NULL);
1837 
1838 	click_mode = g_settings_get_enum (nautilus_preferences, NAUTILUS_PREFERENCES_CLICK_POLICY);
1839 
1840 	nautilus_canvas_container_set_single_click_mode (canvas_container,
1841 						       click_mode == NAUTILUS_CLICK_POLICY_SINGLE);
1842 }
1843 
1844 static gboolean
1845 get_stored_layout_timestamp (NautilusCanvasContainer *container,
1846 			     NautilusCanvasIconData *icon_data,
1847 			     time_t *timestamp,
1848 			     NautilusCanvasView *view)
1849 {
1850 	NautilusFile *file;
1851 	NautilusDirectory *directory;
1852 
1853 	if (icon_data == NULL) {
1854 		directory = nautilus_view_get_model (NAUTILUS_VIEW (view));
1855 		if (directory == NULL) {
1856 			return FALSE;
1857 		}
1858 
1859 		file = nautilus_directory_get_corresponding_file (directory);
1860 		*timestamp = nautilus_file_get_time_metadata (file,
1861 							      NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP);
1862 		nautilus_file_unref (file);
1863 	} else {
1864 		*timestamp = nautilus_file_get_time_metadata (NAUTILUS_FILE (icon_data),
1865 							      NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP);
1866 	}
1867 
1868 	return TRUE;
1869 }
1870 
1871 static gboolean
1872 store_layout_timestamp (NautilusCanvasContainer *container,
1873 			NautilusCanvasIconData *icon_data,
1874 			const time_t *timestamp,
1875 			NautilusCanvasView *view)
1876 {
1877 	NautilusFile *file;
1878 	NautilusDirectory *directory;
1879 
1880 	if (icon_data == NULL) {
1881 		directory = nautilus_view_get_model (NAUTILUS_VIEW (view));
1882 		if (directory == NULL) {
1883 			return FALSE;
1884 		}
1885 
1886 		file = nautilus_directory_get_corresponding_file (directory);
1887 		nautilus_file_set_time_metadata (file,
1888 						 NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP,
1889 						 (time_t) *timestamp);
1890 		nautilus_file_unref (file);
1891 	} else {
1892 		nautilus_file_set_time_metadata (NAUTILUS_FILE (icon_data),
1893 						 NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
1894 						 (time_t) *timestamp);
1895 	}
1896 
1897 	return TRUE;
1898 }
1899 
1900 static NautilusCanvasContainer *
1901 create_canvas_container (NautilusCanvasView *canvas_view)
1902 {
1903 	NautilusCanvasContainer *canvas_container;
1904 
1905 	canvas_container = nautilus_canvas_view_container_new (canvas_view);
1906 	canvas_view->details->canvas_container = GTK_WIDGET (canvas_container);
1907 	g_object_add_weak_pointer (G_OBJECT (canvas_container),
1908 				   (gpointer *) &canvas_view->details->canvas_container);
1909 	
1910 	gtk_widget_set_can_focus (GTK_WIDGET (canvas_container), TRUE);
1911 	
1912 	g_signal_connect_object (canvas_container, "activate",	
1913 				 G_CALLBACK (canvas_container_activate_callback), canvas_view, 0);
1914 	g_signal_connect_object (canvas_container, "activate_alternate",	
1915 				 G_CALLBACK (canvas_container_activate_alternate_callback), canvas_view, 0);
1916 	g_signal_connect_object (canvas_container, "activate_previewer",
1917 				 G_CALLBACK (canvas_container_activate_previewer_callback), canvas_view, 0);
1918 	g_signal_connect_object (canvas_container, "band_select_started",
1919 				 G_CALLBACK (band_select_started_callback), canvas_view, 0);
1920 	g_signal_connect_object (canvas_container, "band_select_ended",
1921 				 G_CALLBACK (band_select_ended_callback), canvas_view, 0);
1922 	g_signal_connect_object (canvas_container, "context_click_selection",
1923 				 G_CALLBACK (canvas_container_context_click_selection_callback), canvas_view, 0);
1924 	g_signal_connect_object (canvas_container, "context_click_background",
1925 				 G_CALLBACK (canvas_container_context_click_background_callback), canvas_view, 0);
1926 	g_signal_connect_object (canvas_container, "icon_position_changed",
1927 				 G_CALLBACK (icon_position_changed_callback), canvas_view, 0);
1928 	g_signal_connect_object (canvas_container, "selection_changed",
1929 				 G_CALLBACK (selection_changed_callback), canvas_view, 0);
1930 	/* FIXME: many of these should move into fm-canvas-container as virtual methods */
1931 	g_signal_connect_object (canvas_container, "get_icon_uri",
1932 				 G_CALLBACK (get_icon_uri_callback), canvas_view, 0);
1933 	g_signal_connect_object (canvas_container, "get_icon_drop_target_uri",
1934 				 G_CALLBACK (get_icon_drop_target_uri_callback), canvas_view, 0);
1935 	g_signal_connect_object (canvas_container, "move_copy_items",
1936 				 G_CALLBACK (canvas_view_move_copy_items), canvas_view, 0);
1937 	g_signal_connect_object (canvas_container, "get_container_uri",
1938 				 G_CALLBACK (canvas_view_get_container_uri), canvas_view, 0);
1939 	g_signal_connect_object (canvas_container, "can_accept_item",
1940 				 G_CALLBACK (canvas_view_can_accept_item), canvas_view, 0);
1941 	g_signal_connect_object (canvas_container, "get_stored_icon_position",
1942 				 G_CALLBACK (get_stored_icon_position_callback), canvas_view, 0);
1943 	g_signal_connect_object (canvas_container, "layout_changed",
1944 				 G_CALLBACK (layout_changed_callback), canvas_view, 0);
1945 	g_signal_connect_object (canvas_container, "icon_rename_started",
1946 				 G_CALLBACK (icon_rename_started_cb), canvas_view, 0);
1947 	g_signal_connect_object (canvas_container, "icon_rename_ended",
1948 				 G_CALLBACK (icon_rename_ended_cb), canvas_view, 0);
1949 	g_signal_connect_object (canvas_container, "icon_stretch_started",
1950 				 G_CALLBACK (nautilus_view_update_menus), canvas_view,
1951 				 G_CONNECT_SWAPPED);
1952 	g_signal_connect_object (canvas_container, "icon_stretch_ended",
1953 				 G_CALLBACK (nautilus_view_update_menus), canvas_view,
1954 				 G_CONNECT_SWAPPED);
1955 
1956 	g_signal_connect_object (canvas_container, "get_stored_layout_timestamp",
1957 				 G_CALLBACK (get_stored_layout_timestamp), canvas_view, 0);
1958 	g_signal_connect_object (canvas_container, "store_layout_timestamp",
1959 				 G_CALLBACK (store_layout_timestamp), canvas_view, 0);
1960 
1961 	gtk_container_add (GTK_CONTAINER (canvas_view),
1962 			   GTK_WIDGET (canvas_container));
1963 
1964 	nautilus_canvas_view_update_click_mode (canvas_view);
1965 	nautilus_canvas_container_set_zoom_level (canvas_container,
1966 						  get_default_zoom_level (canvas_view));
1967 
1968 	gtk_widget_show (GTK_WIDGET (canvas_container));
1969 
1970 	return canvas_container;
1971 }
1972 
1973 /* Handles an URL received from Mozilla */
1974 static void
1975 canvas_view_handle_netscape_url (NautilusCanvasContainer *container, const char *encoded_url,
1976 			       const char *target_uri,
1977 			       GdkDragAction action, int x, int y, NautilusCanvasView *view)
1978 {
1979 	nautilus_view_handle_netscape_url_drop (NAUTILUS_VIEW (view),
1980 						encoded_url, target_uri, action, x, y);
1981 }
1982 
1983 static void
1984 canvas_view_handle_uri_list (NautilusCanvasContainer *container, const char *item_uris,
1985 			   const char *target_uri,
1986 			   GdkDragAction action, int x, int y, NautilusCanvasView *view)
1987 {
1988 	nautilus_view_handle_uri_list_drop (NAUTILUS_VIEW (view),
1989 					    item_uris, target_uri, action, x, y);
1990 }
1991 
1992 static void
1993 canvas_view_handle_text (NautilusCanvasContainer *container, const char *text,
1994 		       const char *target_uri,
1995 		       GdkDragAction action, int x, int y, NautilusCanvasView *view)
1996 {
1997 	nautilus_view_handle_text_drop (NAUTILUS_VIEW (view),
1998 					text, target_uri, action, x, y);
1999 }
2000 
2001 static void
2002 canvas_view_handle_raw (NautilusCanvasContainer *container, const char *raw_data,
2003 		      int length, const char *target_uri, const char *direct_save_uri,
2004 		      GdkDragAction action, int x, int y, NautilusCanvasView *view)
2005 {
2006 	nautilus_view_handle_raw_drop (NAUTILUS_VIEW (view),
2007 				       raw_data, length, target_uri, direct_save_uri, action, x, y);
2008 }
2009 
2010 static char *
2011 canvas_view_get_first_visible_file (NautilusView *view)
2012 {
2013 	NautilusFile *file;
2014 	NautilusCanvasView *canvas_view;
2015 
2016 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
2017 
2018 	file = NAUTILUS_FILE (nautilus_canvas_container_get_first_visible_icon (get_canvas_container (canvas_view)));
2019 
2020 	if (file) {
2021 		return nautilus_file_get_uri (file);
2022 	}
2023 	
2024 	return NULL;
2025 }
2026 
2027 static void
2028 canvas_view_scroll_to_file (NautilusView *view,
2029 			  const char *uri)
2030 {
2031 	NautilusFile *file;
2032 	NautilusCanvasView *canvas_view;
2033 
2034 	canvas_view = NAUTILUS_CANVAS_VIEW (view);
2035 	
2036 	if (uri != NULL) {
2037 		/* Only if existing, since we don't want to add the file to
2038 		   the directory if it has been removed since then */
2039 		file = nautilus_file_get_existing_by_uri (uri);
2040 		if (file != NULL) {
2041 			nautilus_canvas_container_scroll_to_canvas (get_canvas_container (canvas_view),
2042 								NAUTILUS_CANVAS_ICON_DATA (file));
2043 			nautilus_file_unref (file);
2044 		}
2045 	}
2046 }
2047 
2048 static const char *
2049 nautilus_canvas_view_get_id (NautilusView *view)
2050 {
2051 	return NAUTILUS_CANVAS_VIEW_ID;
2052 }
2053 
2054 static void
2055 nautilus_canvas_view_set_property (GObject         *object,
2056 			   guint            prop_id,
2057 			   const GValue    *value,
2058 			   GParamSpec      *pspec)
2059 {
2060 	NautilusCanvasView *canvas_view;
2061   
2062 	canvas_view = NAUTILUS_CANVAS_VIEW (object);
2063 
2064 	switch (prop_id)  {
2065 	case PROP_SUPPORTS_AUTO_LAYOUT:
2066 		canvas_view->details->supports_auto_layout = g_value_get_boolean (value);
2067 		break;
2068 	case PROP_SUPPORTS_MANUAL_LAYOUT:
2069 		canvas_view->details->supports_manual_layout = g_value_get_boolean (value);
2070 		break;
2071 	case PROP_SUPPORTS_SCALING:
2072 		canvas_view->details->supports_scaling = g_value_get_boolean (value);
2073 		break;
2074 	case PROP_SUPPORTS_KEEP_ALIGNED:
2075 		canvas_view->details->supports_keep_aligned = g_value_get_boolean (value);
2076 		break;
2077 	default:
2078 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2079 		break;
2080 	}
2081 }
2082 
2083 static void
2084 nautilus_canvas_view_finalize (GObject *object)
2085 {
2086 	NautilusCanvasView *canvas_view;
2087 
2088 	canvas_view = NAUTILUS_CANVAS_VIEW (object);
2089 
2090 	g_free (canvas_view->details);
2091 
2092 	g_signal_handlers_disconnect_by_func (nautilus_preferences,
2093 					      default_sort_order_changed_callback,
2094 					      canvas_view);
2095 	g_signal_handlers_disconnect_by_func (nautilus_preferences,
2096 					      default_sort_in_reverse_order_changed_callback,
2097 					      canvas_view);
2098 	g_signal_handlers_disconnect_by_func (nautilus_preferences,
2099 					      image_display_policy_changed_callback,
2100 					      canvas_view);
2101 
2102 	g_signal_handlers_disconnect_by_func (nautilus_icon_view_preferences,
2103 					      text_attribute_names_changed_callback,
2104 					      canvas_view);
2105 
2106 	G_OBJECT_CLASS (nautilus_canvas_view_parent_class)->finalize (object);
2107 }
2108 
2109 static void
2110 nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
2111 {
2112 	NautilusViewClass *nautilus_view_class;
2113 	GObjectClass *oclass;
2114 
2115 	nautilus_view_class = NAUTILUS_VIEW_CLASS (klass);
2116 	oclass = G_OBJECT_CLASS (klass);
2117 
2118 	oclass->set_property = nautilus_canvas_view_set_property;
2119 	oclass->finalize = nautilus_canvas_view_finalize;
2120 
2121 	GTK_WIDGET_CLASS (klass)->destroy = nautilus_canvas_view_destroy;
2122 	GTK_WIDGET_CLASS (klass)->screen_changed = nautilus_canvas_view_screen_changed;
2123 	
2124 	nautilus_view_class->add_file = nautilus_canvas_view_add_file;
2125 	nautilus_view_class->begin_loading = nautilus_canvas_view_begin_loading;
2126 	nautilus_view_class->bump_zoom_level = nautilus_canvas_view_bump_zoom_level;
2127 	nautilus_view_class->can_rename_file = nautilus_canvas_view_can_rename_file;
2128 	nautilus_view_class->can_zoom_in = nautilus_canvas_view_can_zoom_in;
2129 	nautilus_view_class->can_zoom_out = nautilus_canvas_view_can_zoom_out;
2130 	nautilus_view_class->clear = nautilus_canvas_view_clear;
2131 	nautilus_view_class->end_loading = nautilus_canvas_view_end_loading;
2132 	nautilus_view_class->file_changed = nautilus_canvas_view_file_changed;
2133 	nautilus_view_class->get_selected_icon_locations = nautilus_canvas_view_get_selected_icon_locations;
2134 	nautilus_view_class->get_selection = nautilus_canvas_view_get_selection;
2135 	nautilus_view_class->get_selection_for_file_transfer = nautilus_canvas_view_get_selection;
2136 	nautilus_view_class->is_empty = nautilus_canvas_view_is_empty;
2137 	nautilus_view_class->remove_file = nautilus_canvas_view_remove_file;
2138 	nautilus_view_class->reset_to_defaults = nautilus_canvas_view_reset_to_defaults;
2139 	nautilus_view_class->restore_default_zoom_level = nautilus_canvas_view_restore_default_zoom_level;
2140 	nautilus_view_class->reveal_selection = nautilus_canvas_view_reveal_selection;
2141 	nautilus_view_class->select_all = nautilus_canvas_view_select_all;
2142 	nautilus_view_class->select_first = nautilus_canvas_view_select_first;
2143 	nautilus_view_class->set_selection = nautilus_canvas_view_set_selection;
2144 	nautilus_view_class->invert_selection = nautilus_canvas_view_invert_selection;
2145 	nautilus_view_class->compare_files = compare_files;
2146 	nautilus_view_class->zoom_to_level = nautilus_canvas_view_zoom_to_level;
2147 	nautilus_view_class->get_zoom_level = nautilus_canvas_view_get_zoom_level;
2148         nautilus_view_class->click_policy_changed = nautilus_canvas_view_click_policy_changed;
2149         nautilus_view_class->merge_menus = nautilus_canvas_view_merge_menus;
2150         nautilus_view_class->unmerge_menus = nautilus_canvas_view_unmerge_menus;
2151         nautilus_view_class->sort_directories_first_changed = nautilus_canvas_view_sort_directories_first_changed;
2152         nautilus_view_class->start_renaming_file = nautilus_canvas_view_start_renaming_file;
2153         nautilus_view_class->update_menus = nautilus_canvas_view_update_menus;
2154 	nautilus_view_class->using_manual_layout = nautilus_canvas_view_using_manual_layout;
2155 	nautilus_view_class->widget_to_file_operation_position = nautilus_canvas_view_widget_to_file_operation_position;
2156 	nautilus_view_class->get_view_id = nautilus_canvas_view_get_id;
2157 	nautilus_view_class->get_first_visible_file = canvas_view_get_first_visible_file;
2158 	nautilus_view_class->scroll_to_file = canvas_view_scroll_to_file;
2159 
2160 	properties[PROP_SUPPORTS_AUTO_LAYOUT] =
2161 		g_param_spec_boolean ("supports-auto-layout",
2162 				      "Supports auto layout",
2163 				      "Whether this view supports auto layout",
2164 				      TRUE,
2165 				      G_PARAM_WRITABLE |
2166 				      G_PARAM_CONSTRUCT_ONLY);
2167 	properties[PROP_SUPPORTS_MANUAL_LAYOUT] =
2168 		g_param_spec_boolean ("supports-manual-layout",
2169 				      "Supports manual layout",
2170 				      "Whether this view supports manual layout",
2171 				      FALSE,
2172 				      G_PARAM_WRITABLE |
2173 				      G_PARAM_CONSTRUCT_ONLY);
2174 	properties[PROP_SUPPORTS_SCALING] =
2175 		g_param_spec_boolean ("supports-scaling",
2176 				      "Supports scaling",
2177 				      "Whether this view supports scaling",
2178 				      FALSE,
2179 				      G_PARAM_WRITABLE |
2180 				      G_PARAM_CONSTRUCT_ONLY);
2181 	properties[PROP_SUPPORTS_KEEP_ALIGNED] =
2182 		g_param_spec_boolean ("supports-keep-aligned",
2183 				      "Supports keep aligned",
2184 				      "Whether this view supports keep aligned",
2185 				      FALSE,
2186 				      G_PARAM_WRITABLE |
2187 				      G_PARAM_CONSTRUCT_ONLY);
2188 
2189 	g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
2190 }
2191 
2192 static void
2193 nautilus_canvas_view_init (NautilusCanvasView *canvas_view)
2194 {
2195 	NautilusCanvasContainer *canvas_container;
2196 
2197         g_return_if_fail (gtk_bin_get_child (GTK_BIN (canvas_view)) == NULL);
2198 
2199 	canvas_view->details = g_new0 (NautilusCanvasViewDetails, 1);
2200 	canvas_view->details->sort = &sort_criteria[0];
2201 	canvas_view->details->filter_by_screen = FALSE;
2202 
2203 	canvas_container = create_canvas_container (canvas_view);
2204 
2205 	/* Set our default layout mode */
2206 	nautilus_canvas_container_set_layout_mode (canvas_container,
2207 						 gtk_widget_get_direction (GTK_WIDGET(canvas_container)) == GTK_TEXT_DIR_RTL ?
2208 						 NAUTILUS_CANVAS_LAYOUT_R_L_T_B :
2209 						 NAUTILUS_CANVAS_LAYOUT_L_R_T_B);
2210 
2211 	g_signal_connect_swapped (nautilus_preferences,
2212 				  "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_ORDER,
2213 				  G_CALLBACK (default_sort_order_changed_callback),
2214 				  canvas_view);
2215 	g_signal_connect_swapped (nautilus_preferences,
2216 				  "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_IN_REVERSE_ORDER,
2217 				  G_CALLBACK (default_sort_in_reverse_order_changed_callback),
2218 				  canvas_view);
2219 	g_signal_connect_swapped (nautilus_preferences,
2220 				  "changed::" NAUTILUS_PREFERENCES_SHOW_FILE_THUMBNAILS,
2221 				  G_CALLBACK (image_display_policy_changed_callback),
2222 				  canvas_view);
2223 
2224 	g_signal_connect_swapped (nautilus_icon_view_preferences,
2225 				  "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
2226 				  G_CALLBACK (text_attribute_names_changed_callback),
2227 				  canvas_view);
2228 
2229 	g_signal_connect_object (get_canvas_container (canvas_view), "handle_netscape_url",
2230 				 G_CALLBACK (canvas_view_handle_netscape_url), canvas_view, 0);
2231 	g_signal_connect_object (get_canvas_container (canvas_view), "handle_uri_list",
2232 				 G_CALLBACK (canvas_view_handle_uri_list), canvas_view, 0);
2233 	g_signal_connect_object (get_canvas_container (canvas_view), "handle_text",
2234 				 G_CALLBACK (canvas_view_handle_text), canvas_view, 0);
2235 	g_signal_connect_object (get_canvas_container (canvas_view), "handle_raw",
2236 				 G_CALLBACK (canvas_view_handle_raw), canvas_view, 0);
2237 
2238 	canvas_view->details->clipboard_handler_id =
2239 		g_signal_connect (nautilus_clipboard_monitor_get (),
2240 		                  "clipboard_info",
2241 		                  G_CALLBACK (canvas_view_notify_clipboard_info), canvas_view);
2242 }
2243 
2244 static NautilusView *
2245 nautilus_canvas_view_create (NautilusWindowSlot *slot)
2246 {
2247 	NautilusCanvasView *view;
2248 
2249 	view = g_object_new (NAUTILUS_TYPE_CANVAS_VIEW,
2250 			     "window-slot", slot,
2251 			     NULL);
2252 	return NAUTILUS_VIEW (view);
2253 }
2254 
2255 static gboolean
2256 nautilus_canvas_view_supports_uri (const char *uri,
2257 			   GFileType file_type,
2258 			   const char *mime_type)
2259 {
2260 	if (file_type == G_FILE_TYPE_DIRECTORY) {
2261 		return TRUE;
2262 	}
2263 	if (strcmp (mime_type, NAUTILUS_SAVED_SEARCH_MIMETYPE) == 0){
2264 		return TRUE;
2265 	}
2266 	if (g_str_has_prefix (uri, "trash:")) {
2267 		return TRUE;
2268 	}
2269 	if (g_str_has_prefix (uri, EEL_SEARCH_URI)) {
2270 		return TRUE;
2271 	}
2272 
2273 	return FALSE;
2274 }
2275 
2276 #define TRANSLATE_VIEW_INFO(view_info)					\
2277 	view_info.view_combo_label = _(view_info.view_combo_label);	\
2278 	view_info.view_menu_label_with_mnemonic = _(view_info.view_menu_label_with_mnemonic); \
2279 	view_info.error_label = _(view_info.error_label);		\
2280 	view_info.startup_error_label = _(view_info.startup_error_label); \
2281 	view_info.display_location_label = _(view_info.display_location_label); \
2282 	
2283 
2284 static NautilusViewInfo nautilus_canvas_view = {
2285 	NAUTILUS_CANVAS_VIEW_ID,
2286 	/* translators: this is used in the view selection dropdown
2287 	 * of navigation windows and in the preferences dialog */
2288 	N_("Icon View"),
2289 	/* translators: this is used in the view menu */
2290 	N_("_Icons"),
2291 	N_("The icon view encountered an error."),
2292 	N_("The icon view encountered an error while starting up."),
2293 	N_("Display this location with the icon view."),
2294 	nautilus_canvas_view_create,
2295 	nautilus_canvas_view_supports_uri
2296 };
2297 
2298 void
2299 nautilus_canvas_view_register (void)
2300 {
2301 	TRANSLATE_VIEW_INFO (nautilus_canvas_view)
2302 		nautilus_view_factory_register (&nautilus_canvas_view);
2303 }