nautilus r14519 - in trunk: . libnautilus-private src/file-manager



Author: cneumair
Date: Sun Aug 24 20:44:34 2008
New Revision: 14519
URL: http://svn.gnome.org/viewvc/nautilus?rev=14519&view=rev

Log:
2008-08-24  Christian Neumair  <cneumair gnome org>

	* libnautilus-private/nautilus-directory.c
	(nautilus_directory_schedule_position_set):
	* libnautilus-private/nautilus-file.c (get_time_from_time_string),
	(nautilus_file_get_time_metadata),
	(nautilus_file_set_time_metadata):
	* libnautilus-private/nautilus-file.h:
	* libnautilus-private/nautilus-icon-container.c
	(lay_down_icons_vertical_desktop),
	(nautilus_icon_container_class_init),
	(nautilus_icon_container_instance_init),
	(nautilus_icon_container_clear), (finish_adding_new_icons),
	(is_old_or_unknown_icon_data), (nautilus_icon_container_add),
	(nautilus_icon_container_begin_loading),
	(store_layout_timestamps_now),
	(nautilus_icon_container_end_loading),
	(nautilus_icon_container_get_store_layout_timestamps),
	(nautilus_icon_container_set_store_layout_timestamps):
	* libnautilus-private/nautilus-icon-container.h:
	* libnautilus-private/nautilus-icon-dnd.c (handle_local_move):
	* libnautilus-private/nautilus-icon-private.h:
	* libnautilus-private/nautilus-metadata.h:
	* src/file-manager/fm-desktop-icon-view.c
	(fm_desktop_icon_view_init):
	* src/file-manager/fm-directory-view.c (done_loading),
	(display_pending_files), (fm_directory_view_end_loading),
	(fm_directory_view_stop), (fm_directory_view_class_init):
	* src/file-manager/fm-directory-view.h:
	* src/file-manager/fm-icon-view.c (fm_icon_view_add_file),
	(fm_icon_view_begin_loading), (fm_icon_view_end_loading),
	(fm_icon_view_screen_changed), (get_stored_layout_timestamp),
	(store_layout_timestamp), (create_icon_container):
	No more overlapping desktop icons.

	Implement a layout timestamp concept where each file on the desktop
	and the desktop directory itself is timestamped when a full layout
	happened. Iff files were not part of the last layout (or added more
	recently, through DND), they are treated as being âsemi-positionedâ
	(cf. 2005-11-07).
	This means that they may be freely shifted around, starting from their
	last position, until they don't overlap and fully laid out items.
	Should inter alia fix #330298.


Modified:
   trunk/ChangeLog
   trunk/libnautilus-private/nautilus-directory.c
   trunk/libnautilus-private/nautilus-file.c
   trunk/libnautilus-private/nautilus-file.h
   trunk/libnautilus-private/nautilus-icon-container.c
   trunk/libnautilus-private/nautilus-icon-container.h
   trunk/libnautilus-private/nautilus-icon-dnd.c
   trunk/libnautilus-private/nautilus-icon-private.h
   trunk/libnautilus-private/nautilus-metadata.h
   trunk/src/file-manager/fm-desktop-icon-view.c
   trunk/src/file-manager/fm-directory-view.c
   trunk/src/file-manager/fm-directory-view.h
   trunk/src/file-manager/fm-icon-view.c

Modified: trunk/libnautilus-private/nautilus-directory.c
==============================================================================
--- trunk/libnautilus-private/nautilus-directory.c	(original)
+++ trunk/libnautilus-private/nautilus-directory.c	Sun Aug 24 20:44:34 2008
@@ -1591,6 +1591,9 @@
 	const NautilusFileChangesQueuePosition *item;
 	NautilusFile *file;
 	char str[64];
+	time_t now;
+
+	time (&now);
 
 	for (p = position_setting_list; p != NULL; p = p->next) {
 		item = (NautilusFileChangesQueuePosition *) p->data;
@@ -1609,6 +1612,18 @@
 			 str);
 
 		if (item->set) {
+			nautilus_file_set_time_metadata
+				(file,
+				 NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
+				 now);
+		} else {
+			nautilus_file_set_time_metadata
+				(file,
+				 NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
+				 UNDEFINED_TIME);
+		}
+
+		if (item->set) {
 			g_snprintf (str, sizeof (str), "%d", item->screen);
 		} else {
 			str[0] = 0;

Modified: trunk/libnautilus-private/nautilus-file.c
==============================================================================
--- trunk/libnautilus-private/nautilus-file.c	(original)
+++ trunk/libnautilus-private/nautilus-file.c	Sun Aug 24 20:44:34 2008
@@ -2976,6 +2976,62 @@
 		 default_metadata);
 }
 
