summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2000-01-25 23:49:39 +0000
committerDarin Adler <darin@src.gnome.org>2000-01-25 23:49:39 +0000
commit6d5f07d86e8a136fa00bd79b6b3db6f5c21838be (patch)
tree6220ee1730d638497022ecfebd0ddf63bd4b4367
parentc1e840df79970774e319916befafa4e905ed0881 (diff)
downloadnautilus-6d5f07d86e8a136fa00bd79b6b3db6f5c21838be.tar.gz
Redid drag code so that it will work if there are multiple windows
* libnautilus/gnome-icon-container-dnd.c: (create_selection_shadow): (set_gnome_icon_list_selection): (get_gnome_icon_list_selection): (gnome_icon_container_receive_dropped_icons): Redid drag code so that it will work if there are multiple windows involved, although we still don't handle copies. Changed selection to include the width and height of the icon, and to hold the top left of the icon. * libnautilus/gnome-icon-container-private.h: libnautilus/gnome-icon-container.c: (move_icon): (gnome_icon_container_move_icon): Made move_icon visible to the DnD code, and added a raise boolean so it could move and icon and bring it to the front. (gnome_icon_container_get_icon_by_uri): (gnome_icon_container_select_list_unselect_others): Added new functions for use by DnD code. * libnautilus/gnome-icon-container-private.h: libnautilus/gnome-icon-container.c: (handle_icon_button_press): Got rid of unused drag_x_offset and drag_y_offset. * libnautilus/gnome-icon-container.c: (icon_select): (icon_toggle_selected): (select_icon): (select_one_unselect_others): (toggle_icon): (unselect_all_but_one): (unselect_all): (rubberband_select_in_cell): (kbd_move_to): (kbd_space): (linger_select_timeout_cb): (handle_icon_button_press): (gnome_icon_container_select_all): (gnome_icon_container_unselect_all): Cleaned up selection logic and made it simpler. * libnautilus/gnome-icon-container.h: libnautilus/gnome-icon-container.c: (gnome_icon_container_xlate_selected): Got rid of unused function. * libnautilus/nautilus-self-checks.h: libnautilus/nautilus-self-checks.c: (nautilus_self_checks_failed): (nautilus_exit_if_self_checks_failed): src/ntl-main.c: (main): Added blank lines before and after the first and last failed checks when at least one check fails. * src/ntl-view.c: (nautilus_view_destroy): Removed a straggler message. (I hope Elliot's not still using it.) * RENAMING: Some new name ideas.
-rw-r--r--ChangeLog-2000041464
-rw-r--r--RENAMING8
-rw-r--r--libnautilus-extensions/gnome-icon-container-dnd.c113
-rw-r--r--libnautilus-extensions/gnome-icon-container-private.h11
-rw-r--r--libnautilus-extensions/gnome-icon-container.c235
-rw-r--r--libnautilus-extensions/gnome-icon-container.h5
-rw-r--r--libnautilus-extensions/nautilus-self-checks.c13
-rw-r--r--libnautilus-extensions/nautilus-self-checks.h24
-rw-r--r--libnautilus-private/gnome-icon-container-dnd.c113
-rw-r--r--libnautilus-private/gnome-icon-container-private.h11
-rw-r--r--libnautilus-private/gnome-icon-container.c235
-rw-r--r--libnautilus-private/gnome-icon-container.h5
-rw-r--r--libnautilus-private/nautilus-self-checks.c13
-rw-r--r--libnautilus-private/nautilus-self-checks.h24
-rw-r--r--libnautilus/gnome-icon-container-dnd.c113
-rw-r--r--libnautilus/gnome-icon-container-private.h11
-rw-r--r--libnautilus/gnome-icon-container.c235
-rw-r--r--libnautilus/gnome-icon-container.h5
-rw-r--r--libnautilus/nautilus-self-checks.c13
-rw-r--r--libnautilus/nautilus-self-checks.h24
-rw-r--r--src/nautilus-main.c3
-rw-r--r--src/nautilus-view-frame.c2
-rw-r--r--src/ntl-main.c3
-rw-r--r--src/ntl-view.c2
24 files changed, 662 insertions, 623 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414
index 58db90e7b..a5ff85b19 100644
--- a/ChangeLog-20000414
+++ b/ChangeLog-20000414
@@ -1,3 +1,67 @@
+2000-01-25 Darin Adler <darin@eazel.com>
+
+ * libnautilus/gnome-icon-container-dnd.c:
+ (create_selection_shadow):
+ (set_gnome_icon_list_selection):
+ (get_gnome_icon_list_selection):
+ (gnome_icon_container_receive_dropped_icons):
+ Redid drag code so that it will work if there are multiple
+ windows involved, although we still don't handle copies.
+ Changed selection to include the width and height of the icon,
+ and to hold the top left of the icon.
+
+ * libnautilus/gnome-icon-container-private.h:
+ libnautilus/gnome-icon-container.c:
+ (move_icon):
+ (gnome_icon_container_move_icon):
+ Made move_icon visible to the DnD code, and added a raise boolean
+ so it could move and icon and bring it to the front.
+ (gnome_icon_container_get_icon_by_uri):
+ (gnome_icon_container_select_list_unselect_others):
+ Added new functions for use by DnD code.
+
+ * libnautilus/gnome-icon-container-private.h:
+ libnautilus/gnome-icon-container.c:
+ (handle_icon_button_press):
+ Got rid of unused drag_x_offset and drag_y_offset.
+
+ * libnautilus/gnome-icon-container.c:
+ (icon_select):
+ (icon_toggle_selected):
+ (select_icon):
+ (select_one_unselect_others):
+ (toggle_icon):
+ (unselect_all_but_one):
+ (unselect_all):
+ (rubberband_select_in_cell):
+ (kbd_move_to):
+ (kbd_space):
+ (linger_select_timeout_cb):
+ (handle_icon_button_press):
+ (gnome_icon_container_select_all):
+ (gnome_icon_container_unselect_all):
+ Cleaned up selection logic and made it simpler.
+
+ * libnautilus/gnome-icon-container.h:
+ libnautilus/gnome-icon-container.c:
+ (gnome_icon_container_xlate_selected):
+ Got rid of unused function.
+
+ * libnautilus/nautilus-self-checks.h:
+ libnautilus/nautilus-self-checks.c:
+ (nautilus_self_checks_failed):
+ (nautilus_exit_if_self_checks_failed):
+ src/ntl-main.c:
+ (main):
+ Added blank lines before and after the first and last failed
+ checks when at least one check fails.
+
+ * src/ntl-view.c:
+ (nautilus_view_destroy):
+ Removed a straggler message. (I hope Elliot's not still using it.)
+
+ * RENAMING: Some new name ideas.
+
2000-01-25 John Sullivan <sullivan@eazel.com>
Better text for displayed file dates. This is currently used only
diff --git a/RENAMING b/RENAMING
index 18badbd66..9ab4e3e02 100644
--- a/RENAMING
+++ b/RENAMING
@@ -1,11 +1,13 @@
We put plans for renaming in here so we can think about them for a while.
+gdk-extensions.[ch] -> nautilus-gdk-extensions.[ch]
+ntl* -> nautilus*
+
ExplorerLocationBar -> NautilusLocationBar
FMIconCache -> NautilusIconFactory
-GnomeIconContainer -> NautilusIconsView
+
+GnomeIconContainer -> NautilusIconContainer
GtkFList -> NautilusList
-gdk-extensions -> nautilus-gdk-extensions
-ntl* -> nautilus*
FMDirectoryViewIcons -> FMDirectoryIconView
FMDirectoryViewList -> FMDirectoryListView
diff --git a/libnautilus-extensions/gnome-icon-container-dnd.c b/libnautilus-extensions/gnome-icon-container-dnd.c
index 5d7eb56ca..2ad08b3ef 100644
--- a/libnautilus-extensions/gnome-icon-container-dnd.c
+++ b/libnautilus-extensions/gnome-icon-container-dnd.c
@@ -40,11 +40,12 @@
-struct _DndSelectionItem {
+typedef struct {
char *uri;
- int x, y;
-};
-typedef struct _DndSelectionItem DndSelectionItem;
+ gboolean got_icon_position;
+ int icon_x, icon_y;
+ int icon_width, icon_height;
+} DndSelectionItem;
static GtkTargetEntry drag_types [] = {
{ GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST_TYPE, 0, GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST },
@@ -61,9 +62,6 @@ static GtkTargetEntry drop_types [] = {
};
static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
-/* number of pixels of margin for shadow box */
-#define SHADOW_MARGIN 8
-
static GnomeCanvasItem *
create_selection_shadow (GnomeIconContainer *container,
GList *list)
@@ -73,9 +71,6 @@ create_selection_shadow (GnomeIconContainer *container,
GdkBitmap *stipple;
int max_x, max_y;
int min_x, min_y;
- int icon_width, icon_height;
- int cell_width;
- int x_offset;
GList *p;
if (list == NULL)
@@ -84,11 +79,6 @@ create_selection_shadow (GnomeIconContainer *container,
stipple = container->details->dnd_info->stipple;
g_return_val_if_fail (stipple != NULL, NULL);
- icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
- icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
- cell_width = GNOME_ICON_CONTAINER_CELL_WIDTH (container);
- x_offset = cell_width - icon_width - SHADOW_MARGIN;
-
canvas = GNOME_CANVAS (container);
/* Creating a big set of rectangles in the canvas can be expensive, so
@@ -115,10 +105,13 @@ create_selection_shadow (GnomeIconContainer *container,
item = p->data;
- x1 = item->x + x_offset;
- y1 = item->y;
- x2 = item->x + icon_width + x_offset;
- y2 = item->y + icon_height;
+ if (!item->got_icon_position)
+ continue;
+
+ x1 = item->icon_x;
+ y1 = item->icon_y;
+ x2 = x1 + item->icon_width;
+ y2 = y1 + item->icon_height;
if (x2 >= min_x && x1 <= max_x && y2 >= min_y && y1 <= max_y) {
GnomeCanvasItem *rect;
@@ -167,10 +160,7 @@ dnd_selection_item_new (void)
{
DndSelectionItem *new;
- new = g_new (DndSelectionItem, 1);
- new->uri = NULL;
- new->x = 0;
- new->y = 0;
+ new = g_new0 (DndSelectionItem, 1);
return new;
}
@@ -198,7 +188,10 @@ destroy_selection_list (GList *list)
/* Source-side handling of the drag. */
-/* Encode a "special/x-gnome-icon-list" selection. */
+/* Encode a "special/x-gnome-icon-list" selection.
+ Along with the URIs of the dragged files, this encodes
+ the location and size of each icon relative to the cursor.
+*/
static void
set_gnome_icon_list_selection (GnomeIconContainer *container,
GtkSelectionData *selection_data)
@@ -206,28 +199,29 @@ set_gnome_icon_list_selection (GnomeIconContainer *container,
GnomeIconContainerDetails *details;
GList *p;
GString *data;
- gdouble x_offset, y_offset;
details = container->details;
- x_offset = details->dnd_info->start_x;
- y_offset = details->dnd_info->start_y;
data = g_string_new (NULL);
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
char *uri;
char *s;
- int x, y;
+ int icon_x, icon_y, icon_width, icon_height;
icon = p->data;
if (!icon->is_selected)
continue;
- x = icon->x - x_offset - (GNOME_ICON_CONTAINER_ICON_WIDTH (container) / 2);
- y = icon->y - y_offset;
+ /* Corner of the icon relative to the cursor. */
+ icon_x = icon->x - details->dnd_info->start_x;
+ icon_y = icon->y - details->dnd_info->start_y;
+ icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
+ icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
uri = nautilus_icons_controller_get_icon_uri (details->controller, icon->data);
- s = g_strdup_printf ("%s\r%d:%d\r\n", uri, x, y);
+ s = g_strdup_printf ("%s\r%d:%d:%d:%d\r\n",
+ uri, icon_x, icon_y, icon_width, icon_height);
g_free (uri);
g_string_append (data, s);
@@ -364,9 +358,12 @@ get_gnome_icon_list_selection (GnomeIconContainer *container,
/* 2: Decode geometry information. */
- if (sscanf (p, "%d:%d%*s", &item->x, &item->y) != 2)
+ item->got_icon_position = sscanf (p, "%d:%d:%d:%d%*s",
+ &item->icon_x, &item->icon_y,
+ &item->icon_height, &item->icon_width) == 4;
+ if (!item->got_icon_position)
g_warning ("Invalid special/x-gnome-icon-list data received: "
- "invalid geometry specification.");
+ "invalid icon position specification.");
dnd_info->selection_list
= g_list_prepend (dnd_info->selection_list, item);
@@ -527,6 +524,7 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
int x, int y)
{
GnomeIconContainerDndInfo *dnd_info;
+ GList *p;
dnd_info = container->details->dnd_info;
if (dnd_info->selection_list == NULL)
@@ -551,14 +549,41 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
*/
if (context->action == GDK_ACTION_MOVE) {
double world_x, world_y;
-
+ GList *icons_to_select;
+
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
-
- gnome_icon_container_xlate_selected (container,
- world_x - dnd_info->start_x,
- world_y - dnd_info->start_y,
- TRUE);
+
+ icons_to_select = NULL;
+ for (p = dnd_info->selection_list; p != NULL; p = p->next) {
+ DndSelectionItem *item;
+ GnomeIconContainerIcon *icon;
+
+ item = p->data;
+ icon = gnome_icon_container_get_icon_by_uri
+ (container, item->uri);
+
+ if (icon == NULL) {
+ g_warning ("drag between containers not implemented yet");
+ continue;
+ }
+
+ if (item->got_icon_position) {
+ int icon_x, icon_y;
+
+ icon_x = (int) world_x + item->icon_x;
+ icon_y = (int) world_y + item->icon_y;
+
+ gnome_icon_container_move_icon
+ (container, icon, icon_x, icon_y, TRUE);
+ }
+
+ icons_to_select = g_list_prepend (icons_to_select, icon);
+ }
+
+ gnome_icon_container_select_list_unselect_others (container, icons_to_select);
+
+ g_list_free (icons_to_select);
}
destroy_selection_list (dnd_info->selection_list);
@@ -627,6 +652,12 @@ drag_leave_cb (GtkWidget *widget,
guint32 time,
gpointer data)
{
+ GnomeIconContainerDndInfo *dnd_info;
+
+ dnd_info = GNOME_ICON_CONTAINER (widget)->details->dnd_info;
+
+ if (dnd_info->shadow != NULL)
+ gnome_canvas_item_hide (dnd_info->shadow);
}
void
@@ -735,8 +766,8 @@ gnome_icon_container_dnd_begin_drag (GnomeIconContainer *container,
pixbuf_args[0].name = "NautilusIconsViewIconItem::pixbuf";
gtk_object_getv (GTK_OBJECT (pixbuf_item), 1, pixbuf_args);
temp_pixbuf = (GdkPixbuf *) GTK_VALUE_OBJECT (pixbuf_args[0]);
- gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
-
+ gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
+
/* set the pixmap and mask for dragging */
gtk_drag_set_icon_pixmap (context, gtk_widget_get_colormap (GTK_WIDGET (container)),
pixmap_for_dragged_file, mask_for_dragged_file,
diff --git a/libnautilus-extensions/gnome-icon-container-private.h b/libnautilus-extensions/gnome-icon-container-private.h
index a60dee6a2..4ad49aa42 100644
--- a/libnautilus-extensions/gnome-icon-container-private.h
+++ b/libnautilus-extensions/gnome-icon-container-private.h
@@ -149,9 +149,6 @@ struct _GnomeIconContainerDetails {
/* Whether we are actually performing a dragging action. */
gboolean doing_drag;
- /* Drag offset. */
- int drag_x_offset, drag_y_offset;
-
/* Idle ID. */
guint idle_id;
@@ -181,4 +178,12 @@ struct _GnomeIconContainerDetails {
#define GNOME_ICON_CONTAINER_ICON_WIDTH(container) 48
#define GNOME_ICON_CONTAINER_ICON_HEIGHT(container) 48
+GnomeIconContainerIcon *gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri);
+void gnome_icon_container_move_icon (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon,
+ int x, int y, gboolean raise);
+void gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons);
+
#endif /* GNOME_ICON_CONTAINER_PRIVATE_H */
diff --git a/libnautilus-extensions/gnome-icon-container.c b/libnautilus-extensions/gnome-icon-container.c
index c48fa7ac4..075e0ccb9 100644
--- a/libnautilus-extensions/gnome-icon-container.c
+++ b/libnautilus-extensions/gnome-icon-container.c
@@ -45,7 +45,8 @@
/* Timeout for making the icon currently selected for keyboard operation
visible. FIXME: This *must* be higher than the double-click time in GDK,
- but there is no way to access its value from outside. */
+ but there is no way to access its value from outside.
+*/
#define KBD_ICON_VISIBILITY_TIMEOUT 300
/* Timeout for selecting an icon in "linger-select" mode (i.e. by just placing the
@@ -175,29 +176,24 @@ icon_show (GnomeIconContainerIcon *icon)
}
static void
-icon_select (GnomeIconContainerIcon *icon,
- gboolean sel)
+icon_toggle_selected (GnomeIconContainerIcon *icon)
{
-
- if (sel == icon->is_selected)
- return;
-
- icon->is_selected = sel;
+ icon->is_selected = !icon->is_selected;
gnome_canvas_item_set (GNOME_CANVAS_ITEM (icon->item),
- "selected", (gboolean) sel,
+ "selected", (gboolean) icon->is_selected,
NULL);
}
+/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-icon_toggle_selection (GnomeIconContainerIcon *icon)
+icon_select (GnomeIconContainerIcon *icon,
+ gboolean select)
{
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- return TRUE;
- } else {
- icon_select (icon, TRUE);
+ if (select == icon->is_selected)
return FALSE;
- }
+
+ icon_toggle_selected (icon);
+ return TRUE;
}
static gboolean
@@ -984,37 +980,9 @@ button_event_modifies_selection (GdkEventButton *event)
return event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK);
}
-
-/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-select_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon,
- gboolean sel)
-{
- GnomeIconContainerDetails *details;
- gboolean was_selected;
-
- details = container->details;
-
- was_selected = icon->is_selected;
- icon_select (icon, sel);
-
- if ((! was_selected && sel) || (was_selected && ! sel))
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-toggle_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon)
-{
- icon_toggle_selection (icon);
-}
-
-static gboolean
-unselect_all_but_one (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon_to_avoid)
+select_one_unselect_others (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon_to_select)
{
GnomeIconContainerDetails *details;
GList *p;
@@ -1022,31 +990,28 @@ unselect_all_but_one (GnomeIconContainer *container,
details = container->details;
selection_changed = FALSE;
-
+
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (icon != icon_to_avoid && icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
+ selection_changed |= icon_select (icon, icon == icon_to_select);
}
-
+
return selection_changed;
}
static gboolean
unselect_all (GnomeIconContainer *container)
{
- return unselect_all_but_one (container, NULL);
+ return select_one_unselect_others (container, NULL);
}
/* FIXME: This could be optimized a bit. */
-static void
-move_icon (GnomeIconContainer *container,
+void
+gnome_icon_container_move_icon (GnomeIconContainer *container,
GnomeIconContainerIcon *icon,
- gint x, gint y)
+ int x, int y, gboolean raise)
{
GnomeIconContainerDetails *details;
gint old_x, old_y;
@@ -1088,6 +1053,12 @@ move_icon (GnomeIconContainer *container,
icon_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1);
icon_position (icon, container, x, y);
+ if (raise)
+ icon_raise (icon);
+
+ /* Update the keyboard selection indicator. */
+ if (details->kbd_current == icon)
+ set_kbd_current (container, icon, FALSE);
gtk_signal_emit (GTK_OBJECT (container), signals[ICON_MOVED],
icon->data, x, y);
@@ -1123,31 +1094,12 @@ rubberband_select_in_cell (GList *cell,
prev_x1, prev_y1,
prev_x2, prev_y2);
- if (in_curr_region && ! in_prev_region) {
- if (icon->was_selected_before_rubberband) {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- } else {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- }
- } else if (in_prev_region && ! in_curr_region) {
- if (icon->was_selected_before_rubberband) {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- } else {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- }
- }
+ if (in_curr_region && ! in_prev_region)
+ selection_changed |= icon_select (icon,
+ !icon->was_selected_before_rubberband);
+ else if (in_prev_region && ! in_curr_region)
+ selection_changed |= icon_select (icon,
+ icon->was_selected_before_rubberband);
}
return selection_changed;
@@ -1374,7 +1326,7 @@ kbd_move_to (GnomeIconContainer *container,
gboolean selection_changed;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -1661,7 +1613,7 @@ kbd_space (GnomeIconContainer *container,
GdkEventKey *event)
{
if (container->details->kbd_current != NULL) {
- if (select_icon (container, container->details->kbd_current, TRUE))
+ if (icon_select (container->details->kbd_current, TRUE))
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -1825,8 +1777,8 @@ button_release_event (GtkWidget *widget,
gboolean selection_changed;
selection_changed
- = unselect_all_but_one (container,
- details->drag_icon);
+ = select_one_unselect_others (container,
+ details->drag_icon);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -2104,7 +2056,7 @@ linger_select_timeout_cb (gpointer data)
icon = details->linger_selection_mode_icon;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
set_kbd_current (container, icon, FALSE);
make_icon_visible (container, icon);
@@ -2132,7 +2084,6 @@ handle_icon_button_press (GnomeIconContainer *container,
GdkEventButton *event)
{
GnomeIconContainerDetails *details;
- gdouble world_x, world_y;
details = container->details;
@@ -2154,12 +2105,12 @@ handle_icon_button_press (GnomeIconContainer *container,
return FALSE;
if (button_event_modifies_selection (event)) {
- toggle_icon (container, icon);
+ icon_toggle_selected (icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
} else if (! icon->is_selected) {
unselect_all (container);
- select_icon (container, icon, TRUE);
+ icon_select (icon, TRUE);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -2185,11 +2136,6 @@ handle_icon_button_press (GnomeIconContainer *container,
details->drag_x = event->x;
details->drag_y = event->y;
- gnome_canvas_window_to_world (GNOME_CANVAS (container), event->x, event->y,
- &world_x, &world_y);
- details->drag_x_offset = (gint) world_x - icon->x;
- details->drag_y_offset = (gint) world_y - icon->y;
-
return TRUE;
}
@@ -2689,28 +2635,17 @@ gnome_icon_container_get_selection (GnomeIconContainer *container)
void
gnome_icon_container_select_all (GnomeIconContainer *container)
{
- GnomeIconContainerDetails *details;
- GnomeIconContainerIconGrid *grid;
- GList **p, *q;
- guint i, j;
gboolean selection_changed;
+ GList *p;
- g_return_if_fail (container != NULL);
-
- details = container->details;
- grid = details->grid;
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
selection_changed = FALSE;
- p = grid->elems;
- for (i = 0; i < grid->height; i++) {
- for (j = 0; j < grid->width; j++) {
- for (q = p[j]; q != NULL; q =q->next) {
- if (select_icon (container, q->data, TRUE))
- selection_changed = TRUE;
- }
- }
+ for (p = container->details->icons; p != NULL; p = p->next) {
+ GnomeIconContainerIcon *icon;
- p += grid->alloc_width;
+ icon = p->data;
+ selection_changed |= icon_select (icon, TRUE);
}
if (selection_changed)
@@ -2719,29 +2654,32 @@ gnome_icon_container_select_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_unselect_all:
+ * gnome_icon_container_select_list_unselect_others:
* @container: An icon container widget.
+ * @list: A list of GnomeContainerIcons.
*
- * Deselect all the icons in @container.
+ * Select only the icons in the list, deselect all others.
**/
void
-gnome_icon_container_unselect_all (GnomeIconContainer *container)
+gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons)
{
- GnomeIconContainerDetails *details;
gboolean selection_changed;
GList *p;
- g_return_if_fail (container != NULL);
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
- details = container->details;
+ /* To avoid an N^2 algorithm, we could put the icons into a hash
+ table, but this should be OK for now.
+ */
selection_changed = FALSE;
- for (p = details->icons; p != NULL; p = p->next) {
+ for (p = container->details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (select_icon (container, icon, FALSE))
- selection_changed = TRUE;
+ selection_changed |= icon_select
+ (icon, g_list_find (icons, icon) != NULL);
}
if (selection_changed)
@@ -2750,43 +2688,56 @@ gnome_icon_container_unselect_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_xlate_selected:
+ * gnome_icon_container_unselect_all:
* @container: An icon container widget.
- * @amount_x: Amount of translation on the X axis.
- * @amount_y: Amount of translation on the Y axis.
- * @raise: Whether icons should be raised during this operation.
*
- * Translate all the currently selected items in @container by @amount_x
- * horizontally and @amount_y vertically. Positive values move to the
- * right/bottom, negative values to the left/top.
+ * Deselect all the icons in @container.
**/
void
-gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- gint amount_x,
- gint amount_y,
- gboolean raise)
+gnome_icon_container_unselect_all (GnomeIconContainer *container)
+{
+ if (unselect_all (container))
+ gtk_signal_emit (GTK_OBJECT (container),
+ signals[SELECTION_CHANGED]);
+}
+
+/**
+ * gnome_icon_container_get_icon_by_uri:
+ * @container: An icon container widget.
+ * @uri: The uri of an icon to find.
+ *
+ * Locate an icon, given the URI. The URI must match exactly.
+ * Later we may have to have some way of figuring out if the
+ * URI specifies the same object that does not require an exact match.
+ **/
+GnomeIconContainerIcon *
+gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri)
{
GnomeIconContainerDetails *details;
GList *p;
- g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
-
- if (amount_x == 0 && amount_y == 0)
- return;
+ /* Eventually, we must avoid searching the entire icon list,
+ but it's OK for now.
+ */
details = container->details;
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
+ char *icon_uri;
+ gboolean is_match;
icon = p->data;
- if (icon->is_selected) {
- move_icon (container, icon,
- icon->x + amount_x, icon->y + amount_y);
- if (raise)
- icon_raise (icon);
- }
+
+ icon_uri = nautilus_icons_controller_get_icon_uri
+ (details->controller, icon->data);
+ is_match = strcmp (uri, icon_uri) == 0;
+ g_free (icon_uri);
+
+ if (is_match)
+ return icon;
}
- set_kbd_current (container, details->kbd_current, FALSE);
+ return NULL;
}
diff --git a/libnautilus-extensions/gnome-icon-container.h b/libnautilus-extensions/gnome-icon-container.h
index 7e7921817..d5c76824f 100644
--- a/libnautilus-extensions/gnome-icon-container.h
+++ b/libnautilus-extensions/gnome-icon-container.h
@@ -88,9 +88,4 @@ GList * gnome_icon_container_get_selection (GnomeIconContainer
void gnome_icon_container_unselect_all (GnomeIconContainer *view);
void gnome_icon_container_select_all (GnomeIconContainer *view);
-void gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- int delta_x,
- int delta_y,
- gboolean raise);
-
#endif
diff --git a/libnautilus-extensions/nautilus-self-checks.c b/libnautilus-extensions/nautilus-self-checks.c
index a41df1f9d..ebf1a2bf4 100644
--- a/libnautilus-extensions/nautilus-self-checks.c
+++ b/libnautilus-extensions/nautilus-self-checks.c
@@ -30,6 +30,7 @@
#include "nautilus-self-checks.h"
#include <stdio.h>
+#include <stdlib.h>
static gboolean failed;
@@ -37,14 +38,22 @@ static const char *current_expression;
static const char *current_file_name;
static int current_line_number;
-gboolean nautilus_self_checks_failed (void)
+void nautilus_exit_if_self_checks_failed (void)
{
- return failed;
+ if (!failed)
+ return;
+
+ printf ("\n");
+
+ exit (EXIT_FAILURE);
}
static void
nautilus_report_check_failure (char *result, char *expected)
{
+ if (!failed)
+ printf ("\n");
+
printf ("FAIL: check failed in %s, line %d\n", current_file_name, current_line_number);
printf (" evaluated: %s\n", current_expression);
printf (" expected: %s\n", expected == NULL ? "NULL" : expected);
diff --git a/libnautilus-extensions/nautilus-self-checks.h b/libnautilus-extensions/nautilus-self-checks.h
index ab4b30ef3..30a40ac6a 100644
--- a/libnautilus-extensions/nautilus-self-checks.h
+++ b/libnautilus-extensions/nautilus-self-checks.h
@@ -27,17 +27,6 @@
#include <glib.h>
-gboolean nautilus_self_checks_failed (void);
-void nautilus_before_check (const char *expression,
- const char *file_name,
- int line_number);
-void nautilus_check_boolean_result (gboolean result,
- gboolean expected_value);
-void nautilus_check_integer_result (long result,
- long expected_value);
-void nautilus_check_string_result (char *result,
- const char *expected_value);
-
#define NAUTILUS_CHECK_RESULT(type, expression, expected_value) \
G_STMT_START { \
nautilus_before_check (#expression, __FILE__, __LINE__); \
@@ -51,6 +40,19 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+void nautilus_exit_if_self_checks_failed (void);
+
+void nautilus_before_check (const char *expression,
+ const char *file_name,
+ int line_number);
+
+void nautilus_check_boolean_result (gboolean result,
+ gboolean expected_value);
+void nautilus_check_integer_result (long result,
+ long expected_value);
+void nautilus_check_string_result (char *result,
+ const char *expected_value);
+
#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
void function (void);
diff --git a/libnautilus-private/gnome-icon-container-dnd.c b/libnautilus-private/gnome-icon-container-dnd.c
index 5d7eb56ca..2ad08b3ef 100644
--- a/libnautilus-private/gnome-icon-container-dnd.c
+++ b/libnautilus-private/gnome-icon-container-dnd.c
@@ -40,11 +40,12 @@
-struct _DndSelectionItem {
+typedef struct {
char *uri;
- int x, y;
-};
-typedef struct _DndSelectionItem DndSelectionItem;
+ gboolean got_icon_position;
+ int icon_x, icon_y;
+ int icon_width, icon_height;
+} DndSelectionItem;
static GtkTargetEntry drag_types [] = {
{ GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST_TYPE, 0, GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST },
@@ -61,9 +62,6 @@ static GtkTargetEntry drop_types [] = {
};
static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
-/* number of pixels of margin for shadow box */
-#define SHADOW_MARGIN 8
-
static GnomeCanvasItem *
create_selection_shadow (GnomeIconContainer *container,
GList *list)
@@ -73,9 +71,6 @@ create_selection_shadow (GnomeIconContainer *container,
GdkBitmap *stipple;
int max_x, max_y;
int min_x, min_y;
- int icon_width, icon_height;
- int cell_width;
- int x_offset;
GList *p;
if (list == NULL)
@@ -84,11 +79,6 @@ create_selection_shadow (GnomeIconContainer *container,
stipple = container->details->dnd_info->stipple;
g_return_val_if_fail (stipple != NULL, NULL);
- icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
- icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
- cell_width = GNOME_ICON_CONTAINER_CELL_WIDTH (container);
- x_offset = cell_width - icon_width - SHADOW_MARGIN;
-
canvas = GNOME_CANVAS (container);
/* Creating a big set of rectangles in the canvas can be expensive, so
@@ -115,10 +105,13 @@ create_selection_shadow (GnomeIconContainer *container,
item = p->data;
- x1 = item->x + x_offset;
- y1 = item->y;
- x2 = item->x + icon_width + x_offset;
- y2 = item->y + icon_height;
+ if (!item->got_icon_position)
+ continue;
+
+ x1 = item->icon_x;
+ y1 = item->icon_y;
+ x2 = x1 + item->icon_width;
+ y2 = y1 + item->icon_height;
if (x2 >= min_x && x1 <= max_x && y2 >= min_y && y1 <= max_y) {
GnomeCanvasItem *rect;
@@ -167,10 +160,7 @@ dnd_selection_item_new (void)
{
DndSelectionItem *new;
- new = g_new (DndSelectionItem, 1);
- new->uri = NULL;
- new->x = 0;
- new->y = 0;
+ new = g_new0 (DndSelectionItem, 1);
return new;
}
@@ -198,7 +188,10 @@ destroy_selection_list (GList *list)
/* Source-side handling of the drag. */
-/* Encode a "special/x-gnome-icon-list" selection. */
+/* Encode a "special/x-gnome-icon-list" selection.
+ Along with the URIs of the dragged files, this encodes
+ the location and size of each icon relative to the cursor.
+*/
static void
set_gnome_icon_list_selection (GnomeIconContainer *container,
GtkSelectionData *selection_data)
@@ -206,28 +199,29 @@ set_gnome_icon_list_selection (GnomeIconContainer *container,
GnomeIconContainerDetails *details;
GList *p;
GString *data;
- gdouble x_offset, y_offset;
details = container->details;
- x_offset = details->dnd_info->start_x;
- y_offset = details->dnd_info->start_y;
data = g_string_new (NULL);
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
char *uri;
char *s;
- int x, y;
+ int icon_x, icon_y, icon_width, icon_height;
icon = p->data;
if (!icon->is_selected)
continue;
- x = icon->x - x_offset - (GNOME_ICON_CONTAINER_ICON_WIDTH (container) / 2);
- y = icon->y - y_offset;
+ /* Corner of the icon relative to the cursor. */
+ icon_x = icon->x - details->dnd_info->start_x;
+ icon_y = icon->y - details->dnd_info->start_y;
+ icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
+ icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
uri = nautilus_icons_controller_get_icon_uri (details->controller, icon->data);
- s = g_strdup_printf ("%s\r%d:%d\r\n", uri, x, y);
+ s = g_strdup_printf ("%s\r%d:%d:%d:%d\r\n",
+ uri, icon_x, icon_y, icon_width, icon_height);
g_free (uri);
g_string_append (data, s);
@@ -364,9 +358,12 @@ get_gnome_icon_list_selection (GnomeIconContainer *container,
/* 2: Decode geometry information. */
- if (sscanf (p, "%d:%d%*s", &item->x, &item->y) != 2)
+ item->got_icon_position = sscanf (p, "%d:%d:%d:%d%*s",
+ &item->icon_x, &item->icon_y,
+ &item->icon_height, &item->icon_width) == 4;
+ if (!item->got_icon_position)
g_warning ("Invalid special/x-gnome-icon-list data received: "
- "invalid geometry specification.");
+ "invalid icon position specification.");
dnd_info->selection_list
= g_list_prepend (dnd_info->selection_list, item);
@@ -527,6 +524,7 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
int x, int y)
{
GnomeIconContainerDndInfo *dnd_info;
+ GList *p;
dnd_info = container->details->dnd_info;
if (dnd_info->selection_list == NULL)
@@ -551,14 +549,41 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
*/
if (context->action == GDK_ACTION_MOVE) {
double world_x, world_y;
-
+ GList *icons_to_select;
+
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
-
- gnome_icon_container_xlate_selected (container,
- world_x - dnd_info->start_x,
- world_y - dnd_info->start_y,
- TRUE);
+
+ icons_to_select = NULL;
+ for (p = dnd_info->selection_list; p != NULL; p = p->next) {
+ DndSelectionItem *item;
+ GnomeIconContainerIcon *icon;
+
+ item = p->data;
+ icon = gnome_icon_container_get_icon_by_uri
+ (container, item->uri);
+
+ if (icon == NULL) {
+ g_warning ("drag between containers not implemented yet");
+ continue;
+ }
+
+ if (item->got_icon_position) {
+ int icon_x, icon_y;
+
+ icon_x = (int) world_x + item->icon_x;
+ icon_y = (int) world_y + item->icon_y;
+
+ gnome_icon_container_move_icon
+ (container, icon, icon_x, icon_y, TRUE);
+ }
+
+ icons_to_select = g_list_prepend (icons_to_select, icon);
+ }
+
+ gnome_icon_container_select_list_unselect_others (container, icons_to_select);
+
+ g_list_free (icons_to_select);
}
destroy_selection_list (dnd_info->selection_list);
@@ -627,6 +652,12 @@ drag_leave_cb (GtkWidget *widget,
guint32 time,
gpointer data)
{
+ GnomeIconContainerDndInfo *dnd_info;
+
+ dnd_info = GNOME_ICON_CONTAINER (widget)->details->dnd_info;
+
+ if (dnd_info->shadow != NULL)
+ gnome_canvas_item_hide (dnd_info->shadow);
}
void
@@ -735,8 +766,8 @@ gnome_icon_container_dnd_begin_drag (GnomeIconContainer *container,
pixbuf_args[0].name = "NautilusIconsViewIconItem::pixbuf";
gtk_object_getv (GTK_OBJECT (pixbuf_item), 1, pixbuf_args);
temp_pixbuf = (GdkPixbuf *) GTK_VALUE_OBJECT (pixbuf_args[0]);
- gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
-
+ gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
+
/* set the pixmap and mask for dragging */
gtk_drag_set_icon_pixmap (context, gtk_widget_get_colormap (GTK_WIDGET (container)),
pixmap_for_dragged_file, mask_for_dragged_file,
diff --git a/libnautilus-private/gnome-icon-container-private.h b/libnautilus-private/gnome-icon-container-private.h
index a60dee6a2..4ad49aa42 100644
--- a/libnautilus-private/gnome-icon-container-private.h
+++ b/libnautilus-private/gnome-icon-container-private.h
@@ -149,9 +149,6 @@ struct _GnomeIconContainerDetails {
/* Whether we are actually performing a dragging action. */
gboolean doing_drag;
- /* Drag offset. */
- int drag_x_offset, drag_y_offset;
-
/* Idle ID. */
guint idle_id;
@@ -181,4 +178,12 @@ struct _GnomeIconContainerDetails {
#define GNOME_ICON_CONTAINER_ICON_WIDTH(container) 48
#define GNOME_ICON_CONTAINER_ICON_HEIGHT(container) 48
+GnomeIconContainerIcon *gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri);
+void gnome_icon_container_move_icon (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon,
+ int x, int y, gboolean raise);
+void gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons);
+
#endif /* GNOME_ICON_CONTAINER_PRIVATE_H */
diff --git a/libnautilus-private/gnome-icon-container.c b/libnautilus-private/gnome-icon-container.c
index c48fa7ac4..075e0ccb9 100644
--- a/libnautilus-private/gnome-icon-container.c
+++ b/libnautilus-private/gnome-icon-container.c
@@ -45,7 +45,8 @@
/* Timeout for making the icon currently selected for keyboard operation
visible. FIXME: This *must* be higher than the double-click time in GDK,
- but there is no way to access its value from outside. */
+ but there is no way to access its value from outside.
+*/
#define KBD_ICON_VISIBILITY_TIMEOUT 300
/* Timeout for selecting an icon in "linger-select" mode (i.e. by just placing the
@@ -175,29 +176,24 @@ icon_show (GnomeIconContainerIcon *icon)
}
static void
-icon_select (GnomeIconContainerIcon *icon,
- gboolean sel)
+icon_toggle_selected (GnomeIconContainerIcon *icon)
{
-
- if (sel == icon->is_selected)
- return;
-
- icon->is_selected = sel;
+ icon->is_selected = !icon->is_selected;
gnome_canvas_item_set (GNOME_CANVAS_ITEM (icon->item),
- "selected", (gboolean) sel,
+ "selected", (gboolean) icon->is_selected,
NULL);
}
+/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-icon_toggle_selection (GnomeIconContainerIcon *icon)
+icon_select (GnomeIconContainerIcon *icon,
+ gboolean select)
{
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- return TRUE;
- } else {
- icon_select (icon, TRUE);
+ if (select == icon->is_selected)
return FALSE;
- }
+
+ icon_toggle_selected (icon);
+ return TRUE;
}
static gboolean
@@ -984,37 +980,9 @@ button_event_modifies_selection (GdkEventButton *event)
return event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK);
}
-
-/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-select_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon,
- gboolean sel)
-{
- GnomeIconContainerDetails *details;
- gboolean was_selected;
-
- details = container->details;
-
- was_selected = icon->is_selected;
- icon_select (icon, sel);
-
- if ((! was_selected && sel) || (was_selected && ! sel))
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-toggle_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon)
-{
- icon_toggle_selection (icon);
-}
-
-static gboolean
-unselect_all_but_one (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon_to_avoid)
+select_one_unselect_others (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon_to_select)
{
GnomeIconContainerDetails *details;
GList *p;
@@ -1022,31 +990,28 @@ unselect_all_but_one (GnomeIconContainer *container,
details = container->details;
selection_changed = FALSE;
-
+
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (icon != icon_to_avoid && icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
+ selection_changed |= icon_select (icon, icon == icon_to_select);
}
-
+
return selection_changed;
}
static gboolean
unselect_all (GnomeIconContainer *container)
{
- return unselect_all_but_one (container, NULL);
+ return select_one_unselect_others (container, NULL);
}
/* FIXME: This could be optimized a bit. */
-static void
-move_icon (GnomeIconContainer *container,
+void
+gnome_icon_container_move_icon (GnomeIconContainer *container,
GnomeIconContainerIcon *icon,
- gint x, gint y)
+ int x, int y, gboolean raise)
{
GnomeIconContainerDetails *details;
gint old_x, old_y;
@@ -1088,6 +1053,12 @@ move_icon (GnomeIconContainer *container,
icon_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1);
icon_position (icon, container, x, y);
+ if (raise)
+ icon_raise (icon);
+
+ /* Update the keyboard selection indicator. */
+ if (details->kbd_current == icon)
+ set_kbd_current (container, icon, FALSE);
gtk_signal_emit (GTK_OBJECT (container), signals[ICON_MOVED],
icon->data, x, y);
@@ -1123,31 +1094,12 @@ rubberband_select_in_cell (GList *cell,
prev_x1, prev_y1,
prev_x2, prev_y2);
- if (in_curr_region && ! in_prev_region) {
- if (icon->was_selected_before_rubberband) {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- } else {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- }
- } else if (in_prev_region && ! in_curr_region) {
- if (icon->was_selected_before_rubberband) {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- } else {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- }
- }
+ if (in_curr_region && ! in_prev_region)
+ selection_changed |= icon_select (icon,
+ !icon->was_selected_before_rubberband);
+ else if (in_prev_region && ! in_curr_region)
+ selection_changed |= icon_select (icon,
+ icon->was_selected_before_rubberband);
}
return selection_changed;
@@ -1374,7 +1326,7 @@ kbd_move_to (GnomeIconContainer *container,
gboolean selection_changed;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -1661,7 +1613,7 @@ kbd_space (GnomeIconContainer *container,
GdkEventKey *event)
{
if (container->details->kbd_current != NULL) {
- if (select_icon (container, container->details->kbd_current, TRUE))
+ if (icon_select (container->details->kbd_current, TRUE))
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -1825,8 +1777,8 @@ button_release_event (GtkWidget *widget,
gboolean selection_changed;
selection_changed
- = unselect_all_but_one (container,
- details->drag_icon);
+ = select_one_unselect_others (container,
+ details->drag_icon);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -2104,7 +2056,7 @@ linger_select_timeout_cb (gpointer data)
icon = details->linger_selection_mode_icon;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
set_kbd_current (container, icon, FALSE);
make_icon_visible (container, icon);
@@ -2132,7 +2084,6 @@ handle_icon_button_press (GnomeIconContainer *container,
GdkEventButton *event)
{
GnomeIconContainerDetails *details;
- gdouble world_x, world_y;
details = container->details;
@@ -2154,12 +2105,12 @@ handle_icon_button_press (GnomeIconContainer *container,
return FALSE;
if (button_event_modifies_selection (event)) {
- toggle_icon (container, icon);
+ icon_toggle_selected (icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
} else if (! icon->is_selected) {
unselect_all (container);
- select_icon (container, icon, TRUE);
+ icon_select (icon, TRUE);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -2185,11 +2136,6 @@ handle_icon_button_press (GnomeIconContainer *container,
details->drag_x = event->x;
details->drag_y = event->y;
- gnome_canvas_window_to_world (GNOME_CANVAS (container), event->x, event->y,
- &world_x, &world_y);
- details->drag_x_offset = (gint) world_x - icon->x;
- details->drag_y_offset = (gint) world_y - icon->y;
-
return TRUE;
}
@@ -2689,28 +2635,17 @@ gnome_icon_container_get_selection (GnomeIconContainer *container)
void
gnome_icon_container_select_all (GnomeIconContainer *container)
{
- GnomeIconContainerDetails *details;
- GnomeIconContainerIconGrid *grid;
- GList **p, *q;
- guint i, j;
gboolean selection_changed;
+ GList *p;
- g_return_if_fail (container != NULL);
-
- details = container->details;
- grid = details->grid;
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
selection_changed = FALSE;
- p = grid->elems;
- for (i = 0; i < grid->height; i++) {
- for (j = 0; j < grid->width; j++) {
- for (q = p[j]; q != NULL; q =q->next) {
- if (select_icon (container, q->data, TRUE))
- selection_changed = TRUE;
- }
- }
+ for (p = container->details->icons; p != NULL; p = p->next) {
+ GnomeIconContainerIcon *icon;
- p += grid->alloc_width;
+ icon = p->data;
+ selection_changed |= icon_select (icon, TRUE);
}
if (selection_changed)
@@ -2719,29 +2654,32 @@ gnome_icon_container_select_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_unselect_all:
+ * gnome_icon_container_select_list_unselect_others:
* @container: An icon container widget.
+ * @list: A list of GnomeContainerIcons.
*
- * Deselect all the icons in @container.
+ * Select only the icons in the list, deselect all others.
**/
void
-gnome_icon_container_unselect_all (GnomeIconContainer *container)
+gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons)
{
- GnomeIconContainerDetails *details;
gboolean selection_changed;
GList *p;
- g_return_if_fail (container != NULL);
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
- details = container->details;
+ /* To avoid an N^2 algorithm, we could put the icons into a hash
+ table, but this should be OK for now.
+ */
selection_changed = FALSE;
- for (p = details->icons; p != NULL; p = p->next) {
+ for (p = container->details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (select_icon (container, icon, FALSE))
- selection_changed = TRUE;
+ selection_changed |= icon_select
+ (icon, g_list_find (icons, icon) != NULL);
}
if (selection_changed)
@@ -2750,43 +2688,56 @@ gnome_icon_container_unselect_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_xlate_selected:
+ * gnome_icon_container_unselect_all:
* @container: An icon container widget.
- * @amount_x: Amount of translation on the X axis.
- * @amount_y: Amount of translation on the Y axis.
- * @raise: Whether icons should be raised during this operation.
*
- * Translate all the currently selected items in @container by @amount_x
- * horizontally and @amount_y vertically. Positive values move to the
- * right/bottom, negative values to the left/top.
+ * Deselect all the icons in @container.
**/
void
-gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- gint amount_x,
- gint amount_y,
- gboolean raise)
+gnome_icon_container_unselect_all (GnomeIconContainer *container)
+{
+ if (unselect_all (container))
+ gtk_signal_emit (GTK_OBJECT (container),
+ signals[SELECTION_CHANGED]);
+}
+
+/**
+ * gnome_icon_container_get_icon_by_uri:
+ * @container: An icon container widget.
+ * @uri: The uri of an icon to find.
+ *
+ * Locate an icon, given the URI. The URI must match exactly.
+ * Later we may have to have some way of figuring out if the
+ * URI specifies the same object that does not require an exact match.
+ **/
+GnomeIconContainerIcon *
+gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri)
{
GnomeIconContainerDetails *details;
GList *p;
- g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
-
- if (amount_x == 0 && amount_y == 0)
- return;
+ /* Eventually, we must avoid searching the entire icon list,
+ but it's OK for now.
+ */
details = container->details;
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
+ char *icon_uri;
+ gboolean is_match;
icon = p->data;
- if (icon->is_selected) {
- move_icon (container, icon,
- icon->x + amount_x, icon->y + amount_y);
- if (raise)
- icon_raise (icon);
- }
+
+ icon_uri = nautilus_icons_controller_get_icon_uri
+ (details->controller, icon->data);
+ is_match = strcmp (uri, icon_uri) == 0;
+ g_free (icon_uri);
+
+ if (is_match)
+ return icon;
}
- set_kbd_current (container, details->kbd_current, FALSE);
+ return NULL;
}
diff --git a/libnautilus-private/gnome-icon-container.h b/libnautilus-private/gnome-icon-container.h
index 7e7921817..d5c76824f 100644
--- a/libnautilus-private/gnome-icon-container.h
+++ b/libnautilus-private/gnome-icon-container.h
@@ -88,9 +88,4 @@ GList * gnome_icon_container_get_selection (GnomeIconContainer
void gnome_icon_container_unselect_all (GnomeIconContainer *view);
void gnome_icon_container_select_all (GnomeIconContainer *view);
-void gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- int delta_x,
- int delta_y,
- gboolean raise);
-
#endif
diff --git a/libnautilus-private/nautilus-self-checks.c b/libnautilus-private/nautilus-self-checks.c
index a41df1f9d..ebf1a2bf4 100644
--- a/libnautilus-private/nautilus-self-checks.c
+++ b/libnautilus-private/nautilus-self-checks.c
@@ -30,6 +30,7 @@
#include "nautilus-self-checks.h"
#include <stdio.h>
+#include <stdlib.h>
static gboolean failed;
@@ -37,14 +38,22 @@ static const char *current_expression;
static const char *current_file_name;
static int current_line_number;
-gboolean nautilus_self_checks_failed (void)
+void nautilus_exit_if_self_checks_failed (void)
{
- return failed;
+ if (!failed)
+ return;
+
+ printf ("\n");
+
+ exit (EXIT_FAILURE);
}
static void
nautilus_report_check_failure (char *result, char *expected)
{
+ if (!failed)
+ printf ("\n");
+
printf ("FAIL: check failed in %s, line %d\n", current_file_name, current_line_number);
printf (" evaluated: %s\n", current_expression);
printf (" expected: %s\n", expected == NULL ? "NULL" : expected);
diff --git a/libnautilus-private/nautilus-self-checks.h b/libnautilus-private/nautilus-self-checks.h
index ab4b30ef3..30a40ac6a 100644
--- a/libnautilus-private/nautilus-self-checks.h
+++ b/libnautilus-private/nautilus-self-checks.h
@@ -27,17 +27,6 @@
#include <glib.h>
-gboolean nautilus_self_checks_failed (void);
-void nautilus_before_check (const char *expression,
- const char *file_name,
- int line_number);
-void nautilus_check_boolean_result (gboolean result,
- gboolean expected_value);
-void nautilus_check_integer_result (long result,
- long expected_value);
-void nautilus_check_string_result (char *result,
- const char *expected_value);
-
#define NAUTILUS_CHECK_RESULT(type, expression, expected_value) \
G_STMT_START { \
nautilus_before_check (#expression, __FILE__, __LINE__); \
@@ -51,6 +40,19 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+void nautilus_exit_if_self_checks_failed (void);
+
+void nautilus_before_check (const char *expression,
+ const char *file_name,
+ int line_number);
+
+void nautilus_check_boolean_result (gboolean result,
+ gboolean expected_value);
+void nautilus_check_integer_result (long result,
+ long expected_value);
+void nautilus_check_string_result (char *result,
+ const char *expected_value);
+
#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
void function (void);
diff --git a/libnautilus/gnome-icon-container-dnd.c b/libnautilus/gnome-icon-container-dnd.c
index 5d7eb56ca..2ad08b3ef 100644
--- a/libnautilus/gnome-icon-container-dnd.c
+++ b/libnautilus/gnome-icon-container-dnd.c
@@ -40,11 +40,12 @@
-struct _DndSelectionItem {
+typedef struct {
char *uri;
- int x, y;
-};
-typedef struct _DndSelectionItem DndSelectionItem;
+ gboolean got_icon_position;
+ int icon_x, icon_y;
+ int icon_width, icon_height;
+} DndSelectionItem;
static GtkTargetEntry drag_types [] = {
{ GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST_TYPE, 0, GNOME_ICON_CONTAINER_DND_GNOME_ICON_LIST },
@@ -61,9 +62,6 @@ static GtkTargetEntry drop_types [] = {
};
static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
-/* number of pixels of margin for shadow box */
-#define SHADOW_MARGIN 8
-
static GnomeCanvasItem *
create_selection_shadow (GnomeIconContainer *container,
GList *list)
@@ -73,9 +71,6 @@ create_selection_shadow (GnomeIconContainer *container,
GdkBitmap *stipple;
int max_x, max_y;
int min_x, min_y;
- int icon_width, icon_height;
- int cell_width;
- int x_offset;
GList *p;
if (list == NULL)
@@ -84,11 +79,6 @@ create_selection_shadow (GnomeIconContainer *container,
stipple = container->details->dnd_info->stipple;
g_return_val_if_fail (stipple != NULL, NULL);
- icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
- icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
- cell_width = GNOME_ICON_CONTAINER_CELL_WIDTH (container);
- x_offset = cell_width - icon_width - SHADOW_MARGIN;
-
canvas = GNOME_CANVAS (container);
/* Creating a big set of rectangles in the canvas can be expensive, so
@@ -115,10 +105,13 @@ create_selection_shadow (GnomeIconContainer *container,
item = p->data;
- x1 = item->x + x_offset;
- y1 = item->y;
- x2 = item->x + icon_width + x_offset;
- y2 = item->y + icon_height;
+ if (!item->got_icon_position)
+ continue;
+
+ x1 = item->icon_x;
+ y1 = item->icon_y;
+ x2 = x1 + item->icon_width;
+ y2 = y1 + item->icon_height;
if (x2 >= min_x && x1 <= max_x && y2 >= min_y && y1 <= max_y) {
GnomeCanvasItem *rect;
@@ -167,10 +160,7 @@ dnd_selection_item_new (void)
{
DndSelectionItem *new;
- new = g_new (DndSelectionItem, 1);
- new->uri = NULL;
- new->x = 0;
- new->y = 0;
+ new = g_new0 (DndSelectionItem, 1);
return new;
}
@@ -198,7 +188,10 @@ destroy_selection_list (GList *list)
/* Source-side handling of the drag. */
-/* Encode a "special/x-gnome-icon-list" selection. */
+/* Encode a "special/x-gnome-icon-list" selection.
+ Along with the URIs of the dragged files, this encodes
+ the location and size of each icon relative to the cursor.
+*/
static void
set_gnome_icon_list_selection (GnomeIconContainer *container,
GtkSelectionData *selection_data)
@@ -206,28 +199,29 @@ set_gnome_icon_list_selection (GnomeIconContainer *container,
GnomeIconContainerDetails *details;
GList *p;
GString *data;
- gdouble x_offset, y_offset;
details = container->details;
- x_offset = details->dnd_info->start_x;
- y_offset = details->dnd_info->start_y;
data = g_string_new (NULL);
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
char *uri;
char *s;
- int x, y;
+ int icon_x, icon_y, icon_width, icon_height;
icon = p->data;
if (!icon->is_selected)
continue;
- x = icon->x - x_offset - (GNOME_ICON_CONTAINER_ICON_WIDTH (container) / 2);
- y = icon->y - y_offset;
+ /* Corner of the icon relative to the cursor. */
+ icon_x = icon->x - details->dnd_info->start_x;
+ icon_y = icon->y - details->dnd_info->start_y;
+ icon_width = GNOME_ICON_CONTAINER_ICON_WIDTH (container);
+ icon_height = GNOME_ICON_CONTAINER_ICON_HEIGHT (container);
uri = nautilus_icons_controller_get_icon_uri (details->controller, icon->data);
- s = g_strdup_printf ("%s\r%d:%d\r\n", uri, x, y);
+ s = g_strdup_printf ("%s\r%d:%d:%d:%d\r\n",
+ uri, icon_x, icon_y, icon_width, icon_height);
g_free (uri);
g_string_append (data, s);
@@ -364,9 +358,12 @@ get_gnome_icon_list_selection (GnomeIconContainer *container,
/* 2: Decode geometry information. */
- if (sscanf (p, "%d:%d%*s", &item->x, &item->y) != 2)
+ item->got_icon_position = sscanf (p, "%d:%d:%d:%d%*s",
+ &item->icon_x, &item->icon_y,
+ &item->icon_height, &item->icon_width) == 4;
+ if (!item->got_icon_position)
g_warning ("Invalid special/x-gnome-icon-list data received: "
- "invalid geometry specification.");
+ "invalid icon position specification.");
dnd_info->selection_list
= g_list_prepend (dnd_info->selection_list, item);
@@ -527,6 +524,7 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
int x, int y)
{
GnomeIconContainerDndInfo *dnd_info;
+ GList *p;
dnd_info = container->details->dnd_info;
if (dnd_info->selection_list == NULL)
@@ -551,14 +549,41 @@ gnome_icon_container_receive_dropped_icons (GnomeIconContainer *container,
*/
if (context->action == GDK_ACTION_MOVE) {
double world_x, world_y;
-
+ GList *icons_to_select;
+
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
-
- gnome_icon_container_xlate_selected (container,
- world_x - dnd_info->start_x,
- world_y - dnd_info->start_y,
- TRUE);
+
+ icons_to_select = NULL;
+ for (p = dnd_info->selection_list; p != NULL; p = p->next) {
+ DndSelectionItem *item;
+ GnomeIconContainerIcon *icon;
+
+ item = p->data;
+ icon = gnome_icon_container_get_icon_by_uri
+ (container, item->uri);
+
+ if (icon == NULL) {
+ g_warning ("drag between containers not implemented yet");
+ continue;
+ }
+
+ if (item->got_icon_position) {
+ int icon_x, icon_y;
+
+ icon_x = (int) world_x + item->icon_x;
+ icon_y = (int) world_y + item->icon_y;
+
+ gnome_icon_container_move_icon
+ (container, icon, icon_x, icon_y, TRUE);
+ }
+
+ icons_to_select = g_list_prepend (icons_to_select, icon);
+ }
+
+ gnome_icon_container_select_list_unselect_others (container, icons_to_select);
+
+ g_list_free (icons_to_select);
}
destroy_selection_list (dnd_info->selection_list);
@@ -627,6 +652,12 @@ drag_leave_cb (GtkWidget *widget,
guint32 time,
gpointer data)
{
+ GnomeIconContainerDndInfo *dnd_info;
+
+ dnd_info = GNOME_ICON_CONTAINER (widget)->details->dnd_info;
+
+ if (dnd_info->shadow != NULL)
+ gnome_canvas_item_hide (dnd_info->shadow);
}
void
@@ -735,8 +766,8 @@ gnome_icon_container_dnd_begin_drag (GnomeIconContainer *container,
pixbuf_args[0].name = "NautilusIconsViewIconItem::pixbuf";
gtk_object_getv (GTK_OBJECT (pixbuf_item), 1, pixbuf_args);
temp_pixbuf = (GdkPixbuf *) GTK_VALUE_OBJECT (pixbuf_args[0]);
- gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
-
+ gdk_pixbuf_render_pixmap_and_mask (temp_pixbuf, &pixmap_for_dragged_file, &mask_for_dragged_file, 128);
+
/* set the pixmap and mask for dragging */
gtk_drag_set_icon_pixmap (context, gtk_widget_get_colormap (GTK_WIDGET (container)),
pixmap_for_dragged_file, mask_for_dragged_file,
diff --git a/libnautilus/gnome-icon-container-private.h b/libnautilus/gnome-icon-container-private.h
index a60dee6a2..4ad49aa42 100644
--- a/libnautilus/gnome-icon-container-private.h
+++ b/libnautilus/gnome-icon-container-private.h
@@ -149,9 +149,6 @@ struct _GnomeIconContainerDetails {
/* Whether we are actually performing a dragging action. */
gboolean doing_drag;
- /* Drag offset. */
- int drag_x_offset, drag_y_offset;
-
/* Idle ID. */
guint idle_id;
@@ -181,4 +178,12 @@ struct _GnomeIconContainerDetails {
#define GNOME_ICON_CONTAINER_ICON_WIDTH(container) 48
#define GNOME_ICON_CONTAINER_ICON_HEIGHT(container) 48
+GnomeIconContainerIcon *gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri);
+void gnome_icon_container_move_icon (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon,
+ int x, int y, gboolean raise);
+void gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons);
+
#endif /* GNOME_ICON_CONTAINER_PRIVATE_H */
diff --git a/libnautilus/gnome-icon-container.c b/libnautilus/gnome-icon-container.c
index c48fa7ac4..075e0ccb9 100644
--- a/libnautilus/gnome-icon-container.c
+++ b/libnautilus/gnome-icon-container.c
@@ -45,7 +45,8 @@
/* Timeout for making the icon currently selected for keyboard operation
visible. FIXME: This *must* be higher than the double-click time in GDK,
- but there is no way to access its value from outside. */
+ but there is no way to access its value from outside.
+*/
#define KBD_ICON_VISIBILITY_TIMEOUT 300
/* Timeout for selecting an icon in "linger-select" mode (i.e. by just placing the
@@ -175,29 +176,24 @@ icon_show (GnomeIconContainerIcon *icon)
}
static void
-icon_select (GnomeIconContainerIcon *icon,
- gboolean sel)
+icon_toggle_selected (GnomeIconContainerIcon *icon)
{
-
- if (sel == icon->is_selected)
- return;
-
- icon->is_selected = sel;
+ icon->is_selected = !icon->is_selected;
gnome_canvas_item_set (GNOME_CANVAS_ITEM (icon->item),
- "selected", (gboolean) sel,
+ "selected", (gboolean) icon->is_selected,
NULL);
}
+/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-icon_toggle_selection (GnomeIconContainerIcon *icon)
+icon_select (GnomeIconContainerIcon *icon,
+ gboolean select)
{
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- return TRUE;
- } else {
- icon_select (icon, TRUE);
+ if (select == icon->is_selected)
return FALSE;
- }
+
+ icon_toggle_selected (icon);
+ return TRUE;
}
static gboolean
@@ -984,37 +980,9 @@ button_event_modifies_selection (GdkEventButton *event)
return event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK);
}
-
-/* Select an icon. Return TRUE if selection has changed. */
static gboolean
-select_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon,
- gboolean sel)
-{
- GnomeIconContainerDetails *details;
- gboolean was_selected;
-
- details = container->details;
-
- was_selected = icon->is_selected;
- icon_select (icon, sel);
-
- if ((! was_selected && sel) || (was_selected && ! sel))
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-toggle_icon (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon)
-{
- icon_toggle_selection (icon);
-}
-
-static gboolean
-unselect_all_but_one (GnomeIconContainer *container,
- GnomeIconContainerIcon *icon_to_avoid)
+select_one_unselect_others (GnomeIconContainer *container,
+ GnomeIconContainerIcon *icon_to_select)
{
GnomeIconContainerDetails *details;
GList *p;
@@ -1022,31 +990,28 @@ unselect_all_but_one (GnomeIconContainer *container,
details = container->details;
selection_changed = FALSE;
-
+
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (icon != icon_to_avoid && icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
+ selection_changed |= icon_select (icon, icon == icon_to_select);
}
-
+
return selection_changed;
}
static gboolean
unselect_all (GnomeIconContainer *container)
{
- return unselect_all_but_one (container, NULL);
+ return select_one_unselect_others (container, NULL);
}
/* FIXME: This could be optimized a bit. */
-static void
-move_icon (GnomeIconContainer *container,
+void
+gnome_icon_container_move_icon (GnomeIconContainer *container,
GnomeIconContainerIcon *icon,
- gint x, gint y)
+ int x, int y, gboolean raise)
{
GnomeIconContainerDetails *details;
gint old_x, old_y;
@@ -1088,6 +1053,12 @@ move_icon (GnomeIconContainer *container,
icon_grid_add (details->grid, icon, new_grid_x + 1, new_grid_y + 1);
icon_position (icon, container, x, y);
+ if (raise)
+ icon_raise (icon);
+
+ /* Update the keyboard selection indicator. */
+ if (details->kbd_current == icon)
+ set_kbd_current (container, icon, FALSE);
gtk_signal_emit (GTK_OBJECT (container), signals[ICON_MOVED],
icon->data, x, y);
@@ -1123,31 +1094,12 @@ rubberband_select_in_cell (GList *cell,
prev_x1, prev_y1,
prev_x2, prev_y2);
- if (in_curr_region && ! in_prev_region) {
- if (icon->was_selected_before_rubberband) {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- } else {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- }
- } else if (in_prev_region && ! in_curr_region) {
- if (icon->was_selected_before_rubberband) {
- if (! icon->is_selected) {
- icon_select (icon, TRUE);
- selection_changed = TRUE;
- }
- } else {
- if (icon->is_selected) {
- icon_select (icon, FALSE);
- selection_changed = TRUE;
- }
- }
- }
+ if (in_curr_region && ! in_prev_region)
+ selection_changed |= icon_select (icon,
+ !icon->was_selected_before_rubberband);
+ else if (in_prev_region && ! in_curr_region)
+ selection_changed |= icon_select (icon,
+ icon->was_selected_before_rubberband);
}
return selection_changed;
@@ -1374,7 +1326,7 @@ kbd_move_to (GnomeIconContainer *container,
gboolean selection_changed;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -1661,7 +1613,7 @@ kbd_space (GnomeIconContainer *container,
GdkEventKey *event)
{
if (container->details->kbd_current != NULL) {
- if (select_icon (container, container->details->kbd_current, TRUE))
+ if (icon_select (container->details->kbd_current, TRUE))
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -1825,8 +1777,8 @@ button_release_event (GtkWidget *widget,
gboolean selection_changed;
selection_changed
- = unselect_all_but_one (container,
- details->drag_icon);
+ = select_one_unselect_others (container,
+ details->drag_icon);
if (selection_changed)
gtk_signal_emit (GTK_OBJECT (container),
@@ -2104,7 +2056,7 @@ linger_select_timeout_cb (gpointer data)
icon = details->linger_selection_mode_icon;
selection_changed = unselect_all (container);
- selection_changed |= select_icon (container, icon, TRUE);
+ selection_changed |= icon_select (icon, TRUE);
set_kbd_current (container, icon, FALSE);
make_icon_visible (container, icon);
@@ -2132,7 +2084,6 @@ handle_icon_button_press (GnomeIconContainer *container,
GdkEventButton *event)
{
GnomeIconContainerDetails *details;
- gdouble world_x, world_y;
details = container->details;
@@ -2154,12 +2105,12 @@ handle_icon_button_press (GnomeIconContainer *container,
return FALSE;
if (button_event_modifies_selection (event)) {
- toggle_icon (container, icon);
+ icon_toggle_selected (icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
} else if (! icon->is_selected) {
unselect_all (container);
- select_icon (container, icon, TRUE);
+ icon_select (icon, TRUE);
gtk_signal_emit (GTK_OBJECT (container),
signals[SELECTION_CHANGED]);
}
@@ -2185,11 +2136,6 @@ handle_icon_button_press (GnomeIconContainer *container,
details->drag_x = event->x;
details->drag_y = event->y;
- gnome_canvas_window_to_world (GNOME_CANVAS (container), event->x, event->y,
- &world_x, &world_y);
- details->drag_x_offset = (gint) world_x - icon->x;
- details->drag_y_offset = (gint) world_y - icon->y;
-
return TRUE;
}
@@ -2689,28 +2635,17 @@ gnome_icon_container_get_selection (GnomeIconContainer *container)
void
gnome_icon_container_select_all (GnomeIconContainer *container)
{
- GnomeIconContainerDetails *details;
- GnomeIconContainerIconGrid *grid;
- GList **p, *q;
- guint i, j;
gboolean selection_changed;
+ GList *p;
- g_return_if_fail (container != NULL);
-
- details = container->details;
- grid = details->grid;
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
selection_changed = FALSE;
- p = grid->elems;
- for (i = 0; i < grid->height; i++) {
- for (j = 0; j < grid->width; j++) {
- for (q = p[j]; q != NULL; q =q->next) {
- if (select_icon (container, q->data, TRUE))
- selection_changed = TRUE;
- }
- }
+ for (p = container->details->icons; p != NULL; p = p->next) {
+ GnomeIconContainerIcon *icon;
- p += grid->alloc_width;
+ icon = p->data;
+ selection_changed |= icon_select (icon, TRUE);
}
if (selection_changed)
@@ -2719,29 +2654,32 @@ gnome_icon_container_select_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_unselect_all:
+ * gnome_icon_container_select_list_unselect_others:
* @container: An icon container widget.
+ * @list: A list of GnomeContainerIcons.
*
- * Deselect all the icons in @container.
+ * Select only the icons in the list, deselect all others.
**/
void
-gnome_icon_container_unselect_all (GnomeIconContainer *container)
+gnome_icon_container_select_list_unselect_others (GnomeIconContainer *container,
+ GList *icons)
{
- GnomeIconContainerDetails *details;
gboolean selection_changed;
GList *p;
- g_return_if_fail (container != NULL);
+ g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
- details = container->details;
+ /* To avoid an N^2 algorithm, we could put the icons into a hash
+ table, but this should be OK for now.
+ */
selection_changed = FALSE;
- for (p = details->icons; p != NULL; p = p->next) {
+ for (p = container->details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
icon = p->data;
- if (select_icon (container, icon, FALSE))
- selection_changed = TRUE;
+ selection_changed |= icon_select
+ (icon, g_list_find (icons, icon) != NULL);
}
if (selection_changed)
@@ -2750,43 +2688,56 @@ gnome_icon_container_unselect_all (GnomeIconContainer *container)
}
/**
- * gnome_icon_container_xlate_selected:
+ * gnome_icon_container_unselect_all:
* @container: An icon container widget.
- * @amount_x: Amount of translation on the X axis.
- * @amount_y: Amount of translation on the Y axis.
- * @raise: Whether icons should be raised during this operation.
*
- * Translate all the currently selected items in @container by @amount_x
- * horizontally and @amount_y vertically. Positive values move to the
- * right/bottom, negative values to the left/top.
+ * Deselect all the icons in @container.
**/
void
-gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- gint amount_x,
- gint amount_y,
- gboolean raise)
+gnome_icon_container_unselect_all (GnomeIconContainer *container)
+{
+ if (unselect_all (container))
+ gtk_signal_emit (GTK_OBJECT (container),
+ signals[SELECTION_CHANGED]);
+}
+
+/**
+ * gnome_icon_container_get_icon_by_uri:
+ * @container: An icon container widget.
+ * @uri: The uri of an icon to find.
+ *
+ * Locate an icon, given the URI. The URI must match exactly.
+ * Later we may have to have some way of figuring out if the
+ * URI specifies the same object that does not require an exact match.
+ **/
+GnomeIconContainerIcon *
+gnome_icon_container_get_icon_by_uri (GnomeIconContainer *container,
+ const char *uri)
{
GnomeIconContainerDetails *details;
GList *p;
- g_return_if_fail (GNOME_IS_ICON_CONTAINER (container));
-
- if (amount_x == 0 && amount_y == 0)
- return;
+ /* Eventually, we must avoid searching the entire icon list,
+ but it's OK for now.
+ */
details = container->details;
for (p = details->icons; p != NULL; p = p->next) {
GnomeIconContainerIcon *icon;
+ char *icon_uri;
+ gboolean is_match;
icon = p->data;
- if (icon->is_selected) {
- move_icon (container, icon,
- icon->x + amount_x, icon->y + amount_y);
- if (raise)
- icon_raise (icon);
- }
+
+ icon_uri = nautilus_icons_controller_get_icon_uri
+ (details->controller, icon->data);
+ is_match = strcmp (uri, icon_uri) == 0;
+ g_free (icon_uri);
+
+ if (is_match)
+ return icon;
}
- set_kbd_current (container, details->kbd_current, FALSE);
+ return NULL;
}
diff --git a/libnautilus/gnome-icon-container.h b/libnautilus/gnome-icon-container.h
index 7e7921817..d5c76824f 100644
--- a/libnautilus/gnome-icon-container.h
+++ b/libnautilus/gnome-icon-container.h
@@ -88,9 +88,4 @@ GList * gnome_icon_container_get_selection (GnomeIconContainer
void gnome_icon_container_unselect_all (GnomeIconContainer *view);
void gnome_icon_container_select_all (GnomeIconContainer *view);
-void gnome_icon_container_xlate_selected (GnomeIconContainer *container,
- int delta_x,
- int delta_y,
- gboolean raise);
-
#endif
diff --git a/libnautilus/nautilus-self-checks.c b/libnautilus/nautilus-self-checks.c
index a41df1f9d..ebf1a2bf4 100644
--- a/libnautilus/nautilus-self-checks.c
+++ b/libnautilus/nautilus-self-checks.c
@@ -30,6 +30,7 @@
#include "nautilus-self-checks.h"
#include <stdio.h>
+#include <stdlib.h>
static gboolean failed;
@@ -37,14 +38,22 @@ static const char *current_expression;
static const char *current_file_name;
static int current_line_number;
-gboolean nautilus_self_checks_failed (void)
+void nautilus_exit_if_self_checks_failed (void)
{
- return failed;
+ if (!failed)
+ return;
+
+ printf ("\n");
+
+ exit (EXIT_FAILURE);
}
static void
nautilus_report_check_failure (char *result, char *expected)
{
+ if (!failed)
+ printf ("\n");
+
printf ("FAIL: check failed in %s, line %d\n", current_file_name, current_line_number);
printf (" evaluated: %s\n", current_expression);
printf (" expected: %s\n", expected == NULL ? "NULL" : expected);
diff --git a/libnautilus/nautilus-self-checks.h b/libnautilus/nautilus-self-checks.h
index ab4b30ef3..30a40ac6a 100644
--- a/libnautilus/nautilus-self-checks.h
+++ b/libnautilus/nautilus-self-checks.h
@@ -27,17 +27,6 @@
#include <glib.h>
-gboolean nautilus_self_checks_failed (void);
-void nautilus_before_check (const char *expression,
- const char *file_name,
- int line_number);
-void nautilus_check_boolean_result (gboolean result,
- gboolean expected_value);
-void nautilus_check_integer_result (long result,
- long expected_value);
-void nautilus_check_string_result (char *result,
- const char *expected_value);
-
#define NAUTILUS_CHECK_RESULT(type, expression, expected_value) \
G_STMT_START { \
nautilus_before_check (#expression, __FILE__, __LINE__); \
@@ -51,6 +40,19 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+void nautilus_exit_if_self_checks_failed (void);
+
+void nautilus_before_check (const char *expression,
+ const char *file_name,
+ int line_number);
+
+void nautilus_check_boolean_result (gboolean result,
+ gboolean expected_value);
+void nautilus_check_integer_result (long result,
+ long expected_value);
+void nautilus_check_string_result (char *result,
+ const char *expected_value);
+
#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
void function (void);
diff --git a/src/nautilus-main.c b/src/nautilus-main.c
index 6fdc116c8..f9624e43c 100644
--- a/src/nautilus-main.c
+++ b/src/nautilus-main.c
@@ -76,8 +76,7 @@ main(int argc, char *argv[])
/* Run the checks for nautilus and libnautilus. */
nautilus_run_self_checks ();
nautilus_run_lib_self_checks ();
- if (nautilus_self_checks_failed ())
- return EXIT_FAILURE;
+ nautilus_exit_if_self_checks_failed ();
} else {
#endif
diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c
index 72977dd83..93ae89a6c 100644
--- a/src/nautilus-view-frame.c
+++ b/src/nautilus-view-frame.c
@@ -243,8 +243,6 @@ nautilus_view_destroy(GtkObject *view)
NautilusViewClass *klass = NAUTILUS_VIEW_CLASS(view->klass);
NautilusView *nview = NAUTILUS_VIEW(view);
- g_message("-------------------- nautilus_view_destroy(%p): %u", view, nview->timer_id);
-
if(nview->timer_id)
{
g_source_remove(nview->timer_id);
diff --git a/src/ntl-main.c b/src/ntl-main.c
index 6fdc116c8..f9624e43c 100644
--- a/src/ntl-main.c
+++ b/src/ntl-main.c
@@ -76,8 +76,7 @@ main(int argc, char *argv[])
/* Run the checks for nautilus and libnautilus. */
nautilus_run_self_checks ();
nautilus_run_lib_self_checks ();
- if (nautilus_self_checks_failed ())
- return EXIT_FAILURE;
+ nautilus_exit_if_self_checks_failed ();
} else {
#endif
diff --git a/src/ntl-view.c b/src/ntl-view.c
index 72977dd83..93ae89a6c 100644
--- a/src/ntl-view.c
+++ b/src/ntl-view.c
@@ -243,8 +243,6 @@ nautilus_view_destroy(GtkObject *view)
NautilusViewClass *klass = NAUTILUS_VIEW_CLASS(view->klass);
NautilusView *nview = NAUTILUS_VIEW(view);
- g_message("-------------------- nautilus_view_destroy(%p): %u", view, nview->timer_id);
-
if(nview->timer_id)
{
g_source_remove(nview->timer_id);