+++ /dev/null
-? .tm_project.cache
-? nautilus.prj
-? nautilus.pws
-Index: configure.in
-===================================================================
-RCS file: /cvs/gnome/nautilus/configure.in,v
-retrieving revision 1.540
-diff -u -r1.540 configure.in
---- configure.in 22 Sep 2003 17:44:34 -0000 1.540
-+++ configure.in 12 Oct 2003 13:50:52 -0000
-@@ -20,6 +20,7 @@
- RSVG_REQUIRED=2.0.1
- XML_REQUIRED=2.4.7
- STARTUP_NOTIFICATION_REQUIRED=0.5
-+GSTREAMER_REQUIRED=0.6.0
-
- AC_SUBST(ART_REQUIRED)
- AC_SUBST(BONOBO_ACTIVATION_REQUIRED)
-@@ -39,6 +40,7 @@
- AC_SUBST(RSVG_REQUIRED)
- AC_SUBST(XML_REQUIRED)
- AC_SUBST(STARTUP_NOTIFICATION_REQUIRED)
-+AC_SUBST(GSTREAMER_REQUIRED)
-
- dnl ===========================================================================
-
-@@ -245,6 +247,53 @@
-
- dnl ==========================================================================
-
-+dnl gstreamer checking
-+
-+AC_ARG_ENABLE(gstreamer,
-+ AC_HELP_STRING([--enable-gstreamer],[use GStreamer for sound preview]),
-+ [case "${enableval}" in
-+ yes) ENABLE_GST=yes ;;
-+ no) ENABLE_GST=no ;;
-+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-gstreamer) ;;
-+ esac],
-+ [ENABLE_GST=no]) dnl Default value
-+
-+AC_MSG_CHECKING(for backend libraries)
-+
-+if test x$ENABLE_GST = xyes; then
-+
-+dnl Now we're ready to ask for gstreamer libs and cflags
-+dnl And we can also ask for the right version of gstreamer
-+ HAVE_GSTREAMER=no
-+
-+dnl start with 0.7
-+ GST_MAJORMINOR=0.7
-+ PKG_CHECK_MODULES(GST, \
-+ gstreamer-gconf-$GST_MAJORMINOR >= $GSTREAMER_REQUIRED,
-+ HAVE_GSTREAMER=yes,HAVE_GSTREAMER=no)
-+
-+dnl try 0.6
-+ if test "x$HAVE_GSTREAMER" = "xno"; then
-+ GST_MAJORMINOR=0.6
-+ PKG_CHECK_MODULES(GST, \
-+ gstreamer-gconf-$GST_MAJORMINOR >= $GSTREAMER_REQUIRED,
-+ HAVE_GSTREAMER=yes,HAVE_GSTREAMER=no)
-+ fi
-+
-+dnl Give error and exit if we don't have gstreamer
-+ if test "x$HAVE_GSTREAMER" = "xno"; then
-+ AC_MSG_ERROR(you need gstreamer development packages installed !)
-+ fi
-+
-+ MM="gstreamer-libs-$GST_MAJORMINOR >= $GSTREAMER_REQUIRED gstreamer-gconf-$GST_MAJORMINOR >= $GSTREAMER_REQUIRED"
-+
-+ AC_MSG_RESULT(GStreamer)
-+ AC_DEFINE(USE_GST_AUDIO_PREVIEW,1,[Define if you want to use the GStreamer media framework])
-+
-+fi
-+
-+dnl ==========================================================================
-+
- dnl Turn on the additional warnings last, so -Werror doesn't affect other tests.
-
- AC_ARG_ENABLE(more-warnings,
-@@ -314,7 +363,7 @@
- AC_SUBST(LIBNAUTILUS_IDL_INCLUDES)
-
- dnl core nautilus (must list bonobo-activation and libbonobo because idldir does not respect "requires")
--CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 libbonoboui-2.0 esound gnome-desktop-2.0 $EXTRA_CORE_MODULES"
-+CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 libbonoboui-2.0 esound gnome-desktop-2.0 $MM $EXTRA_CORE_MODULES"
- CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags"
- AC_SUBST(CORE_CFLAGS)
- CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $CDDA_LIBS $LIBJPEG $x_libs"
-Index: src/file-manager/fm-icon-view.c
-===================================================================
-RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
-retrieving revision 1.287
-diff -u -r1.287 fm-icon-view.c
---- src/file-manager/fm-icon-view.c 30 Sep 2003 20:38:00 -0000 1.287
-+++ src/file-manager/fm-icon-view.c 12 Oct 2003 13:50:56 -0000
-@@ -78,8 +78,13 @@
- #include <sys/wait.h>
- #include <unistd.h>
-
-+#ifdef USE_GST_AUDIO_PREVIEW
-+#include <gst/gst.h>
-+#include <gst/gconf/gconf.h>
-+#else
- #define USE_OLD_AUDIO_PREVIEW 1
- #define READ_CHUNK_SIZE 16384
-+#endif /* USE_GST_AUDIO_PREVIEW */
-
- /* Paths to use when creating & referring to Bonobo menu items */
- #define MENU_PATH_STRETCH_ICON "/menu/Edit/Edit Items Placeholder/Stretch"
-@@ -195,6 +200,10 @@
- static int preview_sound_auto_value;
- static gboolean gnome_esd_enabled_auto_value;
-
-+#ifdef USE_GST_AUDIO_PREVIEW
-+static GstElement *thread;
-+#endif
-+
- static void fm_icon_view_set_directory_sort_by (FMIconView *icon_view,
- NautilusFile *file,
- const char *sort_by);
-@@ -1741,6 +1750,22 @@
- fm_directory_view_stop_batching_selection_changes (FM_DIRECTORY_VIEW (icon_view));
- }
-
-+#ifdef USE_GST_AUDIO_PREVIEW
-+static void
-+gst_end_of_stream_callback (GstElement *src, gpointer callback_data)
-+{
-+ FMIconView *icon_view;
-+ icon_view = FM_ICON_VIEW (callback_data);
-+
-+ gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
-+
-+ if (icon_view->details->audio_preview_timeout != 0) {
-+ g_source_remove (icon_view->details->audio_preview_timeout);
-+ icon_view->details->audio_preview_timeout = 0;
-+ }
-+}
-+#endif
-+
- /* handle the preview signal by inspecting the mime type. For now, we only preview local sound files. */
-
- /* here's the timer task that actually plays the file using mpg123, ogg123 or play. */
-@@ -1748,6 +1773,34 @@
- static gboolean
- play_file (gpointer callback_data)
- {
-+#ifdef USE_GST_AUDIO_PREVIEW
-+ gchar *file_uri;
-+ GstElement *filesrc, *decoder, *audiosink;
-+ FMIconView *icon_view;
-+
-+ icon_view = FM_ICON_VIEW (callback_data);
-+ file_uri = nautilus_file_get_uri (icon_view->details->audio_preview_file);
-+
-+ if (file_uri != NULL && gst_init_check (NULL, NULL)) {
-+ thread = gst_thread_new ("thread");
-+ filesrc = gst_element_factory_make ("gnomevfssrc", "disk_source");
-+ decoder = gst_element_factory_make ("spider", "spider");
-+ audiosink = gst_gconf_get_default_audio_sink ();
-+
-+ g_object_set (G_OBJECT (filesrc), "location", file_uri, NULL);
-+ g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (gst_end_of_stream_callback), icon_view);
-+
-+ gst_bin_add_many (GST_BIN (thread), filesrc, decoder, audiosink, NULL);
-+ gst_element_link_many (filesrc, decoder, audiosink, NULL);
-+
-+ gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING);
-+ }
-+
-+ g_free (file_uri);
-+
-+ icon_view->details->audio_preview_file = NULL;
-+ icon_view->details->audio_preview_timeout = 0;
-+#else
- #if USE_OLD_AUDIO_PREVIEW
- NautilusFile *file;
- FMIconView *icon_view;
-@@ -1865,6 +1918,7 @@
- icon_view->details->audio_preview_timeout = 0;
- icon_view->details->audio_preview_file = NULL;
- #endif
-+#endif /* USE_GST_AUDIO_PREVIEW */
- return FALSE;
- }
-
-@@ -1878,7 +1932,22 @@
-
- static void
- preview_audio (FMIconView *icon_view, NautilusFile *file, gboolean start_flag)
--{
-+{
-+#ifdef USE_GST_AUDIO_PREVIEW
-+ if (thread != NULL) {
-+ gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);
-+ }
-+
-+ if (icon_view->details->audio_preview_timeout != 0) {
-+ g_source_remove (icon_view->details->audio_preview_timeout);
-+ icon_view->details->audio_preview_timeout = 0;
-+ }
-+
-+ if (start_flag) {
-+ icon_view->details->audio_preview_file = file;
-+ icon_view->details->audio_preview_timeout = g_timeout_add (1000, play_file, icon_view);
-+ }
-+#else
- /* Stop current audio playback */
- #if USE_OLD_AUDIO_PREVIEW
- nautilus_sound_kill_sound ();
-@@ -1903,15 +1972,18 @@
- icon_view->details->audio_preview_timeout = g_timeout_add (1000, play_file, icon_view);
- #endif
- }
-+#endif /* USE_GST_AUDIO_PREVIEW */
- }
-
- static gboolean
- should_preview_sound (NautilusFile *file)
- {
-+#ifndef USE_GST_AUDIO_PREVIEW
- /* Check gnome config sound preference */
- if (!gnome_esd_enabled_auto_value) {
- return FALSE;
- }
-+#endif /* USE_GST_AUDIO_PREVIEW */
-
- /* Check user performance preference */
- if (preview_sound_auto_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
-@@ -1942,10 +2014,18 @@
- mime_type = nautilus_file_get_mime_type (file);
-
- if ((eel_istr_has_prefix (mime_type, "audio/")
-- || eel_istr_has_prefix (mime_type, "application/x-ogg"))
-+#ifdef USE_GST_AUDIO_PREVIEW
-+ || eel_istr_has_prefix (mime_type, "application/ogg")
-+ || eel_istr_has_prefix (mime_type, "application/x-flac"))
- && eel_strcasecmp (mime_type, "audio/x-pn-realaudio") != 0
- && eel_strcasecmp (mime_type, "audio/x-mpegurl") != 0
-- && nautilus_sound_can_play_sound ()) {
-+ ) {
-+#else
-+ || eel_istr_has_prefix (mime_type, "application/ogg"))
-+ && eel_strcasecmp (mime_type, "audio/x-pn-realaudio") != 0
-+ && eel_strcasecmp (mime_type, "audio/x-mpegurl") != 0
-+ && nautilus_sound_can_play_sound ()) {
-+#endif
- result = 1;
- preview_audio (icon_view, file, start_flag);
- }
+++ /dev/null
-Index: libnautilus-private/nautilus-icon-container.c
-===================================================================
-RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
-retrieving revision 1.339
-diff -u -r1.339 nautilus-icon-container.c
---- libnautilus-private/nautilus-icon-container.c 23 Apr 2003 14:31:21 -0000 1.339
-+++ libnautilus-private/nautilus-icon-container.c 3 May 2003 23:21:42 -0000
-@@ -101,9 +101,9 @@
- #define STANDARD_ICON_GRID_WIDTH 155
-
- /* Desktop layout mode defines */
--#define DESKTOP_PAD_HORIZONTAL 30
-+#define DESKTOP_PAD_HORIZONTAL 10
- #define DESKTOP_PAD_VERTICAL 10
--#define CELL_SIZE 20
-+#define SNAP_SIZE 78
-
- /* Value used to protect against icons being dragged outside of the desktop bounds */
- #define DESKTOP_ICON_SAFETY_PAD 10
-@@ -116,6 +116,14 @@
- #define MINIMUM_EMBEDDED_TEXT_RECT_WIDTH 20
- #define MINIMUM_EMBEDDED_TEXT_RECT_HEIGHT 20
-
-+#define SNAP_HORIZONTAL(func,x) ((func ((double)((x) - DESKTOP_PAD_HORIZONTAL) / SNAP_SIZE) * SNAP_SIZE) + DESKTOP_PAD_HORIZONTAL)
-+#define SNAP_VERTICAL(func, y) ((func ((double)((y) - DESKTOP_PAD_VERTICAL) / SNAP_SIZE) * SNAP_SIZE) + DESKTOP_PAD_VERTICAL)
-+
-+#define SNAP_NEAREST_HORIZONTAL(x) SNAP_HORIZONTAL (eel_round, x)
-+#define SNAP_NEAREST_VERTICAL(y) SNAP_VERTICAL (eel_round, y)
-+
-+#define SNAP_CEIL_HORIZONTAL(x) SNAP_HORIZONTAL (ceil, x)
-+#define SNAP_CEIL_VERTICAL(y) SNAP_VERTICAL (ceil, y)
-
- enum {
- NAUTILUS_TYPESELECT_FLUSH_DELAY = 1000000
-@@ -220,6 +228,15 @@
- CLEARED,
- LAST_SIGNAL
- };
-+
-+typedef struct {
-+ int **icon_grid;
-+ int *grid_memory;
-+ int num_rows;
-+ int num_columns;
-+ gboolean tight;
-+} PlacementGrid;
-+
- static guint signals[LAST_SIGNAL];
-
- /* Functions dealing with NautilusIcons. */
-@@ -335,6 +352,7 @@
- icon_set_size (NautilusIconContainer *container,
- NautilusIcon *icon,
- guint icon_size,
-+ gboolean snap,
- gboolean update_position)
- {
- guint old_size;
-@@ -350,8 +368,8 @@
- (container->details->zoom_level);
- nautilus_icon_container_move_icon (container, icon,
- icon->x, icon->y,
-- scale, scale,
-- FALSE, update_position);
-+ scale, scale, FALSE,
-+ snap, update_position);
- }
-
- static void
-@@ -398,6 +416,15 @@
- if (icon == container->details->stretch_icon) {
- container->details->stretch_icon = NULL;
- nautilus_icon_canvas_item_set_show_stretch_handles (icon->item, FALSE);
-+ /* snap the icon if necessary */
-+ if (container->details->keep_aligned) {
-+ nautilus_icon_container_move_icon (container,
-+ icon,
-+ icon->x, icon->y,
-+ icon->scale_x, icon->scale_y,
-+ FALSE, TRUE, TRUE);
-+ }
-+
- emit_stretch_ended (container, icon);
- }
-
-@@ -1004,150 +1031,313 @@
- g_array_free (positions, TRUE);
- }
-
--/* Search for available space at location */
--static gboolean
--find_open_grid_space (NautilusIcon *icon, int **icon_grid, int num_rows,
-- int num_columns, int row, int column)
--{
-- int row_index, column_index;
-- int x1, x2, y1, y2;
-- double width, height;
-- int qwidth, qheight;
--
-- /* Get icon dimensions */
-- icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
--
-- width = (x2 - x1) + DESKTOP_PAD_HORIZONTAL;
-- height = (y2 - y1) + DESKTOP_PAD_VERTICAL;
--
-- /* Convert to grid coordinates */
-- qwidth = ceil (width / CELL_SIZE);
-- qheight = ceil (height / CELL_SIZE);
-+static void
-+snap_position (NautilusIconContainer *container,
-+ NautilusIcon *icon,
-+ int *x, int *y)
-+{
-+ int center_x;
-+ int baseline_y;
-+ int icon_width;
-+ int icon_height;
-+ ArtDRect icon_position;
-+
-+ if (*x < DESKTOP_PAD_HORIZONTAL) {
-+ *x = DESKTOP_PAD_HORIZONTAL;
-+ }
-
-- if ((row + qwidth > num_rows) || (column + qheight > num_columns)) {
-- return FALSE;
-+ if (*y < DESKTOP_PAD_VERTICAL) {
-+ *y = DESKTOP_PAD_VERTICAL;
- }
-
-- qwidth += row;
-- qheight += column;
-+ icon_position = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+ icon_width = icon_position.x1 - icon_position.x0;
-+ icon_height = icon_position.y1 - icon_position.y0;
-
-- for (row_index = row; row_index < qwidth; row_index++) {
-- for (column_index = column; column_index < qheight; column_index++) {
-- if (icon_grid [row_index] [column_index] == 1) {
-- return FALSE;
-- }
-- }
-- }
-- return TRUE;
-+ center_x = *x + icon_width / 2;
-+ *x = SNAP_NEAREST_HORIZONTAL (center_x) - (icon_width / 2);
-+
-+ /* Find the grid position vertically and place on the proper baseline */
-+ baseline_y = *y + icon_height;
-+ baseline_y = SNAP_NEAREST_VERTICAL (baseline_y);
-+ *y = baseline_y - (icon_position.y1 - icon_position.y0);
-+}
-+
-+static int
-+compare_icons_by_position (gconstpointer a, gconstpointer b)
-+{
-+ NautilusIcon *icon_a, *icon_b;
-+ int x1, y1, x2, y2;
-+ int center_a;
-+ int center_b;
-+
-+ icon_a = (NautilusIcon*)a;
-+ icon_b = (NautilusIcon*)b;
-+
-+ icon_get_bounding_box (icon_a, &x1, &y1, &x2, &y2);
-+ center_a = x1 + (x2 - x1) / 2;
-+ icon_get_bounding_box (icon_b, &x1, &y1, &x2, &y2);
-+ center_b = x1 + (x2 - x1) / 2;
-+
-+ return center_a == center_b ?
-+ icon_a->y - icon_b->y :
-+ center_a - center_b;
- }
-
-+static PlacementGrid *
-+placement_grid_new (NautilusIconContainer *container, gboolean tight)
-+{
-+ PlacementGrid *grid;
-+ int width, height;
-+ int num_columns;
-+ int num_rows;
-+ int i;
-+
-+ /* Get container dimensions */
-+ width = GTK_WIDGET (container)->allocation.width /
-+ EEL_CANVAS (container)->pixels_per_unit
-+ - container->details->left_margin
-+ - container->details->right_margin;
-+ height = GTK_WIDGET (container)->allocation.height /
-+ EEL_CANVAS (container)->pixels_per_unit
-+ - container->details->top_margin
-+ - container->details->bottom_margin;
-+
-+ num_columns = width / SNAP_SIZE;
-+ num_rows = height / SNAP_SIZE;
-+
-+ if (num_columns == 0 || num_rows == 0) {
-+ return NULL;
-+ }
-+
-+ grid = g_new0 (PlacementGrid, 1);
-+ grid->tight = tight;
-+ grid->num_columns = num_columns;
-+ grid->num_rows = num_rows;
-+
-+ grid->grid_memory = g_new0 (int, (num_rows * num_columns));
-+ grid->icon_grid = g_new0 (int *, num_columns);
-+
-+ for (i = 0; i < num_columns; i++) {
-+ grid->icon_grid[i] = grid->grid_memory + (i * num_rows);
-+ }
-+
-+ return grid;
-+}
-
- static void
--get_best_empty_grid_location (NautilusIcon *icon, int **icon_grid, int num_rows,
-- int num_columns, int *x, int *y)
-+placement_grid_free (PlacementGrid *grid)
- {
-- gboolean found_space;
-- int row, column;
-+ g_free (grid->icon_grid);
-+ g_free (grid->grid_memory);
-+ g_free (grid);
-+}
-+
-+static gboolean
-+placement_grid_position_is_free (PlacementGrid *grid, ArtIRect pos)
-+{
-+ int x, y;
-
-- g_assert (icon_grid != NULL);
-- g_assert (x != NULL);
-- g_assert (y != NULL);
--
-- found_space = FALSE;
--
-- /* Set up default fallback position */
-- *x = num_columns * CELL_SIZE;
-- *y = num_rows * CELL_SIZE;
--
-- /* Find best empty location */
-- for (row = 0; row < num_rows; row++) {
-- for (column = 0; column < num_columns; column++) {
-- found_space = find_open_grid_space (icon, icon_grid, num_rows,
-- num_columns, row, column);
-- if (found_space) {
-- *x = row * CELL_SIZE;
-- *y = column * CELL_SIZE;
--
-- /* Correct for padding */
-- if (*x < DESKTOP_PAD_HORIZONTAL) {
-- *x = DESKTOP_PAD_HORIZONTAL;
-- }
-- if (*y < DESKTOP_PAD_VERTICAL) {
-- *y = DESKTOP_PAD_VERTICAL;
-- }
-- return;
-+ g_return_val_if_fail (pos.x0 >= 0 && pos.x0 < grid->num_columns, TRUE);
-+ g_return_val_if_fail (pos.y0 >= 0 && pos.y0 < grid->num_rows, TRUE);
-+ g_return_val_if_fail (pos.x1 >= 0 && pos.x1 < grid->num_columns, TRUE);
-+ g_return_val_if_fail (pos.y1 >= 0 && pos.y1 < grid->num_rows, TRUE);
-+
-+ for (x = pos.x0; x <= pos.x1; x++) {
-+ for (y = pos.y0; y <= pos.y1; y++) {
-+ if (grid->icon_grid[x][y] != 0) {
-+ return FALSE;
- }
-- }
-+ }
- }
-+
-+ return TRUE;
- }
-
- static void
--mark_icon_location_in_grid (NautilusIcon *icon, int **icon_grid, int num_rows, int num_columns)
-+placement_grid_mark (PlacementGrid *grid, ArtIRect pos)
- {
-- int x1, x2, y1, y2;
-- double width, height;
-- int qx, qy, qwidth, qheight, qy_index;
-- int grid_width, grid_height;
--
-- icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
--
-- width = (x2 - x1) + DESKTOP_PAD_HORIZONTAL;
-- height = (y2 - y1) + DESKTOP_PAD_VERTICAL;
--
-- /* Convert x and y to our quantized grid value */
-- qx = icon->x / CELL_SIZE;
-- qy = icon->y / CELL_SIZE;
-- qwidth = ceil (width / CELL_SIZE);
-- qheight = ceil (height / CELL_SIZE);
--
-- /* Check and correct for edge conditions */
-- grid_width = num_rows;
-- grid_height = num_columns;
-+ int x, y;
-
-- if ((qx + qwidth) > grid_width) {
-- qwidth = grid_width;
-- } else {
-- qwidth = qx + qwidth;
-+ g_return_if_fail (pos.x0 >= 0 && pos.x0 < grid->num_columns);
-+ g_return_if_fail (pos.y0 >= 0 && pos.y0 < grid->num_rows);
-+ g_return_if_fail (pos.x1 >= 0 && pos.x1 < grid->num_columns);
-+ g_return_if_fail (pos.y1 >= 0 && pos.y1 < grid->num_rows);
-+
-+ for (x = pos.x0; x <= pos.x1; x++) {
-+ for (y = pos.y0; y <= pos.y1; y++) {
-+ grid->icon_grid[x][y] = 1;
-+ }
- }
-- if ((qy + qheight) > grid_height) {
-- qheight = grid_height;
-+}
-+
-+static void
-+canvas_position_to_grid_position (PlacementGrid *grid,
-+ ArtIRect canvas_position,
-+ ArtIRect *grid_position)
-+{
-+ /* The first bit of this block will identify all intersections
-+ * that the icon actually crosses. The second bit will mark
-+ * any intersections that the icon is adjacent to.
-+ * The first causes minimal moving around during a snap, but
-+ * can end up with partially overlapping icons. The second one won't
-+ * allow any overlapping, but can cause more movement to happen
-+ * during a snap. */
-+ if (grid->tight) {
-+ grid_position->x0 = ceil ((double)(canvas_position.x0 - DESKTOP_PAD_HORIZONTAL) / SNAP_SIZE);
-+ grid_position->y0 = ceil ((double)(canvas_position.y0 - DESKTOP_PAD_VERTICAL) / SNAP_SIZE);
-+ grid_position->x1 = floor ((double)(canvas_position.x1 - DESKTOP_PAD_HORIZONTAL) / SNAP_SIZE);
-+ grid_position->y1 = floor ((double)(canvas_position.y1 - DESKTOP_PAD_VERTICAL) / SNAP_SIZE);
- } else {
-- qheight = qy + qheight;
-+ grid_position->x0 = floor ((double)(canvas_position.x0 - DESKTOP_PAD_HORIZONTAL) / SNAP_SIZE);
-+ grid_position->y0 = floor ((double)(canvas_position.y0 - DESKTOP_PAD_VERTICAL) / SNAP_SIZE);
-+ grid_position->x1 = ceil ((double)(canvas_position.x1 - DESKTOP_PAD_HORIZONTAL) / SNAP_SIZE);
-+ grid_position->y1 = ceil ((double)(canvas_position.y1 - DESKTOP_PAD_VERTICAL) / SNAP_SIZE);
- }
-+
-+ grid_position->x0 = CLAMP (grid_position->x0, 0, grid->num_columns - 1);
-+ grid_position->y0 = CLAMP (grid_position->y0, 0, grid->num_rows - 1);
-+ grid_position->x1 = CLAMP (grid_position->x1, grid_position->x0, grid->num_columns - 1);
-+ grid_position->y1 = CLAMP (grid_position->y1, grid_position->y0, grid->num_rows - 1);
-+}
-+
-+static void
-+placement_grid_mark_icon (PlacementGrid *grid, NautilusIcon *icon)
-+{
-+ ArtIRect icon_pos;
-+ ArtIRect grid_pos;
-
-- /* Mark location */
-- for (; qx < qwidth; qx++) {
-- for (qy_index = qy; qy_index < qheight; qy_index++) {
-- icon_grid [qx] [qy_index] = 1;
-+ icon_get_bounding_box (icon,
-+ &icon_pos.x0, &icon_pos.y0,
-+ &icon_pos.x1, &icon_pos.y1);
-+ canvas_position_to_grid_position (grid,
-+ icon_pos,
-+ &grid_pos);
-+ placement_grid_mark (grid, grid_pos);
-+}
-+
-+static void
-+find_empty_location (NautilusIconContainer *container,
-+ PlacementGrid *grid,
-+ NautilusIcon *icon,
-+ int start_x,
-+ int start_y,
-+ int *x,
-+ int *y)
-+{
-+ double icon_width, icon_height;
-+ int canvas_width;
-+ int canvas_height;
-+ ArtIRect icon_position;
-+ ArtDRect pixbuf_rect;
-+ gboolean collision;
-+
-+ /* Get container dimensions */
-+ canvas_width = GTK_WIDGET (container)->allocation.width /
-+ EEL_CANVAS (container)->pixels_per_unit
-+ - container->details->left_margin
-+ - container->details->right_margin;
-+ canvas_height = GTK_WIDGET (container)->allocation.height /
-+ EEL_CANVAS (container)->pixels_per_unit
-+ - container->details->top_margin
-+ - container->details->bottom_margin;
-+
-+ icon_get_bounding_box (icon,
-+ &icon_position.x0, &icon_position.y0,
-+ &icon_position.x1, &icon_position.y1);
-+ icon_width = icon_position.x1 - icon_position.x0;
-+ icon_height = icon_position.y1 - icon_position.y0;
-+
-+ pixbuf_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+
-+ /* Start the icon on a grid location */
-+ snap_position (container, icon, &start_x, &start_y);
-+
-+ icon_position.x0 = start_x;
-+ icon_position.y0 = start_y;
-+ icon_position.x1 = icon_position.x0 + icon_width;
-+ icon_position.y1 = icon_position.y0 + icon_height;
-+
-+ do {
-+ ArtIRect grid_position;
-+
-+ collision = FALSE;
-+
-+ canvas_position_to_grid_position (grid,
-+ icon_position,
-+ &grid_position);
-+
-+ if (!placement_grid_position_is_free (grid, grid_position)) {
-+ icon_position.y0 += SNAP_SIZE;
-+ icon_position.y1 = icon_position.y0 + icon_width;
-+
-+ if (icon_position.y1 + DESKTOP_PAD_VERTICAL > canvas_height) {
-+ /* Move to the next column */
-+ icon_position.y0 = DESKTOP_PAD_VERTICAL + SNAP_SIZE - (pixbuf_rect.y1 - pixbuf_rect.y0);
-+ while (icon_position.y0 < DESKTOP_PAD_VERTICAL) {
-+ icon_position.y0 += SNAP_SIZE;
-+ }
-+ icon_position.y1 = icon_position.y0 + icon_width;
-+
-+ icon_position.x0 += SNAP_SIZE;
-+ icon_position.x1 = icon_position.x0 + icon_height;
-+ }
-+
-+ collision = TRUE;
- }
-- }
-+ } while (collision && (icon_position.x1 < canvas_width));
-+
-+ *x = icon_position.x0;
-+ *y = icon_position.y0;
- }
-
--static void
--mark_icon_locations_in_grid (GList *icon_list, int **icon_grid, int num_rows, int num_columns)
-+static void
-+align_icons (NautilusIconContainer *container)
- {
-- GList *p;
-- NautilusIcon *icon;
-+ GList *unplaced_icons;
-+ GList *l;
-+ PlacementGrid *grid;
-+
-+ unplaced_icons = g_list_copy (container->details->icons);
-
-- /* Mark filled grid locations */
-- for (p = icon_list; p != NULL; p = p->next) {
-- icon = p->data;
-- mark_icon_location_in_grid (icon, icon_grid, num_rows, num_columns);
-+ unplaced_icons = g_list_sort (unplaced_icons,
-+ compare_icons_by_position);
-+
-+ grid = placement_grid_new (container, TRUE);
-+
-+ if (!grid) {
-+ return;
- }
-+
-+ for (l = unplaced_icons; l != NULL; l = l->next) {
-+ NautilusIcon *icon;
-+ int x, y;
-+
-+ icon = l->data;
-+ x = icon->x;
-+ y = icon->y;
-+
-+ find_empty_location (container, grid,
-+ icon, x, y, &x, &y);
-+
-+ icon_set_position (icon, x, y);
-+
-+ placement_grid_mark_icon (grid, icon);
-+ }
-+
-+ g_list_free (unplaced_icons);
-+
-+ placement_grid_free (grid);
- }
-
- static void
- lay_down_icons_tblr (NautilusIconContainer *container, GList *icons)
- {
- GList *p, *placed_icons, *unplaced_icons;
-- int index, total, new_length, placed;
-+ int total, new_length, placed;
- NautilusIcon *icon;
-- int width, height, max_width, icon_width, icon_height;
-+ int width, height, max_width, column_width, icon_width, icon_height;
- int x, y, x1, x2, y1, y2;
-- int *grid_memory;
-- int **icon_grid;
-- int num_rows, num_columns;
-- int row, column;
- ArtDRect icon_rect;
-
- /* Get container dimensions */
-@@ -1168,6 +1358,7 @@
- new_length = g_list_length (icons);
- placed = total - new_length;
- if (placed > 0) {
-+ PlacementGrid *grid;
- /* Add only placed icons in list */
- for (p = container->details->icons; p != NULL; p = p->next) {
- icon = p->data;
-@@ -1181,54 +1372,40 @@
- }
- placed_icons = g_list_reverse (placed_icons);
- unplaced_icons = g_list_reverse (unplaced_icons);
--
-- /* Allocate grid array */
-- num_rows = width / CELL_SIZE;
-- num_columns = height / CELL_SIZE;
--
-- /* Allocate array memory */
-- grid_memory = malloc (num_rows * num_columns * sizeof (int *));
-- g_assert (grid_memory);
--
-- /* Allocate room for the pointers to the rows */
-- icon_grid = malloc (num_rows * sizeof (int *));
-- g_assert (icon_grid);
--
-- /* Point to array pointers */
-- for (index = 0; index < num_rows; index++) {
-- icon_grid[index] = grid_memory + (index * num_columns);
-- }
--
-- /* Set all grid values to unfilled */
-- for (row = 0; row < num_rows; row++) {
-- for (column = 0; column < num_columns; column++) {
-- icon_grid [row] [column] = 0;
-- }
-- }
--
-- /* Mark filled grid locations */
-- mark_icon_locations_in_grid (placed_icons, icon_grid, num_rows, num_columns);
-
-- /* Place unplaced icons in the best locations */
-- for (p = unplaced_icons; p != NULL; p = p->next) {
-- icon = p->data;
-- get_best_empty_grid_location (icon, icon_grid, num_rows, num_columns,
-- &x, &y);
-+ grid = placement_grid_new (container, FALSE);
-
-- icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
-- icon_width = x2 - x1;
-+ if (grid) {
-+ for (p = placed_icons; p != NULL; p = p->next) {
-+ placement_grid_mark_icon
-+ (grid, (NautilusIcon*)p->data);
-+ }
-
-- icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+ /* Place unplaced icons in the best locations */
-+ for (p = unplaced_icons; p != NULL; p = p->next) {
-+ icon = p->data;
-+
-+ icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+ icon_get_bounding_box (icon,
-+ &x1, &y1, &x2, &y2);
-+
-+ /* Start the icon in the first column */
-+ x = DESKTOP_PAD_HORIZONTAL + SNAP_SIZE - ((x2 - x1) / 2);
-+ y = DESKTOP_PAD_VERTICAL + SNAP_SIZE - (icon_rect.y1 - icon_rect.y0);
-+
-+ find_empty_location (container,
-+ grid,
-+ icon,
-+ x, y,
-+ &x, &y);
-+
-+ icon_set_position (icon, x, y);
-+ placement_grid_mark_icon (grid, icon);
-+ }
-
-- icon_set_position (icon,
-- x + (icon_width - (icon_rect.x1 - icon_rect.x0)) / 2, y);
-- /* Add newly placed icon to grid */
-- mark_icon_location_in_grid (icon, icon_grid, num_rows, num_columns);
-+ placement_grid_free (grid);
- }
--
-- /* Clean up */
-- free (icon_grid);
-- free (grid_memory);
-+
- g_list_free (placed_icons);
- g_list_free (unplaced_icons);
- } else {
-@@ -1236,18 +1413,32 @@
- x = DESKTOP_PAD_HORIZONTAL;
-
- while (icons != NULL) {
-+ int center_x;
-+ int baseline;
-+ gboolean should_snap;
-+
-+ should_snap = !(container->details->tighter_layout && !container->details->keep_aligned);
-+
- y = DESKTOP_PAD_VERTICAL;
-- max_width = 0;
-
-+ max_width = 0;
-+
- /* Calculate max width for column */
- for (p = icons; p != NULL; p = p->next) {
- icon = p->data;
--
- icon_get_bounding_box (icon, &x1, &y1, &x2, &y2);
-
- icon_width = x2 - x1;
- icon_height = y2 - y1;
--
-+
-+ if (should_snap) {
-+ /* Snap the baseline to a grid position */
-+ icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+ baseline = y + (icon_rect.y1 - icon_rect.y0);
-+ baseline = SNAP_CEIL_VERTICAL (baseline);
-+ y = baseline - (icon_rect.y1 - icon_rect.y0);
-+ }
-+
- /* Check and see if we need to move to a new column */
- if (y != DESKTOP_PAD_VERTICAL && y > height - icon_height) {
- break;
-@@ -1261,6 +1452,15 @@
- }
-
- y = DESKTOP_PAD_VERTICAL;
-+
-+ center_x = x + max_width / 2;
-+ column_width = max_width;
-+ if (should_snap) {
-+ /* Find the grid column to center on */
-+ center_x = SNAP_CEIL_HORIZONTAL (center_x);
-+ column_width = (center_x - x) + (max_width / 2);
-+ }
-+
- /* Lay out column */
- for (p = icons; p != NULL; p = p->next) {
- icon = p->data;
-@@ -1269,15 +1469,21 @@
- icon_height = y2 - y1;
-
- icon_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
-+
-+ if (should_snap) {
-+ baseline = y + (icon_rect.y1 - icon_rect.y0);
-+ baseline = SNAP_CEIL_VERTICAL (baseline);
-+ y = baseline - (icon_rect.y1 - icon_rect.y0);
-+ }
-
- /* Check and see if we need to move to a new column */
- if (y != DESKTOP_PAD_VERTICAL && y > height - icon_height) {
-- x += max_width + DESKTOP_PAD_HORIZONTAL;
-+ x += column_width + DESKTOP_PAD_HORIZONTAL;
- break;
- }
-
- icon_set_position (icon,
-- x + max_width / 2 - (icon_rect.x1 - icon_rect.x0) / 2,
-+ center_x - (icon_rect.x1 - icon_rect.x0) / 2,
- y);
-
- y += icon_height + DESKTOP_PAD_VERTICAL;
-@@ -1493,6 +1699,7 @@
- int x, int y,
- double scale_x, double scale_y,
- gboolean raise,
-+ gboolean snap,
- gboolean update_position)
- {
- NautilusIconContainerDetails *details;
-@@ -1507,13 +1714,6 @@
- end_renaming_mode (container, TRUE);
- }
-
-- if (!details->auto_layout) {
-- if (x != icon->x || y != icon->y) {
-- icon_set_position (icon, x, y);
-- emit_signal = update_position;
-- }
-- }
--
- if (scale_x != icon->scale_x || scale_y != icon->scale_y) {
- icon->scale_x = scale_x;
- icon->scale_y = scale_y;
-@@ -1522,7 +1722,17 @@
- redo_layout (container);
- emit_signal = TRUE;
- }
-+ }
-+
-+ if (!details->auto_layout) {
-+ if (details->keep_aligned && snap) {
-+ snap_position (container, icon, &x, &y);
-+ }
-
-+ if (x != icon->x || y != icon->y) {
-+ icon_set_position (icon, x, y);
-+ emit_signal = update_position;
-+ }
- }
-
- if (emit_signal) {
-@@ -2598,6 +2808,12 @@
- g_source_remove (container->details->stretch_idle_id);
- container->details->stretch_idle_id = 0;
- }
-+
-+ if (container->details->align_idle_id != 0) {
-+ g_source_remove (container->details->align_idle_id);
-+ container->details->align_idle_id = 0;
-+ }
-+
-
- nautilus_icon_container_flush_typeselect_state (container);
-
-@@ -2985,7 +3201,7 @@
- &world_x, &world_y);
-
- icon_set_position (icon, world_x, world_y);
-- icon_set_size (container, icon, stretch_state.icon_size, FALSE);
-+ icon_set_size (container, icon, stretch_state.icon_size, FALSE, FALSE);
-
- container->details->stretch_idle_id = 0;
-
-@@ -3062,6 +3278,7 @@
- icon_set_size (container,
- stretched_icon,
- container->details->stretch_initial_size,
-+ TRUE,
- TRUE);
-
- container->details->stretch_icon = NULL;
-@@ -5113,7 +5330,7 @@
- nautilus_icon_container_move_icon (container, icon,
- icon->x, icon->y,
- 1.0, 1.0,
-- FALSE, TRUE);
-+ FALSE, TRUE, TRUE);
- }
- }
- }
-@@ -5251,6 +5468,57 @@
- }
- }
-
-+gboolean
-+nautilus_icon_container_is_keep_aligned (NautilusIconContainer *container)
-+{
-+ return container->details->keep_aligned;
-+}
-+
-+static gboolean
-+align_icons_callback (gpointer callback_data)
-+{
-+ NautilusIconContainer *container;
-+
-+ container = NAUTILUS_ICON_CONTAINER (callback_data);
-+ align_icons (container);
-+ container->details->align_idle_id = 0;
-+
-+ return FALSE;
-+}
-+
-+static void
-+unschedule_align_icons (NautilusIconContainer *container)
-+{
-+ if (container->details->align_idle_id != 0) {
-+ g_source_remove (container->details->align_idle_id);
-+ container->details->align_idle_id = 0;
-+ }
-+}
-+
-+static void
-+schedule_align_icons (NautilusIconContainer *container)
-+{
-+ if (container->details->align_idle_id == 0
-+ && container->details->has_been_allocated) {
-+ container->details->align_idle_id = g_idle_add
-+ (align_icons_callback, container);
-+ }
-+}
-+
-+void
-+nautilus_icon_container_set_keep_aligned (NautilusIconContainer *container,
-+ gboolean keep_aligned)
-+{
-+ if (container->details->keep_aligned != keep_aligned) {
-+ container->details->keep_aligned = keep_aligned;
-+
-+ if (keep_aligned && !container->details->auto_layout) {
-+ schedule_align_icons (container);
-+ } else {
-+ unschedule_align_icons (container);
-+ }
-+ }
-+}
-
- void
- nautilus_icon_container_set_layout_mode (NautilusIconContainer *container,
-Index: libnautilus-private/nautilus-icon-container.h
-===================================================================
-RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.h,v
-retrieving revision 1.78
-diff -u -r1.78 nautilus-icon-container.h
---- libnautilus-private/nautilus-icon-container.h 7 Apr 2003 11:56:03 -0000 1.78
-+++ libnautilus-private/nautilus-icon-container.h 3 May 2003 23:21:42 -0000
-@@ -205,6 +205,10 @@
- gboolean nautilus_icon_container_is_tighter_layout (NautilusIconContainer *container);
- void nautilus_icon_container_set_tighter_layout (NautilusIconContainer *container,
- gboolean tighter_layout);
-+
-+gboolean nautilus_icon_container_is_keep_aligned (NautilusIconContainer *container);
-+void nautilus_icon_container_set_keep_aligned (NautilusIconContainer *container,
-+ gboolean keep_aligned);
- void nautilus_icon_container_set_layout_mode (NautilusIconContainer *container,
- NautilusIconLayoutMode mode);
- void nautilus_icon_container_sort (NautilusIconContainer *container);
-Index: libnautilus-private/nautilus-icon-dnd.c
-===================================================================
-RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-dnd.c,v
-retrieving revision 1.130
-diff -u -r1.130 nautilus-icon-dnd.c
---- libnautilus-private/nautilus-icon-dnd.c 23 Apr 2003 09:49:47 -0000 1.130
-+++ libnautilus-private/nautilus-icon-dnd.c 3 May 2003 23:21:43 -0000
-@@ -811,7 +811,7 @@
- (container, icon,
- world_x + item->icon_x, world_y + item->icon_y,
- icon->scale_x, icon->scale_y,
-- TRUE, TRUE);
-+ TRUE, TRUE, TRUE);
- }
- moved_icons = g_list_prepend (moved_icons, icon);
- }
-Index: libnautilus-private/nautilus-icon-private.h
-===================================================================
-RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-private.h,v
-retrieving revision 1.71
-diff -u -r1.71 nautilus-icon-private.h
---- libnautilus-private/nautilus-icon-private.h 27 Mar 2003 12:53:07 -0000 1.71
-+++ libnautilus-private/nautilus-icon-private.h 3 May 2003 23:21:43 -0000
-@@ -177,6 +177,9 @@
- /* Idle handler for stretch code */
- guint stretch_idle_id;
-
-+ /* Align idle id */
-+ guint align_idle_id;
-+
- /* DnD info. */
- NautilusIconDndInfo *dnd_info;
-
-@@ -215,7 +218,10 @@
- /* Layout mode */
- NautilusIconLayoutMode layout_mode;
-
-- /* Set to TRUE after first allocation has been done */
-+ /* Should the container keep icons aligned to a grid */
-+ gboolean keep_aligned;
-+
-+ /* Set to TRUE after first allocation has been done */
- gboolean has_been_allocated;
-
- /* Is the container fixed or resizable */
-@@ -252,6 +258,7 @@
- double scale_x,
- double scale_y,
- gboolean raise,
-+ gboolean snap,
- gboolean update_position);
- void nautilus_icon_container_select_list_unselect_others (NautilusIconContainer *container,
- GList *icons);
-Index: libnautilus-private/nautilus-metadata.h
-===================================================================
-RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-metadata.h,v
-retrieving revision 1.25
-diff -u -r1.25 nautilus-metadata.h
---- libnautilus-private/nautilus-metadata.h 19 Dec 2002 19:56:36 -0000 1.25
-+++ libnautilus-private/nautilus-metadata.h 3 May 2003 23:21:43 -0000
-@@ -53,6 +53,7 @@
- #define NAUTILUS_METADATA_KEY_ICON_VIEW_TIGHTER_LAYOUT "icon_view_tighter_layout"
- #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_LIST_VIEW_ZOOM_LEVEL "list_view_zoom_level"
- #define NAUTILUS_METADATA_KEY_LIST_VIEW_SORT_COLUMN "list_view_sort_column"
-Index: src/file-manager/fm-desktop-icon-view.c
-===================================================================
-RCS file: /cvs/gnome/nautilus/src/file-manager/fm-desktop-icon-view.c,v
-retrieving revision 1.202
-diff -u -r1.202 fm-desktop-icon-view.c
---- src/file-manager/fm-desktop-icon-view.c 23 Apr 2003 10:49:38 -0000 1.202
-+++ src/file-manager/fm-desktop-icon-view.c 3 May 2003 23:21:43 -0000
-@@ -121,6 +121,7 @@
- FMDesktopIconView *icon_view);
- static void update_desktop_directory (UpdateType type);
- static gboolean real_supports_auto_layout (FMIconView *view);
-+static gboolean real_supports_keep_aligned (FMIconView *view);
- static void real_merge_menus (FMDirectoryView *view);
- static void real_update_menus (FMDirectoryView *view);
- static gboolean real_supports_zooming (FMDirectoryView *view);
-@@ -300,6 +301,7 @@
- FM_DIRECTORY_VIEW_CLASS (class)->supports_zooming = real_supports_zooming;
-
- FM_ICON_VIEW_CLASS (class)->supports_auto_layout = real_supports_auto_layout;
-+ FM_ICON_VIEW_CLASS (class)->supports_keep_aligned = real_supports_keep_aligned;
- }
-
- static void
-@@ -1470,6 +1472,12 @@
- * fixed-size window.
- */
- return FALSE;
-+}
-+
-+static gboolean
-+real_supports_keep_aligned (FMIconView *view)
-+{
-+ return TRUE;
- }
-
- static gboolean
-Index: src/file-manager/fm-icon-view.c
-===================================================================
-RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
-retrieving revision 1.278
-diff -u -r1.278 fm-icon-view.c
---- src/file-manager/fm-icon-view.c 7 Apr 2003 11:56:04 -0000 1.278
-+++ src/file-manager/fm-icon-view.c 3 May 2003 23:21:43 -0000
-@@ -98,10 +98,12 @@
- #define COMMAND_TIGHTER_LAYOUT "/commands/Tighter Layout"
- #define COMMAND_SORT_REVERSED "/commands/Reversed Order"
- #define COMMAND_CLEAN_UP "/commands/Clean Up"
-+#define COMMAND_KEEP_ALIGNED "/commands/Keep Aligned"
-
- #define ID_MANUAL_LAYOUT "Manual Layout"
- #define ID_TIGHTER_LAYOUT "Tighter Layout"
- #define ID_SORT_REVERSED "Reversed Order"
-+#define ID_KEEP_ALIGNED "Keep Aligned"
-
- typedef struct {
- NautilusFileSortType sort_type;
-@@ -578,6 +580,16 @@
- supports_auto_layout, (view));
- }
-
-+static gboolean
-+fm_icon_view_supports_keep_aligned (FMIconView *view)
-+{
-+ g_return_val_if_fail (FM_IS_ICON_VIEW (view), FALSE);
-+
-+ return EEL_CALL_METHOD_WITH_RETURN_VALUE
-+ (FM_ICON_VIEW_CLASS, view,
-+ supports_keep_aligned, (view));
-+}
-+
- static void
- update_layout_menus (FMIconView *view)
- {
-@@ -617,6 +629,18 @@
- nautilus_bonobo_set_sensitive
- (view->details->ui, COMMAND_CLEAN_UP, !is_auto_layout);
-
-+
-+ nautilus_bonobo_set_hidden (view->details->ui,
-+ COMMAND_KEEP_ALIGNED,
-+ !fm_icon_view_supports_keep_aligned (view));
-+
-+ nautilus_bonobo_set_toggle_state
-+ (view->details->ui, COMMAND_KEEP_ALIGNED,
-+ nautilus_icon_container_is_keep_aligned (get_icon_container (view)));
-+
-+ nautilus_bonobo_set_sensitive
-+ (view->details->ui, COMMAND_KEEP_ALIGNED, !is_auto_layout);
-+
- bonobo_ui_component_thaw (view->details->ui, NULL);
- }
-
-@@ -753,6 +777,41 @@
- sort_reversed);
- }
-
-+static gboolean
-+get_default_directory_keep_aligned (void)
-+{
-+ return TRUE;
-+}
-+
-+static gboolean
-+fm_icon_view_get_directory_keep_aligned (FMIconView *icon_view,
-+ NautilusFile *file)
-+{
-+ if (!fm_icon_view_supports_keep_aligned (icon_view)) {
-+ return FALSE;
-+ }
-+
-+ return nautilus_file_get_boolean_metadata
-+ (file,
-+ NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED,
-+ get_default_directory_keep_aligned ());
-+}
-+
-+static void
-+fm_icon_view_set_directory_keep_aligned (FMIconView *icon_view,
-+ NautilusFile *file,
-+ gboolean keep_aligned)
-+{
-+ if (!fm_icon_view_supports_keep_aligned (icon_view)) {
-+ return;
-+ }
-+
-+ nautilus_file_set_boolean_metadata
-+ (file, NAUTILUS_METADATA_KEY_ICON_VIEW_KEEP_ALIGNED,
-+ get_default_directory_keep_aligned (),
-+ keep_aligned);
-+}
-+
- /* maintainence of auto layout boolean */
- static gboolean default_directory_manual_layout = FALSE;
-
-@@ -880,6 +939,14 @@
- }
-
- static gboolean
-+real_supports_keep_aligned (FMIconView *view)
-+{
-+ g_return_val_if_fail (FM_IS_ICON_VIEW (view), FALSE);
-+
-+ return FALSE;
-+}
-+
-+static gboolean
- set_sort_reversed (FMIconView *icon_view, gboolean new_value)
- {
- if (icon_view->details->sort_reversed == new_value) {
-@@ -1005,6 +1072,9 @@
- /* Set the sort direction from the metadata. */
- set_sort_reversed (icon_view, fm_icon_view_get_directory_sort_reversed (icon_view, file));
-
-+ nautilus_icon_container_set_keep_aligned
-+ (get_icon_container (icon_view),
-+ fm_icon_view_get_directory_keep_aligned (icon_view, file));
- nautilus_icon_container_set_tighter_layout
- (get_icon_container (icon_view),
- fm_icon_view_get_directory_tighter_layout (icon_view, file));
-@@ -1287,6 +1357,37 @@
- }
-
- static void
-+keep_aligned_state_changed_callback (BonoboUIComponent *component,
-+ const char *path,
-+ Bonobo_UIComponent_EventType type,
-+ const char *state,
-+ gpointer user_data)
-+{
-+ FMIconView *icon_view;
-+ NautilusFile *file;
-+ gboolean keep_aligned;
-+
-+ g_assert (strcmp (path, ID_KEEP_ALIGNED) == 0);
-+
-+ icon_view = FM_ICON_VIEW (user_data);
-+
-+ if (strcmp (state, "") == 0) {
-+ /* State goes blank when component is removed; ignore this. */
-+ return;
-+ }
-+
-+ keep_aligned = strcmp (state, "1") == 0 ? TRUE : FALSE;
-+
-+ file = fm_directory_view_get_directory_as_file (FM_DIRECTORY_VIEW (icon_view));
-+ fm_icon_view_set_directory_keep_aligned (icon_view,
-+ file,
-+ keep_aligned);
-+
-+ nautilus_icon_container_set_keep_aligned (get_icon_container (icon_view),
-+ keep_aligned);
-+}
-+
-+static void
- switch_to_manual_layout (FMIconView *icon_view)
- {
- if (!fm_icon_view_using_auto_layout (icon_view)) {
-@@ -1393,6 +1494,7 @@
-
- bonobo_ui_component_add_listener (icon_view->details->ui, ID_TIGHTER_LAYOUT, tighter_layout_state_changed_callback, view);
- bonobo_ui_component_add_listener (icon_view->details->ui, ID_SORT_REVERSED, sort_reversed_state_changed_callback, view);
-+ bonobo_ui_component_add_listener (icon_view->details->ui, ID_KEEP_ALIGNED, keep_aligned_state_changed_callback, view);
- icon_view->details->menus_ready = TRUE;
-
- bonobo_ui_component_freeze (icon_view->details->ui, NULL);
-@@ -1472,6 +1574,8 @@
-
- set_sort_criterion (icon_view, get_sort_criterion_by_sort_type (get_default_sort_order ()));
- set_sort_reversed (icon_view, get_default_sort_in_reverse_order ());
-+ nautilus_icon_container_set_keep_aligned
-+ (icon_container, get_default_directory_keep_aligned ());
- nautilus_icon_container_set_tighter_layout
- (icon_container, get_default_directory_tighter_layout ());
-
-@@ -2520,6 +2624,7 @@
-
- klass->clean_up = fm_icon_view_real_clean_up;
- klass->supports_auto_layout = real_supports_auto_layout;
-+ klass->supports_keep_aligned = real_supports_keep_aligned;
- klass->get_directory_auto_layout = fm_icon_view_real_get_directory_auto_layout;
- klass->get_directory_sort_by = fm_icon_view_real_get_directory_sort_by;
- klass->get_directory_sort_reversed = fm_icon_view_real_get_directory_sort_reversed;
-Index: src/file-manager/fm-icon-view.h
-===================================================================
-RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.h,v
-retrieving revision 1.12
-diff -u -r1.12 fm-icon-view.h
---- src/file-manager/fm-icon-view.h 4 Feb 2003 10:36:21 -0000 1.12
-+++ src/file-manager/fm-icon-view.h 3 May 2003 23:21:43 -0000
-@@ -84,6 +84,12 @@
- */
- gboolean (* supports_auto_layout) (FMIconView *view);
-
-+ /* supports_auto_layout is a function pointer that subclasses may
-+ * override to control whether snap-to-grid mode
-+ * should be enabled. The default implementation returns FALSE.
-+ */
-+ gboolean (* supports_keep_aligned) (FMIconView *view);
-+
- };
-
- /* GObject support */
-Index: src/file-manager/nautilus-icon-view-ui.xml
-===================================================================
-RCS file: /cvs/gnome/nautilus/src/file-manager/nautilus-icon-view-ui.xml,v
-retrieving revision 1.23
-diff -u -r1.23 nautilus-icon-view-ui.xml
---- src/file-manager/nautilus-icon-view-ui.xml 5 Jul 2002 20:37:24 -0000 1.23
-+++ src/file-manager/nautilus-icon-view-ui.xml 3 May 2003 23:21:44 -0000
-@@ -24,6 +24,9 @@
- <cmd name="Sort by Emblems"
- _label="By _Emblems"
- _tip="Keep icons sorted by emblems in rows"/>
-+ <cmd name="Keep Aligned"
-+ _label="_Keep Aligned"
-+ _tip="Keep icons lined up on a grid"/>
- <cmd name="Tighter Layout"
- _label="Compact _Layout"
- _tip="Toggle using a tighter layout scheme"/>
-@@ -78,6 +81,9 @@
- </submenu>
- <menuitem name="Clean Up"
- verb="Clean Up"/>
-+ <menuitem name="Keep Aligned"
-+ id="Keep Aligned"
-+ type="toggle"/>
- </placeholder>
-
- </submenu>
-@@ -108,6 +114,7 @@
- id="Sort by Emblems"/>
- </placeholder>
- <separator/>
-+
- <menuitem name="Tighter Layout"
- id="Tighter Layout"
- type="toggle"/>
-@@ -115,7 +122,11 @@
- id="Reversed Order"
- type="toggle"/>
- </submenu>
-+
- <menuitem name="Clean Up" verb="Clean Up"/>
-+ <menuitem name="Keep Aligned"
-+ id="Keep Aligned"
-+ type="toggle"/>
- </placeholder>
- </placeholder>
- </popup>