+static gboolean
+get_time_from_time_string (const char *time_string,
+			   time_t *time)
+{
+	long scanned_time;
+	char c;
+
+	g_assert (time != NULL);
+
+	/* Only accept string if it has one integer with nothing
+	 * afterwards.
+	 */
+	if (time_string == NULL ||
+	    sscanf (time_string, "%ld%c", &scanned_time, &c) != 1) {
+		return FALSE;
+	}
+	*time = (time_t) scanned_time;
+	return TRUE;
+}
+
+time_t
+nautilus_file_get_time_metadata (NautilusFile *file,
+				 const char   *key)
+{
+	time_t time;
+	char *time_string;
+
+	time_string = nautilus_file_get_metadata (file, key, NULL);
+	if (!get_time_from_time_string (time_string, &time)) {
+		time = UNDEFINED_TIME;
+	}
+	g_free (time_string);
+
+	return time;
+}
+
+void
+nautilus_file_set_time_metadata (NautilusFile *file,
+				 const char   *key,
+				 time_t        time)
+{
+	char time_str[21];
+	char *metadata;
+
+	if (time != UNDEFINED_TIME) {
+		/* 2^64 turns out to be 20 characters */
+		snprintf (time_str, 20, "%ld", time);
+		time_str[20] = '\0';
+		metadata = time_str;
+	} else {
+		metadata = NULL;
+	}
+
+	nautilus_file_set_metadata (file, key, NULL, metadata);
+}
+
 
 void
 nautilus_file_set_boolean_metadata (NautilusFile *file,

Modified: trunk/libnautilus-private/nautilus-file.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file.h	(original)
+++ trunk/libnautilus-private/nautilus-file.h	Sun Aug 24 20:44:34 2008
@@ -330,6 +330,14 @@
 									 int                             default_metadata,
 									 int                             metadata);
 
