Fix the "selection_changed" signal to not get emitted twice in some cases.

2004-07-04  Anders Carlsson  <andersca@gnome.org>

	* configure.in:
	* libegg/iconlist/eggiconlist.c: (egg_icon_list_expose),
	(scroll_timeout), (egg_icon_list_motion),
	(egg_icon_list_button_press), (egg_icon_list_update_rubberband),
	(egg_icon_list_start_rubberbanding),
	(egg_icon_list_stop_rubberbanding),
	(egg_icon_list_unselect_all_internal),
	(egg_icon_list_real_select_all),
	(egg_icon_list_adjustment_changed), (egg_icon_list_item_free),
	(egg_icon_list_select_item), (verify_items),
	(egg_icon_list_row_changed), (egg_icon_list_row_inserted),
	(egg_icon_list_row_deleted), (egg_icon_list_rows_reordered),
	(egg_icon_list_select_all_between),
	(egg_icon_list_move_cursor_up_down),
	(egg_icon_list_move_cursor_page_up_down),
	(egg_icon_list_move_cursor_left_right),
	(egg_icon_list_move_cursor_start_end), (egg_icon_list_set_model),
	(egg_icon_list_get_selected_items), (egg_icon_list_select_all),
	(egg_icon_list_unselect_all):
	* libegg/iconlist/eggiconlist.h:
	* libegg/iconlist/testiconlist.c: (foreach_selected_remove):
	Fix the "selection_changed" signal to not get emitted twice in some cases.
	Also fix a bunch of issues reported by Jonathan.
This commit is contained in:
Anders Carlsson 2004-07-04 12:43:26 +00:00 committed by Anders Carlsson
parent fd10968b12
commit 17c3df345a
2 changed files with 185 additions and 115 deletions

View File