+#define UNDEFINED_TIME ((time_t) (-1))
+
+time_t                  nautilus_file_get_time_metadata                 (NautilusFile                  *file,
+									 const char                    *key);
+void                    nautilus_file_set_time_metadata                 (NautilusFile                  *file,
+									 const char                    *key,
+									 time_t                         time);
+
 
 /* Attributes for file objects as user-displayable strings. */
 char *                  nautilus_file_get_string_attribute              (NautilusFile                   *file,

Modified: trunk/libnautilus-private/nautilus-icon-container.c
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-container.c	(original)
+++ trunk/libnautilus-private/nautilus-icon-container.c	Sun Aug 24 20:44:34 2008
@@ -152,6 +152,9 @@
 /* Copied from NautilusIconContainer */
 #define NAUTILUS_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT 5000
 
+/* Copied from NautilusFile */
+#define UNDEFINED_TIME ((time_t) (-1))
+
 enum {
 	ACTION_ACTIVATE,
 	ACTION_MENU,
@@ -216,6 +219,8 @@
 								NautilusIcon *icon,
 								double x);
 
+static void store_layout_timestamps_now (NautilusIconContainer *container);
+
 static gpointer accessible_parent_class;
 
 static GQuark accessible_private_data_quark = 0;
@@ -251,6 +256,8 @@
 	GET_ICON_DROP_TARGET_URI,
 	GET_STORED_ICON_POSITION,
 	ICON_POSITION_CHANGED,
+	GET_STORED_LAYOUT_TIMESTAMP,
+	STORE_LAYOUT_TIMESTAMP,
 	ICON_TEXT_CHANGED,
 	ICON_STRETCH_STARTED,
 	ICON_STRETCH_ENDED,
@@ -1925,7 +1932,6 @@
 				/* Start the icon in the first column */
 				x = DESKTOP_PAD_HORIZONTAL + (SNAP_SIZE_X / 2) - ((icon_rect.x1 - icon_rect.x0) / 2);
 				y = DESKTOP_PAD_VERTICAL + SNAP_SIZE_Y - (icon_rect.y1 - icon_rect.y0);
-				g_message ("got rect y: %f", icon_rect.y1 - icon_rect.y0);
 
 				find_empty_location (container,
 						     grid,
@@ -5523,6 +5529,28 @@
 		                G_TYPE_BOOLEAN, 2,
 				G_TYPE_POINTER,
 				G_TYPE_POINTER);
+	signals[GET_STORED_LAYOUT_TIMESTAMP]
+		= g_signal_new ("get_stored_layout_timestamp",
+		                G_TYPE_FROM_CLASS (class),
+		                G_SIGNAL_RUN_LAST,
+		                G_STRUCT_OFFSET (NautilusIconContainerClass,
+						 get_stored_layout_timestamp),
+		                NULL, NULL,
+		                eel_marshal_BOOLEAN__POINTER_POINTER,
+		                G_TYPE_BOOLEAN, 2,
+				G_TYPE_POINTER,
+				G_TYPE_POINTER);
+	signals[STORE_LAYOUT_TIMESTAMP]
+		= g_signal_new ("store_layout_timestamp",
+		                G_TYPE_FROM_CLASS (class),
+		                G_SIGNAL_RUN_LAST,
+		                G_STRUCT_OFFSET (NautilusIconContainerClass,
+						 store_layout_timestamp),
+		                NULL, NULL,
+		                eel_marshal_BOOLEAN__POINTER_POINTER,
+		                G_TYPE_BOOLEAN, 2,
+				G_TYPE_POINTER,
+				G_TYPE_POINTER);
 	signals[LAYOUT_CHANGED]
 		= g_signal_new ("layout_changed",
 		                G_TYPE_FROM_CLASS (class),
@@ -5877,6 +5905,7 @@
 	details = g_new0 (NautilusIconContainerDetails, 1);
 
 	details->icon_set = g_hash_table_new (g_direct_hash, g_direct_equal);
+	details->layout_timestamp = UNDEFINED_TIME;
 
         details->zoom_level = NAUTILUS_ZOOM_LEVEL_STANDARD;
 
@@ -6113,6 +6142,8 @@
 	g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container));
 
 	details = container->details;
+	details->layout_timestamp = UNDEFINED_TIME;
+	details->store_layout_timestamps_when_finishing_new_icons = FALSE;
 
 	if (details->icons == NULL) {
 		return;
@@ -6747,13 +6778,12 @@
 	no_position_icons = semi_position_icons = NULL;
 	for (p = new_icons; p != NULL; p = p->next) {
 		icon = p->data;
-                if (assign_icon_position (container, icon)) {
-                        if (!container->details->auto_layout && icon->has_lazy_position) {
-                                semi_position_icons = g_list_prepend (semi_position_icons, icon);
-                        }
-                } else {
-                        no_position_icons = g_list_prepend (no_position_icons, icon);
-                }
+		if (icon->has_lazy_position) {
+			assign_icon_position (container, icon);
+			semi_position_icons = g_list_prepend (semi_position_icons, icon);
+		} else if (!assign_icon_position (container, icon)) {
+			no_position_icons = g_list_prepend (no_position_icons, icon);
+		}
 
 		finish_adding_icon (container, icon);
 	}
@@ -6780,6 +6810,7 @@
 
 		for (p = semi_position_icons; p != NULL; p = p->next) {
 			NautilusIcon *icon;
+			NautilusIconPosition position;
 			int x, y;
 
 			icon = p->data;
@@ -6791,7 +6822,12 @@
 
 			icon_set_position (icon, x, y);
 
+			position.x = icon->x;
+			position.y = icon->y;
+			position.scale = icon->scale;
 			placement_grid_mark_icon (grid, icon);
+			g_signal_emit (container, signals[ICON_POSITION_CHANGED], 0,
+				       icon->data, &position);
 
 			/* ensure that next time we run this code, the formerly semi-positioned
 			 * icons are treated as being positioned. */
@@ -6808,28 +6844,50 @@
 		g_assert (!container->details->auto_layout);
 		
 		sort_icons (container, &no_position_icons);
-		get_all_icon_bounds (container, NULL, NULL, NULL, &bottom, BOUNDS_USAGE_FOR_LAYOUT);
-		lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM);
+		if (nautilus_icon_container_get_is_desktop (container)) {
+			lay_down_icons (container, no_position_icons, CONTAINER_PAD_TOP);
+		} else {
+			get_all_icon_bounds (container, NULL, NULL, NULL, &bottom, BOUNDS_USAGE_FOR_LAYOUT);
+			lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM);
+		}
 		g_list_free (no_position_icons);
 	}
+
+	if (container->details->store_layout_timestamps_when_finishing_new_icons) {
+		store_layout_timestamps_now (container);
+		container->details->store_layout_timestamps_when_finishing_new_icons = FALSE;
+	}
+}
+
+static gboolean
+is_old_or_unknown_icon_data (NautilusIconContainer *container,
+			     NautilusIconData *data)
+{
+	time_t timestamp;
+	gboolean success;
+
+	if (container->details->layout_timestamp == UNDEFINED_TIME) {
+		/* don't know */
+		return FALSE;
+	}
+
+	g_signal_emit (container,
+		       signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
+		       data, &timestamp, &success);
+	return (!success || timestamp < container->details->layout_timestamp);
 }
 
 /**
  * nautilus_icon_container_add:
  * @container: A NautilusIconContainer
  * @data: Icon data.
- * @has_lazy_position: Whether the saved icon position should only be used
- * 		       if the previous icon position is free. If the position
- * 		       is occupied, another position near the last one will
- * 		       be used.
  * 
  * Add icon to represent @data to container.
  * Returns FALSE if there was already such an icon.
  **/
 gboolean
 nautilus_icon_container_add (NautilusIconContainer *container,
-			     NautilusIconData *data,
-			     gboolean has_lazy_position)
+			     NautilusIconData *data)
 {
 	NautilusIconContainerDetails *details;
 	NautilusIcon *icon;
@@ -6849,7 +6907,12 @@
 	icon->data = data;
 	icon->x = ICON_UNPOSITIONED_VALUE;
 	icon->y = ICON_UNPOSITIONED_VALUE;
-	icon->has_lazy_position = has_lazy_position;
+
+	/* Whether the saved icon position should only be used
+	 * if the previous icon position is free. If the position
+	 * is occupied, another position near the last one will
+	 */
+	icon->has_lazy_position = is_old_or_unknown_icon_data (container, data);
 	icon->scale = 1.0;
  	icon->item = NAUTILUS_ICON_CANVAS_ITEM
 		(eel_canvas_item_new (EEL_CANVAS_GROUP (EEL_CANVAS (container)->root),
@@ -9151,5 +9214,68 @@
 	return limit;
 }
 
+void
+nautilus_icon_container_begin_loading (NautilusIconContainer *container)
+{
+	gboolean dummy;
+
+	if (nautilus_icon_container_get_store_layout_timestamps (container)) {
+		container->details->layout_timestamp = UNDEFINED_TIME;
+		g_signal_emit (container,
+			       signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
+			       NULL, &container->details->layout_timestamp, &dummy);
+	}
+}
+
+static void
+store_layout_timestamps_now (NautilusIconContainer *container)
+{
+	NautilusIcon *icon;
+	GList *p;
+	gboolean dummy;
+
+	container->details->layout_timestamp = time (NULL);
+	g_signal_emit (container,
+		       signals[STORE_LAYOUT_TIMESTAMP], 0,
+		       NULL, &container->details->layout_timestamp, &dummy);
+
+	for (p = container->details->icons; p != NULL; p = p->next) {
+		icon = p->data;
+
+		g_signal_emit (container,
+			       signals[STORE_LAYOUT_TIMESTAMP], 0,
+			       icon->data, &container->details->layout_timestamp, &dummy);
+	}
+}
+
+
+void
+nautilus_icon_container_end_loading (NautilusIconContainer *container,
+				     gboolean               all_icons_added)
+{
+	if (all_icons_added &&
+	    nautilus_icon_container_get_store_layout_timestamps (container)) {
+		if (container->details->new_icons == NULL) {
+			store_layout_timestamps_now (container);
+		} else {
+			container->details->store_layout_timestamps_when_finishing_new_icons = TRUE;
+		}
+	}
+}
+
+gboolean
+nautilus_icon_container_get_store_layout_timestamps (NautilusIconContainer *container)
+{
+	return container->details->store_layout_timestamps;
+}
+
+
+void
+nautilus_icon_container_set_store_layout_timestamps (NautilusIconContainer *container,
+						     gboolean               store_layout_timestamps)
+{
+	container->details->store_layout_timestamps = store_layout_timestamps;
+}
+
 
 #endif /* ! NAUTILUS_OMIT_SELF_CHECK */

Modified: trunk/libnautilus-private/nautilus-icon-container.h
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-container.h	(original)
+++ trunk/libnautilus-private/nautilus-icon-container.h	Sun Aug 24 20:44:34 2008
@@ -176,6 +176,24 @@
 	char *       (* get_icon_drop_target_uri) (NautilusIconContainer *container,
 						   NautilusIconData *data);
 
+	/* If icon data is NULL, the layout timestamp of the container should be retrieved.
+	 * That is the time when the container displayed a fully loaded directory with
+	 * all icon positions assigned.
+	 *
+	 * If icon data is not NULL, the position timestamp of the icon should be retrieved.
+	 * That is the time when the file (i.e. icon data payload) was last displayed in a
+	 * fully loaded directory with all icon positions assigned.
+	 */
+	gboolean     (* get_stored_layout_timestamp) (NautilusIconContainer *container,
+						      NautilusIconData *data,
+						      time_t *time);
+	/* If icon data is NULL, the layout timestamp of the container should be stored.
+	 * If icon data is not NULL, the position timestamp of the container should be stored.
+	 */
+	gboolean     (* store_layout_timestamp) (NautilusIconContainer *container,
+						 NautilusIconData *data,
+						 const time_t *time);
+
 	/* Notifications for the whole container. */
 	void	     (* band_select_started)	  (NautilusIconContainer *container);
 	void	     (* band_select_ended)	  (NautilusIconContainer *container);
@@ -214,8 +232,7 @@
 /* adding, removing, and managing icons */
 void              nautilus_icon_container_clear                         (NautilusIconContainer  *view);
 gboolean          nautilus_icon_container_add                           (NautilusIconContainer  *view,
-									 NautilusIconData       *data,
-									 gboolean                has_lazy_position);
+									 NautilusIconData       *data);
 void              nautilus_icon_container_layout_now                    (NautilusIconContainer *container);
 gboolean          nautilus_icon_container_remove                        (NautilusIconContainer  *view,
 									 NautilusIconData       *data);
@@ -232,9 +249,11 @@
 void              nautilus_icon_container_scroll_to_icon                (NautilusIconContainer  *container,
 									 NautilusIconData       *data);
 
+void              nautilus_icon_container_begin_loading                 (NautilusIconContainer  *container);
+void              nautilus_icon_container_end_loading                   (NautilusIconContainer  *container,
+									 gboolean                all_icons_added);
+
 /* control the layout */
-void              nautilus_icon_container_set_is_reloading              (NautilusIconContainer  *container,
-									 gboolean                is_reloading);
 gboolean          nautilus_icon_container_is_auto_layout                (NautilusIconContainer  *container);
 void              nautilus_icon_container_set_auto_layout               (NautilusIconContainer  *container,
 									 gboolean                auto_layout);
@@ -313,6 +332,10 @@
 gboolean	  nautilus_icon_container_is_layout_rtl			(NautilusIconContainer  *container);
 gboolean	  nautilus_icon_container_is_layout_vertical		(NautilusIconContainer  *container);
 
+gboolean          nautilus_icon_container_get_store_layout_timestamps   (NautilusIconContainer  *container);
+void              nautilus_icon_container_set_store_layout_timestamps   (NautilusIconContainer  *container,
+									 gboolean                store_layout);
+
 void              nautilus_icon_container_widget_to_file_operation_position (NautilusIconContainer *container,
 									     GdkPoint              *position);
 

Modified: trunk/libnautilus-private/nautilus-icon-dnd.c
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-dnd.c	(original)
+++ trunk/libnautilus-private/nautilus-icon-dnd.c	Sun Aug 24 20:44:34 2008
@@ -925,6 +925,7 @@
 	NautilusFile *file;
 	char screen_string[32];
 	GdkScreen *screen;
+	time_t now;
 
 	if (container->details->auto_layout) {
 		if (!confirm_switch_to_manual_layout (container)) {
@@ -933,6 +934,7 @@
 		nautilus_icon_container_freeze_icon_positions (container);
 	}
 
+	time (&now);
 
 	/* Move and select the icons. */
 	moved_icons = NULL;
@@ -955,10 +957,10 @@
 			nautilus_file_set_metadata (file,
 					NAUTILUS_METADATA_KEY_SCREEN,
 					NULL, screen_string);
+			nautilus_file_set_time_metadata (file,
+							 NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP, now);
 
-			nautilus_icon_container_add (container,
-					NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
-					FALSE);
+			nautilus_icon_container_add (container, NAUTILUS_ICON_CONTAINER_ICON_DATA (file));
 			
 			icon = nautilus_icon_container_get_icon_by_uri
 				(container, item->uri);

Modified: trunk/libnautilus-private/nautilus-icon-private.h
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-private.h	(original)
+++ trunk/libnautilus-private/nautilus-icon-private.h	Sun Aug 24 20:44:34 2008
@@ -273,7 +273,11 @@
 	guint a11y_item_action_idle_handler;
 	GQueue* a11y_item_action_queue;
 
-	eel_boolean_bit is_reloading : 1;
+	eel_boolean_bit is_loading : 1;
+
+	eel_boolean_bit store_layout_timestamps : 1;
+	eel_boolean_bit store_layout_timestamps_when_finishing_new_icons : 1;
+	time_t layout_timestamp;
 
 	/* interactive search */
 	gboolean disable_popdown;

Modified: trunk/libnautilus-private/nautilus-metadata.h
==============================================================================
--- trunk/libnautilus-private/nautilus-metadata.h	(original)
+++ trunk/libnautilus-private/nautilus-metadata.h	Sun Aug 24 20:44:34 2008
@@ -44,6 +44,7 @@
 #define NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY          	"icon_view_sort_by"
 #define NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED    	"icon_view_sort_reversed"
 #define NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED            "icon_view_keep_aligned"
+#define NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP	"icon_view_layout_timestamp"
 
 #define NAUTILUS_METADATA_KEY_LIST_VIEW_ZOOM_LEVEL       	"list_view_zoom_level"
 #define NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_COLUMN      	"list_view_sort_column"
@@ -69,6 +70,7 @@
 
 #define NAUTILUS_METADATA_KEY_ANNOTATION                 	"annotation"
 #define NAUTILUS_METADATA_KEY_ICON_POSITION              	"icon_position"
+#define NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP		"icon_position_timestamp"
 #define NAUTILUS_METADATA_KEY_ICON_SCALE                 	"icon_scale"
 #define NAUTILUS_METADATA_KEY_CUSTOM_ICON                	"custom_icon"
 #define NAUTILUS_METADATA_KEY_SCREEN				"screen"

Modified: trunk/src/file-manager/fm-desktop-icon-view.c
==============================================================================
--- trunk/src/file-manager/fm-desktop-icon-view.c	(original)
+++ trunk/src/file-manager/fm-desktop-icon-view.c	Sun Aug 24 20:44:34 2008
@@ -546,6 +546,7 @@
 	
 	nautilus_icon_container_set_is_fixed_size (icon_container, TRUE);
 	nautilus_icon_container_set_is_desktop (icon_container, TRUE);
+	nautilus_icon_container_set_store_layout_timestamps (icon_container, TRUE);
 
 	/* Set allocation to be at 0, 0 */
 	allocation = &GTK_WIDGET (icon_container)->allocation;

Modified: trunk/src/file-manager/fm-directory-view.c
==============================================================================
--- trunk/src/file-manager/fm-directory-view.c	(original)
+++ trunk/src/file-manager/fm-directory-view.c	Sun Aug 24 20:44:34 2008
@@ -2343,7 +2343,8 @@
 }
 
 static void
-done_loading (FMDirectoryView *view)
+done_loading (FMDirectoryView *view,
+	      gboolean all_files_seen)
 {
 	GList *locations_selected, *selection;
 
@@ -2393,7 +2394,7 @@
 		fm_directory_view_display_selection_info (view);
 	}
 
-	fm_directory_view_end_loading (view);
+	fm_directory_view_end_loading (view, all_files_seen);
 
 	view->details->loading = FALSE;
 }