@ -34,7 +34,10 @@
#define ICON_TEXT_PADDING 3 #define ICON_TEXT_PADDING 3
#define EGG_ICON_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EGG_TYPE_ICON_LIST, EggIconListPrivate)) #define EGG_ICON_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EGG_TYPE_ICON_LIST, EggIconListPrivate))
#define VALID_MODEL_AND_COLUMNS(obj) ((obj)->priv->model != NULL) #define VALID_MODEL_AND_COLUMNS(obj) ((obj)->priv->model != NULL && \
((obj)->priv->pixbuf_column != -1 || \
(obj)->priv->text_column != -1 || \
(obj)->priv->markup_column != -1))
struct _EggIconListItem struct _EggIconListItem
{ {
@ -80,7 +83,7 @@ struct _EggIconListPrivate
guint layout_idle_id; guint layout_idle_id;
gboolean rubberbanding; gboolean doing_rubberband;
gint rubberband_x1, rubberband_y1; gint rubberband_x1, rubberband_y1;
gint rubberband_x2, rubberband_y2; gint rubberband_x2, rubberband_y2;
@ -131,9 +134,6 @@ enum
PROP_MODEL, PROP_MODEL,
}; };
static void egg_icon_list_class_init (EggIconListClass *klass);
static void egg_icon_list_init (EggIconList *icon_list);
/* GObject signals */ /* GObject signals */
static void egg_icon_list_finalize (GObject *object); static void egg_icon_list_finalize (GObject *object);
static void egg_icon_list_set_property (GObject *object, static void egg_icon_list_set_property (GObject *object,
@ -174,10 +174,6 @@ static void egg_icon_list_real_select_all (EggIconList
static void egg_icon_list_real_unselect_all (EggIconList *icon_list); static void egg_icon_list_real_unselect_all (EggIconList *icon_list);
static void egg_icon_list_real_select_cursor_item (EggIconList *icon_list); static void egg_icon_list_real_select_cursor_item (EggIconList *icon_list);
static void egg_icon_list_real_toggle_cursor_item (EggIconList *icon_list); static void egg_icon_list_real_toggle_cursor_item (EggIconList *icon_list);
static void egg_icon_list_select_all_between (EggIconList *icon_list,
EggIconListItem *anchor,
EggIconListItem *cursor,
gboolean emit);
/* Internal functions */ /* Internal functions */
static void egg_icon_list_adjustment_changed (GtkAdjustment *adjustment, static void egg_icon_list_adjustment_changed (GtkAdjustment *adjustment,
@ -207,11 +203,10 @@ static gboolean egg_icon_list_item_hit_test (EggIconListItem *it
static gboolean egg_icon_list_maybe_begin_dragging_items (EggIconList *icon_list, static gboolean egg_icon_list_maybe_begin_dragging_items (EggIconList *icon_list,
GdkEventMotion *event); GdkEventMotion *event);
#endif #endif
static gboolean egg_icon_list_unselect_all_internal (EggIconList *icon_list, static gboolean egg_icon_list_unselect_all_internal (EggIconList *icon_list);
gboolean emit);
static void egg_icon_list_calculate_item_size (EggIconList *icon_list, static void egg_icon_list_calculate_item_size (EggIconList *icon_list,
EggIconListItem *item); EggIconListItem *item);
static void rubberbanding (gpointer data); static void egg_icon_list_update_rubberband (gpointer data);
static void egg_icon_list_item_invalidate_size (EggIconListItem *item); static void egg_icon_list_item_invalidate_size (EggIconListItem *item);
static void egg_icon_list_invalidate_sizes (EggIconList *icon_list); static void egg_icon_list_invalidate_sizes (EggIconList *icon_list);
static void egg_icon_list_add_move_binding (GtkBindingSet *binding_set, static void egg_icon_list_add_move_binding (GtkBindingSet *binding_set,
@ -240,11 +235,13 @@ static void egg_icon_list_select_item (EggIconList *ic
EggIconListItem *item); EggIconListItem *item);
static void egg_icon_list_unselect_item (EggIconList *icon_list, static void egg_icon_list_unselect_item (EggIconList *icon_list,
EggIconListItem *item); EggIconListItem *item);
static gboolean egg_icon_list_select_all_between (EggIconList *icon_list,
EggIconListItem *anchor,
EggIconListItem *cursor);
static EggIconListItem * static EggIconListItem *egg_icon_list_get_item_at_pos (EggIconList *icon_list,
egg_icon_list_get_item_at_pos (EggIconList *icon_list, gint x,
gint x, gint y);
gint y);
@ -253,31 +250,7 @@ egg_icon_list_get_item_at_pos (EggIconList *icon_list,
static GtkContainerClass *parent_class = NULL; static GtkContainerClass *parent_class = NULL;
static guint icon_list_signals[LAST_SIGNAL] = { 0 }; static guint icon_list_signals[LAST_SIGNAL] = { 0 };
GType G_DEFINE_TYPE (EggIconList, egg_icon_list, GTK_TYPE_CONTAINER);
egg_icon_list_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (EggIconListClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) egg_icon_list_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EggIconList),
0, /* n_preallocs */
(GInstanceInitFunc) egg_icon_list_init
};
object_type = g_type_register_static (GTK_TYPE_CONTAINER, "EggIconList", &object_info, 0);
}
return object_type;
}
static void static void
egg_icon_list_class_init (EggIconListClass *klass) egg_icon_list_class_init (EggIconListClass *klass)
@ -839,7 +812,7 @@ egg_icon_list_expose (GtkWidget *widget,
egg_icon_list_paint_item (icon_list, item, &expose->area); egg_icon_list_paint_item (icon_list, item, &expose->area);
} }
if (icon_list->priv->rubberbanding) if (icon_list->priv->doing_rubberband)
{ {
GdkRectangle *rectangles; GdkRectangle *rectangles;
gint n_rectangles; gint n_rectangles;
@ -873,7 +846,7 @@ scroll_timeout (gpointer data)
gtk_adjustment_set_value (icon_list->priv->vadjustment, gtk_adjustment_set_value (icon_list->priv->vadjustment,
value); value);
rubberbanding (icon_list); egg_icon_list_update_rubberband (icon_list);
return TRUE; return TRUE;
} }
@ -889,10 +862,10 @@ egg_icon_list_motion (GtkWidget *widget,
#ifdef DND_WORKS #ifdef DND_WORKS
egg_icon_list_maybe_begin_dragging_items (icon_list, event); egg_icon_list_maybe_begin_dragging_items (icon_list, event);
#endif #endif
if (icon_list->priv->rubberbanding) if (icon_list->priv->doing_rubberband)
{ {
rubberbanding (widget); egg_icon_list_update_rubberband (widget);
abs_y = event->y - icon_list->priv->height * abs_y = event->y - icon_list->priv->height *
(icon_list->priv->vadjustment->value / (icon_list->priv->vadjustment->value /
(icon_list->priv->vadjustment->upper - (icon_list->priv->vadjustment->upper -
@ -955,7 +928,7 @@ egg_icon_list_button_press (GtkWidget *widget,
else if (icon_list->priv->selection_mode == GTK_SELECTION_MULTIPLE && else if (icon_list->priv->selection_mode == GTK_SELECTION_MULTIPLE &&
(event->state & GDK_SHIFT_MASK)) (event->state & GDK_SHIFT_MASK))
{ {
egg_icon_list_unselect_all_internal (icon_list, FALSE); egg_icon_list_unselect_all_internal (icon_list);
egg_icon_list_set_cursor_item (icon_list, item); egg_icon_list_set_cursor_item (icon_list, item);
if (!icon_list->priv->anchor_item) if (!icon_list->priv->anchor_item)
@ -963,7 +936,7 @@ egg_icon_list_button_press (GtkWidget *widget,
else else
egg_icon_list_select_all_between (icon_list, egg_icon_list_select_all_between (icon_list,
icon_list->priv->anchor_item, icon_list->priv->anchor_item,
item, FALSE); item);
dirty = TRUE; dirty = TRUE;
} }
else else
@ -979,7 +952,7 @@ egg_icon_list_button_press (GtkWidget *widget,
{ {
if (!item->selected) if (!item->selected)
{ {
egg_icon_list_unselect_all_internal (icon_list, FALSE); egg_icon_list_unselect_all_internal (icon_list);
item->selected = TRUE; item->selected = TRUE;
egg_icon_list_queue_draw_item (icon_list, item); egg_icon_list_queue_draw_item (icon_list, item);
@ -1006,7 +979,7 @@ egg_icon_list_button_press (GtkWidget *widget,
if (icon_list->priv->selection_mode != GTK_SELECTION_BROWSE && if (icon_list->priv->selection_mode != GTK_SELECTION_BROWSE &&
!(event->state & GDK_CONTROL_MASK)) !(event->state & GDK_CONTROL_MASK))
{ {
dirty = egg_icon_list_unselect_all_internal (icon_list, FALSE); dirty = egg_icon_list_unselect_all_internal (icon_list);
} }
if (icon_list->priv->selection_mode == GTK_SELECTION_MULTIPLE) if (icon_list->priv->selection_mode == GTK_SELECTION_MULTIPLE)
@ -1063,7 +1036,7 @@ egg_icon_list_button_release (GtkWidget *widget,
static void static void
rubberbanding (gpointer data) egg_icon_list_update_rubberband (gpointer data)
{ {
EggIconList *icon_list; EggIconList *icon_list;
gint x, y; gint x, y;
@ -1130,7 +1103,7 @@ egg_icon_list_start_rubberbanding (EggIconList *icon_list,
{ {
GList *items; GList *items;
g_assert (!icon_list->priv->rubberbanding); g_assert (!icon_list->priv->doing_rubberband);
for (items = icon_list->priv->items; items; items = items->next) for (items = icon_list->priv->items; items; items = items->next)
{ {
@ -1144,7 +1117,7 @@ egg_icon_list_start_rubberbanding (EggIconList *icon_list,
icon_list->priv->rubberband_x2 = x; icon_list->priv->rubberband_x2 = x;
icon_list->priv->rubberband_y2 = y; icon_list->priv->rubberband_y2 = y;
icon_list->priv->rubberbanding = TRUE; icon_list->priv->doing_rubberband = TRUE;
gtk_grab_add (GTK_WIDGET (icon_list)); gtk_grab_add (GTK_WIDGET (icon_list));
} }
@ -1152,10 +1125,10 @@ egg_icon_list_start_rubberbanding (EggIconList *icon_list,
static void static void
egg_icon_list_stop_rubberbanding (EggIconList *icon_list) egg_icon_list_stop_rubberbanding (EggIconList *icon_list)
{ {
if (!icon_list->priv->rubberbanding) if (!icon_list->priv->doing_rubberband)
return; return;
icon_list->priv->rubberbanding = FALSE; icon_list->priv->doing_rubberband = FALSE;
gtk_grab_remove (GTK_WIDGET (icon_list)); gtk_grab_remove (GTK_WIDGET (icon_list));
@ -1270,11 +1243,14 @@ egg_icon_list_maybe_begin_dragging_items (EggIconList *icon_list,
#endif #endif
static gboolean static gboolean
egg_icon_list_unselect_all_internal (EggIconList *icon_list, egg_icon_list_unselect_all_internal (EggIconList *icon_list)
gboolean emit)
{ {
gboolean dirty = FALSE; gboolean dirty = FALSE;
GList *items; GList *items;
if (icon_list->priv->selection_mode == GTK_SELECTION_NONE ||
icon_list->priv->selection_mode == GTK_SELECTION_BROWSE)
return FALSE;
for (items = icon_list->priv->items; items; items = items->next) for (items = icon_list->priv->items; items; items = items->next)
{ {
@ -1288,9 +1264,6 @@ egg_icon_list_unselect_all_internal (EggIconList *icon_list,
} }
} }
if (emit && dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
return dirty; return dirty;
} }
@ -1357,9 +1330,6 @@ egg_icon_list_set_adjustments (EggIconList *icon_list,
static void static void
egg_icon_list_real_select_all (EggIconList *icon_list) egg_icon_list_real_select_all (EggIconList *icon_list)
{ {
if (icon_list->priv->selection_mode != GTK_SELECTION_MULTIPLE)
return;
egg_icon_list_select_all (icon_list); egg_icon_list_select_all (icon_list);
} }
@ -1420,8 +1390,8 @@ egg_icon_list_adjustment_changed (GtkAdjustment *adjustment,
- icon_list->priv->hadjustment->value, - icon_list->priv->hadjustment->value,
- icon_list->priv->vadjustment->value); - icon_list->priv->vadjustment->value);
if (icon_list->priv->rubberbanding) if (icon_list->priv->doing_rubberband)
rubberbanding (GTK_WIDGET (icon_list)); egg_icon_list_update_rubberband (GTK_WIDGET (icon_list));
gdk_window_process_updates (icon_list->priv->bin_window, TRUE); gdk_window_process_updates (icon_list->priv->bin_window, TRUE);
} }
@ -1916,25 +1886,11 @@ egg_icon_list_item_new (void)
} }
static void static void
egg_icon_list_item_ref (EggIconListItem *item) egg_icon_list_item_free (EggIconListItem *item)
{ {
g_return_if_fail (item != NULL); g_return_if_fail (item != NULL);
item->ref_count += 1; g_free (item);
}
static void
egg_icon_list_item_unref (EggIconListItem *item)
{
g_return_if_fail (item != NULL);
item->ref_count -= 1;
if (item->ref_count == 0)
{
g_free (item);
}
} }
static void static void
@ -2050,13 +2006,13 @@ egg_icon_list_select_item (EggIconList *icon_list,
if (icon_list->priv->selection_mode == GTK_SELECTION_NONE) if (icon_list->priv->selection_mode == GTK_SELECTION_NONE)
return; return;
else if (icon_list->priv->selection_mode != GTK_SELECTION_MULTIPLE) else if (icon_list->priv->selection_mode != GTK_SELECTION_MULTIPLE)
egg_icon_list_unselect_all_internal (icon_list, FALSE); egg_icon_list_unselect_all_internal (icon_list);
item->selected = TRUE; item->selected = TRUE;
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
egg_icon_list_queue_draw_item (icon_list, item); egg_icon_list_queue_draw_item (icon_list, item);
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
@ -2081,6 +2037,23 @@ egg_icon_list_unselect_item (EggIconList *icon_list,
egg_icon_list_queue_draw_item (icon_list, item); egg_icon_list_queue_draw_item (icon_list, item);
} }
static void
verify_items (EggIconList *icon_list)
{
GList *items;
int i = 0;
for (items = icon_list->priv->items; items; items = items->next)
{
EggIconListItem *item = items->data;
if (item->index != i)
g_error ("List item does not match its index: item index %d and list index %d\n", item->index, i);
i++;
}
}
static void static void
egg_icon_list_row_changed (GtkTreeModel *model, egg_icon_list_row_changed (GtkTreeModel *model,
GtkTreePath *path, GtkTreePath *path,
@ -2098,6 +2071,8 @@ egg_icon_list_row_changed (GtkTreeModel *model,
egg_icon_list_item_invalidate_size (item); egg_icon_list_item_invalidate_size (item);
egg_icon_list_queue_layout (icon_list); egg_icon_list_queue_layout (icon_list);
verify_items (icon_list);
} }
static void static void
@ -2110,7 +2085,8 @@ egg_icon_list_row_inserted (GtkTreeModel *model,
EggIconListItem *item; EggIconListItem *item;
gboolean iters_persist; gboolean iters_persist;
EggIconList *icon_list; EggIconList *icon_list;
GList *list;
icon_list = EGG_ICON_LIST (data); icon_list = EGG_ICON_LIST (data);
iters_persist = gtk_tree_model_get_flags (icon_list->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST; iters_persist = gtk_tree_model_get_flags (icon_list->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
@ -2131,6 +2107,15 @@ egg_icon_list_row_inserted (GtkTreeModel *model,
icon_list->priv->items = g_list_insert (icon_list->priv->items, icon_list->priv->items = g_list_insert (icon_list->priv->items,
item, index); item, index);
list = g_list_nth (icon_list->priv->items, index + 1);
for (; list; list = list->next)
{
item = list->data;
item->index++;
}
verify_items (icon_list);
} }
static void static void
@ -2141,7 +2126,7 @@ egg_icon_list_row_deleted (GtkTreeModel *model,
gint index; gint index;
EggIconList *icon_list; EggIconList *icon_list;
EggIconListItem *item; EggIconListItem *item;
GList *list; GList *list, *next;
gboolean emit = FALSE; gboolean emit = FALSE;
icon_list = EGG_ICON_LIST (data); icon_list = EGG_ICON_LIST (data);
@ -2160,11 +2145,21 @@ egg_icon_list_row_deleted (GtkTreeModel *model,
if (item->selected) if (item->selected)
emit = TRUE; emit = TRUE;
item->index = -1; egg_icon_list_item_free (item);
egg_icon_list_item_unref (item);
for (next = list->next; next; next = next->next)
{
item = next->data;
item->index--;
}
icon_list->priv->items = g_list_delete_link (icon_list->priv->items, list); icon_list->priv->items = g_list_delete_link (icon_list->priv->items, list);
egg_icon_list_queue_layout (icon_list);
verify_items (icon_list);
if (emit) if (emit)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0); g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
@ -2198,11 +2193,16 @@ egg_icon_list_rows_reordered (GtkTreeModel *model,
g_free (inverted_order); g_free (inverted_order);
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
items = g_list_prepend (items, item_array[i]); {
item_array[i]->index = i;
items = g_list_prepend (items, item_array[i]);
}
g_free (item_array); g_free (item_array);
g_list_free (icon_list->priv->items); g_list_free (icon_list->priv->items);
icon_list->priv->items = g_list_reverse (items); icon_list->priv->items = g_list_reverse (items);
verify_items (icon_list);
} }
static void static void
@ -2399,16 +2399,16 @@ find_item_page_up_down (EggIconList *icon_list,
return NULL; return NULL;
} }
static void static gboolean
egg_icon_list_select_all_between (EggIconList *icon_list, egg_icon_list_select_all_between (EggIconList *icon_list,
EggIconListItem *anchor, EggIconListItem *anchor,
EggIconListItem *cursor, EggIconListItem *cursor)
gboolean emit)
{ {
GList *items; GList *items;
EggIconListItem *item; EggIconListItem *item;
gint row1, row2, col1, col2; gint row1, row2, col1, col2;
gboolean dirty = FALSE;
if (anchor->row < cursor->row) if (anchor->row < cursor->row)
{ {
row1 = anchor->row; row1 = anchor->row;
@ -2438,14 +2438,16 @@ egg_icon_list_select_all_between (EggIconList *icon_list,
if (row1 <= item->row && item->row <= row2 && if (row1 <= item->row && item->row <= row2 &&
col1 <= item->col && item->col <= col2) col1 <= item->col && item->col <= col2)
{ {
if (!item->selected)
dirty = TRUE;
item->selected = TRUE; item->selected = TRUE;
egg_icon_list_queue_draw_item (icon_list, item); egg_icon_list_queue_draw_item (icon_list, item);
} }
} }
if (emit) return dirty;
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
static void static void
@ -2453,7 +2455,8 @@ egg_icon_list_move_cursor_up_down (EggIconList *icon_list,
gint count) gint count)
{ {
EggIconListItem *item; EggIconListItem *item;
gboolean dirty = FALSE;
if (!GTK_WIDGET_HAS_FOCUS (icon_list)) if (!GTK_WIDGET_HAS_FOCUS (icon_list))
return; return;
@ -2487,13 +2490,16 @@ egg_icon_list_move_cursor_up_down (EggIconList *icon_list,
if (!icon_list->priv->ctrl_pressed && if (!icon_list->priv->ctrl_pressed &&
icon_list->priv->selection_mode != GTK_SELECTION_NONE) icon_list->priv->selection_mode != GTK_SELECTION_NONE)
{ {
egg_icon_list_unselect_all (icon_list); egg_icon_list_unselect_all_internal (icon_list);
egg_icon_list_select_all_between (icon_list, dirty = egg_icon_list_select_all_between (icon_list,
icon_list->priv->anchor_item, icon_list->priv->anchor_item,
item, TRUE); item);
} }
egg_icon_list_scroll_to_item (icon_list, item); egg_icon_list_scroll_to_item (icon_list, item);
if (dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
static void static void
@ -2501,7 +2507,8 @@ egg_icon_list_move_cursor_page_up_down (EggIconList *icon_list,
gint count) gint count)
{ {
EggIconListItem *item; EggIconListItem *item;
gboolean dirty = FALSE;
if (!GTK_WIDGET_HAS_FOCUS (icon_list)) if (!GTK_WIDGET_HAS_FOCUS (icon_list))
return; return;
@ -2535,13 +2542,16 @@ egg_icon_list_move_cursor_page_up_down (EggIconList *icon_list,
if (!icon_list->priv->ctrl_pressed && if (!icon_list->priv->ctrl_pressed &&
icon_list->priv->selection_mode != GTK_SELECTION_NONE) icon_list->priv->selection_mode != GTK_SELECTION_NONE)
{ {
egg_icon_list_unselect_all (icon_list); egg_icon_list_unselect_all_internal (icon_list);
egg_icon_list_select_all_between (icon_list, dirty = egg_icon_list_select_all_between (icon_list,
icon_list->priv->anchor_item, icon_list->priv->anchor_item,
item, TRUE); item);
} }
egg_icon_list_scroll_to_item (icon_list, item); egg_icon_list_scroll_to_item (icon_list, item);
if (dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
static void static void
@ -2549,7 +2559,8 @@ egg_icon_list_move_cursor_left_right (EggIconList *icon_list,
gint count) gint count)
{ {
EggIconListItem *item; EggIconListItem *item;
gboolean dirty = FALSE;
if (!GTK_WIDGET_HAS_FOCUS (icon_list)) if (!GTK_WIDGET_HAS_FOCUS (icon_list))
return; return;
@ -2583,13 +2594,16 @@ egg_icon_list_move_cursor_left_right (EggIconList *icon_list,
if (!icon_list->priv->ctrl_pressed && if (!icon_list->priv->ctrl_pressed &&
icon_list->priv->selection_mode != GTK_SELECTION_NONE) icon_list->priv->selection_mode != GTK_SELECTION_NONE)
{ {
egg_icon_list_unselect_all (icon_list); egg_icon_list_unselect_all_internal (icon_list);
egg_icon_list_select_all_between (icon_list, dirty = egg_icon_list_select_all_between (icon_list,
icon_list->priv->anchor_item, icon_list->priv->anchor_item,
item, TRUE); item);
} }
egg_icon_list_scroll_to_item (icon_list, item); egg_icon_list_scroll_to_item (icon_list, item);
if (dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
static void static void
@ -2598,6 +2612,7 @@ egg_icon_list_move_cursor_start_end (EggIconList *icon_list,
{ {
EggIconListItem *item; EggIconListItem *item;
GList *list; GList *list;
gboolean dirty = FALSE;
if (!GTK_WIDGET_HAS_FOCUS (icon_list)) if (!GTK_WIDGET_HAS_FOCUS (icon_list))
return; return;
@ -2624,12 +2639,15 @@ egg_icon_list_move_cursor_start_end (EggIconList *icon_list,
icon_list->priv->selection_mode != GTK_SELECTION_NONE) icon_list->priv->selection_mode != GTK_SELECTION_NONE)
{ {
egg_icon_list_unselect_all (icon_list); egg_icon_list_unselect_all (icon_list);
egg_icon_list_select_all_between (icon_list, dirty = egg_icon_list_select_all_between (icon_list,
icon_list->priv->anchor_item, icon_list->priv->anchor_item,
item, TRUE); item);
} }
egg_icon_list_scroll_to_item (icon_list, item); egg_icon_list_scroll_to_item (icon_list, item);
if (dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
static void static void
@ -2859,7 +2877,7 @@ egg_icon_list_set_model (EggIconList *icon_list,
g_object_unref (icon_list->priv->model); g_object_unref (icon_list->priv->model);
g_list_foreach (icon_list->priv->items, (GFunc)egg_icon_list_item_unref, NULL); g_list_foreach (icon_list->priv->items, (GFunc)egg_icon_list_item_free, NULL);
g_list_free (icon_list->priv->items); g_list_free (icon_list->priv->items);
icon_list->priv->items = NULL; icon_list->priv->items = NULL;
} }
@ -3137,6 +3155,49 @@ egg_icon_list_unselect_path (EggIconList *icon_list,
egg_icon_list_unselect_item (icon_list, item); egg_icon_list_unselect_item (icon_list, item);
} }
/**
* egg_icon_list_get_selected_items:
* @selection: A #EggIconList.
*
* Creates a list of path of all selected items. Additionally, if you are
* planning on modifying the model after calling this function, you may
* want to convert the returned list into a list of #GtkTreeRowReference<!-- -->s.
* To do this, you can use gtk_tree_row_reference_new().
*
* To free the return value, use:
* <informalexample><programlisting>
* g_list_foreach (list, gtk_tree_path_free, NULL);
* g_list_free (list);
* </programlisting></informalexample>
*
* Return value: A #GList containing a #GtkTreePath for each selected row.
*
* Since: 2.6
**/
GList *
egg_icon_list_get_selected_items (EggIconList *icon_list)
{
GList *list;
GList *selected = NULL;
g_return_val_if_fail (EGG_IS_ICON_LIST (icon_list), NULL);
for (list = icon_list->priv->items; list != NULL; list = list->next)
{
EggIconListItem *item = list->data;
if (item->selected)
{
GtkTreePath *path = gtk_tree_path_new_from_indices (item->index, -1);
g_print ("index is: %d\n", item->index);
selected = g_list_prepend (selected, path);
}
}
return selected;
}
/** /**
* egg_icon_list_select_all: * egg_icon_list_select_all:
* @icon_list: A #EggIconList. * @icon_list: A #EggIconList.
@ -3152,6 +3213,9 @@ egg_icon_list_select_all (EggIconList *icon_list)
g_return_if_fail (EGG_IS_ICON_LIST (icon_list)); g_return_if_fail (EGG_IS_ICON_LIST (icon_list));
if (icon_list->priv->selection_mode != GTK_SELECTION_MULTIPLE)
return;
for (items = icon_list->priv->items; items; items = items->next) for (items = icon_list->priv->items; items; items = items->next)
{ {
EggIconListItem *item = items->data; EggIconListItem *item = items->data;
@ -3177,9 +3241,14 @@ egg_icon_list_select_all (EggIconList *icon_list)
void void
egg_icon_list_unselect_all (EggIconList *icon_list) egg_icon_list_unselect_all (EggIconList *icon_list)
{ {
gboolean dirty = FALSE;
g_return_if_fail (EGG_IS_ICON_LIST (icon_list)); g_return_if_fail (EGG_IS_ICON_LIST (icon_list));
egg_icon_list_unselect_all_internal (icon_list, TRUE); dirty = egg_icon_list_unselect_all_internal (icon_list);
if (dirty)
g_signal_emit (icon_list, icon_list_signals[SELECTION_CHANGED], 0);
} }
/** /**

View File

@ -102,6 +102,7 @@ void egg_icon_list_unselect_path (EggIconList *icon_
GtkTreePath *path); GtkTreePath *path);
gboolean egg_icon_list_path_is_selected (EggIconList *icon_list, gboolean egg_icon_list_path_is_selected (EggIconList *icon_list,
GtkTreePath *path); GtkTreePath *path);
GList *egg_icon_list_get_selected_items (EggIconList *icon_list);
void egg_icon_list_select_all (EggIconList *icon_list); void egg_icon_list_select_all (EggIconList *icon_list);
void egg_icon_list_unselect_all (EggIconList *icon_list); void egg_icon_list_unselect_all (EggIconList *icon_list);
void egg_icon_list_item_activated (EggIconList *icon_list, void egg_icon_list_item_activated (EggIconList *icon_list,