@@ -2807,7 +2808,7 @@
 	if (view->details->model != NULL
 	    && nautilus_directory_are_all_files_seen (view->details->model)
 	    && g_hash_table_size (view->details->non_ready_files) == 0) {
-		done_loading (view);
+		done_loading (view, TRUE);
 	}
 }
 
@@ -3269,11 +3270,12 @@
  * 
  **/
 void
-fm_directory_view_end_loading (FMDirectoryView *view)
+fm_directory_view_end_loading (FMDirectoryView *view,
+			       gboolean all_files_seen)
 {
 	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
-	g_signal_emit (view, signals[END_LOADING], 0);
+	g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
 }
 
 /**
@@ -8791,7 +8793,7 @@
 	if (view->details->model != NULL) {
 		nautilus_directory_file_monitor_remove (view->details->model, view);
 	}
-	done_loading (view);
+	done_loading (view, FALSE);
 }
 
 gboolean
@@ -9689,8 +9691,8 @@
 		              G_SIGNAL_RUN_LAST,
 		              G_STRUCT_OFFSET (FMDirectoryViewClass, end_loading),
 		              NULL, NULL,
-		              g_cclosure_marshal_VOID__VOID,
-		              G_TYPE_NONE, 0);
+		              g_cclosure_marshal_VOID__BOOLEAN,
+		              G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 	signals[FILE_CHANGED] =
 		g_signal_new ("file_changed",
 		              G_TYPE_FROM_CLASS (klass),

Modified: trunk/src/file-manager/fm-directory-view.h
==============================================================================
--- trunk/src/file-manager/fm-directory-view.h	(original)
+++ trunk/src/file-manager/fm-directory-view.h	Sun Aug 24 20:44:34 2008
@@ -108,8 +108,16 @@
 	 * of a directory are added to the view. It can be replaced by a 
 	 * subclass to do any necessary clean-up. The default implementation 
 	 * does nothing.
+	 *
+	 * If all_files_seen is true, the handler may assume that
+	 * no load error ocurred, and all files of the underlying
+	 * directory were loaded.
+	 *
+	 * Otherwise, end_loading was emitted due to cancellation,
+	 * which usually means that not all files are available.
 	 */
-	void 	(* end_loading) 	 (FMDirectoryView *view);
+	void 	(* end_loading) 	 (FMDirectoryView *view,
+					  gboolean all_files_seen);
 
 	/* The 'load_error' signal is emitted when the directory model
 	 * reports an error in the process of monitoring the directory's
@@ -382,7 +390,8 @@
  */
 void                fm_directory_view_clear                            (FMDirectoryView  *view);
 void                fm_directory_view_begin_loading                    (FMDirectoryView  *view);
-void                fm_directory_view_end_loading                      (FMDirectoryView  *view);
+void                fm_directory_view_end_loading                      (FMDirectoryView  *view,
+									gboolean          all_files_seen);
 
 gboolean            fm_directory_view_get_loading                      (FMDirectoryView  *view);
 

Modified: trunk/src/file-manager/fm-icon-view.c
==============================================================================
--- trunk/src/file-manager/fm-icon-view.c	(original)
+++ trunk/src/file-manager/fm-icon-view.c	Sun Aug 24 20:44:34 2008
@@ -269,6 +269,7 @@
 	return position_good;
 }
 
+
 static gboolean
 set_sort_criterion (FMIconView *icon_view, const SortCriterion *sort)
 {
@@ -495,28 +496,6 @@
 	}
 }
 
-static gboolean
-file_has_lazy_position (FMDirectoryView *view,
-			NautilusFile *file)
-{
-	gboolean lazy_position;
-
-	/* For volumes (i.e. cdrom icon) we use lazy positioning so that when
-	 * an old cdrom gets re-mounted in a place that now has another
-	 * icon we don't overlap that one. We don't do this in general though,
-	 * as it can cause icons moving around.
-	 */
-	lazy_position = nautilus_file_can_unmount (file);
-	if (lazy_position && fm_directory_view_get_loading (view)) {
-		/* if volumes are loaded during directory load, don't mark them
-		 * as lazy. This is wrong for files that were mounted during user
-		 * log-off, but it is right for files that were mounted during login. */
-		lazy_position = FALSE;
-	}
-
-	return lazy_position;
-}
-
 static void
 fm_icon_view_add_file (FMDirectoryView *view, NautilusFile *file, NautilusDirectory *directory)
 {
@@ -539,8 +518,7 @@
 	}
 
 	if (nautilus_icon_container_add (icon_container,
-					 NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
-					 file_has_lazy_position (view, file)))  {
+					 NAUTILUS_ICON_CONTAINER_ICON_DATA (file))) {
 		nautilus_file_ref (file);
 	}
 }
@@ -1128,6 +1106,8 @@
 	file = fm_directory_view_get_directory_as_file (view);
 	icon_container = GTK_WIDGET (get_icon_container (icon_view));
 
+	nautilus_icon_container_begin_loading (NAUTILUS_ICON_CONTAINER (icon_container));
+
 	nautilus_icon_container_set_allow_moves (NAUTILUS_ICON_CONTAINER (icon_container),
 						 fm_directory_view_get_allow_moves (view));
 
@@ -1206,11 +1186,16 @@
 }
 
 static void
-fm_icon_view_end_loading (FMDirectoryView *view)
+fm_icon_view_end_loading (FMDirectoryView *view,
+			  gboolean all_files_seen)
 {
 	FMIconView *icon_view;
+	GtkWidget *icon_container;
 
 	icon_view = FM_ICON_VIEW (view);
+
+	icon_container = GTK_WIDGET (get_icon_container (icon_view));
+	nautilus_icon_container_end_loading (NAUTILUS_ICON_CONTAINER (icon_container), all_files_seen);
 }
 
 static NautilusZoomLevel
@@ -2180,8 +2165,7 @@
 				fm_icon_view_remove_file (view, file, directory);
 			} else {
 				if (nautilus_icon_container_add (icon_container,
-								 NAUTILUS_ICON_CONTAINER_ICON_DATA (file),
-								 file_has_lazy_position (view, file))) {
+								 NAUTILUS_ICON_CONTAINER_ICON_DATA (file))) {
 					nautilus_file_ref (file);
 				}
 			}
@@ -2573,6 +2557,62 @@
 						       click_mode == NAUTILUS_CLICK_POLICY_SINGLE);
 }
 
+static gboolean
+get_stored_layout_timestamp (NautilusIconContainer *container,
+			     NautilusIconData *icon_data,
+			     time_t *timestamp,
+			     FMIconView *view)
+{
+	NautilusFile *file;
+	NautilusDirectory *directory;
+
+	if (icon_data == NULL) {
+		directory = fm_directory_view_get_model (FM_DIRECTORY_VIEW (view));
+		if (directory == NULL) {
+			return FALSE;
+		}
+
+		file = nautilus_directory_get_corresponding_file (directory);
+		*timestamp = nautilus_file_get_time_metadata (file,
+							      NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP);
+		nautilus_file_unref (file);
+	} else {
+		*timestamp = nautilus_file_get_time_metadata (NAUTILUS_FILE (icon_data),
+							      NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+store_layout_timestamp (NautilusIconContainer *container,
+			NautilusIconData *icon_data,
+			const time_t *timestamp,
+			FMIconView *view)
+{
+	NautilusFile *file;
+	NautilusDirectory *directory;
+
+	if (icon_data == NULL) {
+		directory = fm_directory_view_get_model (FM_DIRECTORY_VIEW (view));
+		if (directory == NULL) {
+			return FALSE;
+		}
+
+		file = nautilus_directory_get_corresponding_file (directory);
+		nautilus_file_set_time_metadata (file,
+						 NAUTILUS_METADATA_KEY_ICON_VIEW_LAYOUT_TIMESTAMP,
+						 (time_t) *timestamp);
+		nautilus_file_unref (file);
+	} else {
+		nautilus_file_set_time_metadata (NAUTILUS_FILE (icon_data),
+						 NAUTILUS_METADATA_KEY_ICON_POSITION_TIMESTAMP,
+						 (time_t) *timestamp);
+	}
+
+	return TRUE;
+}
+
 static NautilusIconContainer *
 create_icon_container (FMIconView *icon_view)
 {
@@ -2626,6 +2666,11 @@
 				 G_CALLBACK (fm_directory_view_update_menus), icon_view,
 				 G_CONNECT_SWAPPED);
 
+	g_signal_connect_object (icon_container, "get_stored_layout_timestamp",
+				 G_CALLBACK (get_stored_layout_timestamp), icon_view, 0);
+	g_signal_connect_object (icon_container, "store_layout_timestamp",
+				 G_CALLBACK (store_layout_timestamp), icon_view, 0);
+
 	gtk_container_add (GTK_CONTAINER (icon_view),
 			   GTK_WIDGET (icon_container));
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]