mirror of https://github.com/GNOME/gimp.git
app: add a "select-items" signal to GimpContainerView.
Properly pass the multi-selection information through the container classes. Previous implementation was incomplete (most code paths with multiple item selected were just ignored) and data was passed through the "select-item" signal with the GimpViewable to NULL and the data to a list of items (instead of being a GtkTreeIter otherwise). Having a pointer data which changes meaning in the same function/class is not the best idea. So instead "select-items" will have 2 list as parameters: a list of items and a list of GtkTreePath to be used similarly and with less ambiguity.
This commit is contained in:
parent
15113782fd
commit
288bec3b79
|
@ -480,7 +480,7 @@ action_data_sel_count (gpointer data)
|
|||
GimpContainerEditor *editor;
|
||||
|
||||
editor = GIMP_CONTAINER_EDITOR (data);
|
||||
return gimp_container_view_get_selected (editor->view, NULL);
|
||||
return gimp_container_view_get_selected (editor->view, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -117,7 +117,7 @@ palettes_merge_callback (GtkWidget *widget,
|
|||
context = gimp_container_view_get_context (editor->view);
|
||||
factory = gimp_data_factory_view_get_data_factory (view);
|
||||
|
||||
gimp_container_view_get_selected (editor->view, &selected);
|
||||
gimp_container_view_get_selected (editor->view, &selected, NULL);
|
||||
|
||||
if (g_list_length (selected) < 2)
|
||||
{
|
||||
|
|
|
@ -105,8 +105,9 @@ static GdkPixbuf * gimp_container_icon_view_drag_pixbuf (GtkWidget *wi
|
|||
gpointer data);
|
||||
static gboolean gimp_container_icon_view_get_selected_single (GimpContainerIconView *icon_view,
|
||||
GtkTreeIter *iter);
|
||||
static gint gimp_container_icon_view_get_selected (GimpContainerView *view,
|
||||
GList **items);
|
||||
static gint gimp_container_icon_view_get_selected (GimpContainerView *view,
|
||||
GList **items,
|
||||
GList **paths);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GimpContainerIconView, gimp_container_icon_view,
|
||||
|
@ -604,9 +605,11 @@ gimp_container_icon_view_selection_changed (GtkIconView *gtk_icon_view
|
|||
{
|
||||
GimpContainerView *view = GIMP_CONTAINER_VIEW (icon_view);
|
||||
GList *items;
|
||||
GList *paths;
|
||||
|
||||
gimp_container_icon_view_get_selected (view, &items);
|
||||
gimp_container_view_multi_selected (view, items);
|
||||
gimp_container_icon_view_get_selected (view, &items, &paths);
|
||||
gimp_container_view_multi_selected (view, items, paths);
|
||||
g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
|
||||
g_list_free (items);
|
||||
}
|
||||
|
||||
|
@ -773,22 +776,24 @@ gimp_container_icon_view_get_selected_single (GimpContainerIconView *icon_view,
|
|||
|
||||
static gint
|
||||
gimp_container_icon_view_get_selected (GimpContainerView *view,
|
||||
GList **items)
|
||||
GList **items,
|
||||
GList **paths)
|
||||
{
|
||||
GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view);
|
||||
GList *selected_items;
|
||||
GList *selected_paths;
|
||||
gint selected_count;
|
||||
|
||||
selected_items = gtk_icon_view_get_selected_items (icon_view->view);
|
||||
selected_count = g_list_length (selected_items);
|
||||
selected_paths = gtk_icon_view_get_selected_items (icon_view->view);
|
||||
selected_count = g_list_length (selected_paths);
|
||||
|
||||
if (items)
|
||||
{
|
||||
GList *removed_paths = NULL;
|
||||
GList *list;
|
||||
|
||||
*items = NULL;
|
||||
|
||||
for (list = selected_items;
|
||||
for (list = selected_paths;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
|
@ -804,14 +809,30 @@ gimp_container_icon_view_get_selected (GimpContainerView *view,
|
|||
|
||||
if (renderer->viewable)
|
||||
*items = g_list_prepend (*items, renderer->viewable);
|
||||
else
|
||||
/* Remove from the selected_paths list but at the end, in order not
|
||||
* to break the for loop.
|
||||
*/
|
||||
removed_paths = g_list_prepend (removed_paths, list);
|
||||
|
||||
g_object_unref (renderer);
|
||||
}
|
||||
|
||||
*items = g_list_reverse (*items);
|
||||
|
||||
for (list = removed_paths; list; list = list->next)
|
||||
{
|
||||
GList *remove_list = list->data;
|
||||
|
||||
selected_paths = g_list_remove_link (selected_paths, remove_list);
|
||||
gtk_tree_path_free (remove_list->data);
|
||||
}
|
||||
g_list_free_full (removed_paths, (GDestroyNotify) g_list_free);
|
||||
}
|
||||
|
||||
g_list_free_full (selected_items, (GDestroyNotify) gtk_tree_path_free);
|
||||
if (paths)
|
||||
*paths = selected_paths;
|
||||
else
|
||||
g_list_free_full (selected_paths, (GDestroyNotify) gtk_tree_path_free);
|
||||
|
||||
return selected_count;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,9 @@ static void gimp_container_tree_view_expand_item (GimpContainerVi
|
|||
static gboolean gimp_container_tree_view_select_item (GimpContainerView *view,
|
||||
GimpViewable *viewable,
|
||||
gpointer insert_data);
|
||||
static gboolean gimp_container_tree_view_select_items (GimpContainerView *view,
|
||||
GList *viewables,
|
||||
GList *paths);
|
||||
static void gimp_container_tree_view_clear_items (GimpContainerView *view);
|
||||
static void gimp_container_tree_view_set_view_size (GimpContainerView *view);
|
||||
|
||||
|
@ -126,7 +129,8 @@ static GdkPixbuf *gimp_container_tree_view_drag_pixbuf (GtkWidget
|
|||
static gboolean gimp_container_tree_view_get_selected_single (GimpContainerTreeView *tree_view,
|
||||
GtkTreeIter *iter);
|
||||
static gint gimp_container_tree_view_get_selected (GimpContainerView *view,
|
||||
GList **items);
|
||||
GList **items,
|
||||
GList **paths);
|
||||
static void gimp_container_tree_view_row_expanded (GtkTreeView *tree_view,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *path,
|
||||
|
@ -205,6 +209,7 @@ gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *iface)
|
|||
iface->rename_item = gimp_container_tree_view_rename_item;
|
||||
iface->expand_item = gimp_container_tree_view_expand_item;
|
||||
iface->select_item = gimp_container_tree_view_select_item;
|
||||
iface->select_items = gimp_container_tree_view_select_items;
|
||||
iface->clear_items = gimp_container_tree_view_clear_items;
|
||||
iface->set_view_size = gimp_container_tree_view_set_view_size;
|
||||
iface->get_selected = gimp_container_tree_view_get_selected;
|
||||
|
@ -913,6 +918,47 @@ gimp_container_tree_view_select_item (GimpContainerView *view,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_container_tree_view_select_items (GimpContainerView *view,
|
||||
GList *items,
|
||||
GList *paths)
|
||||
{
|
||||
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
||||
GList *item;
|
||||
GList *path;
|
||||
|
||||
/*gtk_tree_selection_unselect_all (tree_view->priv->selection);*/
|
||||
for (item = items, path = paths; item && path; item = item->next, path = path->next)
|
||||
{
|
||||
GtkTreePath *parent_path;
|
||||
|
||||
/* Expand if necessary. */
|
||||
parent_path = gtk_tree_path_copy (path->data);
|
||||
if (gtk_tree_path_up (parent_path))
|
||||
gtk_tree_view_expand_to_path (tree_view->view, parent_path);
|
||||
gtk_tree_path_free (parent_path);
|
||||
|
||||
/* Add to the selection. */
|
||||
g_signal_handlers_block_by_func (tree_view->priv->selection,
|
||||
gimp_container_tree_view_selection_changed,
|
||||
tree_view);
|
||||
gtk_tree_selection_select_path (tree_view->priv->selection, path->data);
|
||||
g_signal_handlers_unblock_by_func (tree_view->priv->selection,
|
||||
gimp_container_tree_view_selection_changed,
|
||||
tree_view);
|
||||
|
||||
|
||||
/* Scroll to the top item. */
|
||||
if (item == items)
|
||||
gtk_tree_view_scroll_to_cell (tree_view->view, path->data,
|
||||
NULL, FALSE, 0.0, 0.0);
|
||||
/* TODO: better implementation: only scroll if none of the items
|
||||
* are visible. */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_container_tree_view_clear_items (GimpContainerView *view)
|
||||
{
|
||||
|
@ -1111,12 +1157,14 @@ static void
|
|||
gimp_container_tree_view_selection_changed (GtkTreeSelection *selection,
|
||||
GimpContainerTreeView *tree_view)
|
||||
{
|
||||
GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
|
||||
GList *items;
|
||||
GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
|
||||
GList *items;
|
||||
GList *paths;
|
||||
|
||||
gimp_container_tree_view_get_selected (view, &items);
|
||||
gimp_container_view_multi_selected (view, items);
|
||||
gimp_container_tree_view_get_selected (view, &items, &paths);
|
||||
gimp_container_view_multi_selected (view, items, paths);
|
||||
g_list_free (items);
|
||||
g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
|
||||
}
|
||||
|
||||
static GtkCellRenderer *
|
||||
|
@ -1299,7 +1347,7 @@ gimp_container_tree_view_button_press (GtkWidget *widget,
|
|||
{
|
||||
if (multisel_mode)
|
||||
{
|
||||
/* let parent do the work */
|
||||
/* Will be handled by gimp_container_tree_view_selection_changed() */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1535,12 +1583,14 @@ gimp_container_tree_view_get_selected_single (GimpContainerTreeView *tree_view,
|
|||
|
||||
static gint
|
||||
gimp_container_tree_view_get_selected (GimpContainerView *view,
|
||||
GList **items)
|
||||
GList **items,
|
||||
GList **paths)
|
||||
{
|
||||
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
||||
GtkTreeSelection *selection;
|
||||
gint selected_count;
|
||||
GList *selected_rows;
|
||||
GList *selected_paths;
|
||||
GList *removed_paths = NULL;
|
||||
GList *current_row;
|
||||
GtkTreeIter iter;
|
||||
GimpViewRenderer *renderer;
|
||||
|
@ -1550,14 +1600,17 @@ gimp_container_tree_view_get_selected (GimpContainerView *view,
|
|||
|
||||
if (items == NULL)
|
||||
{
|
||||
if (paths)
|
||||
*paths = NULL;
|
||||
|
||||
/* just provide selected count */
|
||||
return selected_count;
|
||||
}
|
||||
|
||||
selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
|
||||
selected_paths = gtk_tree_selection_get_selected_rows (selection, NULL);
|
||||
*items = NULL;
|
||||
|
||||
*items = NULL;
|
||||
for (current_row = selected_rows;
|
||||
for (current_row = selected_paths;
|
||||
current_row;
|
||||
current_row = g_list_next (current_row))
|
||||
{
|
||||
|
@ -1570,14 +1623,30 @@ gimp_container_tree_view_get_selected (GimpContainerView *view,
|
|||
|
||||
if (renderer->viewable)
|
||||
*items = g_list_prepend (*items, renderer->viewable);
|
||||
else
|
||||
/* Remove from the selected_paths list but at the end, in order not
|
||||
* to break the for loop.
|
||||
*/
|
||||
removed_paths = g_list_prepend (removed_paths, current_row);
|
||||
|
||||
g_object_unref (renderer);
|
||||
}
|
||||
|
||||
g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
|
||||
|
||||
*items = g_list_reverse (*items);
|
||||
|
||||
for (current_row = removed_paths; current_row; current_row = current_row->next)
|
||||
{
|
||||
GList *remove_list = current_row->data;
|
||||
|
||||
selected_paths = g_list_remove_link (selected_paths, remove_list);
|
||||
gtk_tree_path_free (remove_list->data);
|
||||
}
|
||||
g_list_free_full (removed_paths, (GDestroyNotify) g_list_free);
|
||||
|
||||
if (paths)
|
||||
*paths = selected_paths;
|
||||
else
|
||||
g_list_free_full (selected_paths, (GDestroyNotify) gtk_tree_path_free);
|
||||
|
||||
return selected_count;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
enum
|
||||
{
|
||||
SELECT_ITEM,
|
||||
SELECT_ITEMS,
|
||||
ACTIVATE_ITEM,
|
||||
CONTEXT_ITEM,
|
||||
LAST_SIGNAL
|
||||
|
@ -139,7 +140,8 @@ static void gimp_container_view_button_viewable_dropped (GtkWidget *widget,
|
|||
GimpViewable *viewable,
|
||||
gpointer data);
|
||||
static gint gimp_container_view_real_get_selected (GimpContainerView *view,
|
||||
GList **list);
|
||||
GList **list,
|
||||
GList **paths);
|
||||
|
||||
|
||||
G_DEFINE_INTERFACE (GimpContainerView, gimp_container_view, GTK_TYPE_WIDGET)
|
||||
|
@ -162,6 +164,17 @@ gimp_container_view_default_init (GimpContainerViewInterface *iface)
|
|||
GIMP_TYPE_OBJECT,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
view_signals[SELECT_ITEMS] =
|
||||
g_signal_new ("select-items",
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GimpContainerViewInterface, select_items),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
view_signals[ACTIVATE_ITEM] =
|
||||
g_signal_new ("activate-item",
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
|
@ -185,6 +198,7 @@ gimp_container_view_default_init (GimpContainerViewInterface *iface)
|
|||
G_TYPE_POINTER);
|
||||
|
||||
iface->select_item = NULL;
|
||||
iface->select_items = NULL;
|
||||
iface->activate_item = NULL;
|
||||
iface->context_item = NULL;
|
||||
|
||||
|
@ -767,10 +781,11 @@ gimp_container_view_item_selected (GimpContainerView *view,
|
|||
|
||||
gboolean
|
||||
gimp_container_view_multi_selected (GimpContainerView *view,
|
||||
GList *items)
|
||||
GList *items,
|
||||
GList *items_data)
|
||||
{
|
||||
guint selected_count;
|
||||
gboolean success = FALSE;
|
||||
gboolean success = FALSE;
|
||||
guint selected_count;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE);
|
||||
|
||||
|
@ -786,33 +801,64 @@ gimp_container_view_multi_selected (GimpContainerView *view,
|
|||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
g_signal_emit (view, view_signals[SELECT_ITEM], 0,
|
||||
NULL, items, &success);
|
||||
g_signal_emit (view, view_signals[SELECT_ITEMS], 0,
|
||||
items, items_data, &success);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_container_view_get_selected:
|
||||
* @view:
|
||||
* @items:
|
||||
* @items_data:
|
||||
*
|
||||
* Get the selected items in @view.
|
||||
*
|
||||
* If @items is not %NULL, fills it with a newly allocated #GList of the
|
||||
* selected items.
|
||||
* If @items_data is not %NULL and if the implementing class associates
|
||||
* data to its contents, it will be filled with a newly allocated #GList
|
||||
* of the same size as @items, or will be %NULL otherwise. It is up to
|
||||
* the class to decide what type of data is passed along.
|
||||
*
|
||||
* Note that by default, the interface only implements some basic single
|
||||
* selection. Override select_item() and select_items() signals to get
|
||||
* more complete selection support.
|
||||
*
|
||||
* Returns: the number of selected items.
|
||||
*/
|
||||
gint
|
||||
gimp_container_view_get_selected (GimpContainerView *view,
|
||||
GList **list)
|
||||
GList **items,
|
||||
GList **items_data)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), 0);
|
||||
|
||||
return GIMP_CONTAINER_VIEW_GET_IFACE (view)->get_selected (view, list);
|
||||
return GIMP_CONTAINER_VIEW_GET_IFACE (view)->get_selected (view, items, items_data);
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_container_view_real_get_selected (GimpContainerView *view,
|
||||
GList **list)
|
||||
GList **items,
|
||||
GList **items_data)
|
||||
{
|
||||
GimpContainerViewPrivate *private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view);
|
||||
GType children_type;
|
||||
GimpObject *object;
|
||||
|
||||
if (list)
|
||||
*list = NULL;
|
||||
if (items)
|
||||
*items = NULL;
|
||||
|
||||
/* In base interface, @items_data just stays NULL. We don't have a
|
||||
* concept for it. Classes implementing this interface may want to
|
||||
* store and pass data for their items, but they will have to
|
||||
* implement themselves which data, and pass through with this
|
||||
* parameter.
|
||||
*/
|
||||
if (items_data)
|
||||
*items_data = NULL;
|
||||
|
||||
if (! private->container || ! private->context)
|
||||
return 0;
|
||||
|
@ -821,8 +867,12 @@ gimp_container_view_real_get_selected (GimpContainerView *view,
|
|||
object = gimp_context_get_by_type (private->context,
|
||||
children_type);
|
||||
|
||||
if (list && object)
|
||||
*list = g_list_append (*list, object);
|
||||
/* Base interface provides the API for multi-selection but only
|
||||
* implements single selection. Classes must implement their own
|
||||
* multi-selection.
|
||||
*/
|
||||
if (items && object)
|
||||
*items = g_list_append (*items, object);
|
||||
|
||||
return object ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@ struct _GimpContainerViewInterface
|
|||
gboolean (* select_item) (GimpContainerView *view,
|
||||
GimpViewable *object,
|
||||
gpointer insert_data);
|
||||
gboolean (* select_items) (GimpContainerView *view,
|
||||
GList *items,
|
||||
GList *paths);
|
||||
|
||||
void (* activate_item) (GimpContainerView *view,
|
||||
GimpViewable *object,
|
||||
gpointer insert_data);
|
||||
|
@ -85,7 +89,8 @@ struct _GimpContainerViewInterface
|
|||
void (* clear_items) (GimpContainerView *view);
|
||||
void (* set_view_size) (GimpContainerView *view);
|
||||
gint (* get_selected) (GimpContainerView *view,
|
||||
GList **items);
|
||||
GList **items,
|
||||
GList **insert_data);
|
||||
|
||||
|
||||
/* the destroy notifier for private->hash_table's values */
|
||||
|
@ -131,7 +136,8 @@ void gimp_container_view_activate_item (GimpContainerView *v
|
|||
void gimp_container_view_context_item (GimpContainerView *view,
|
||||
GimpViewable *viewable);
|
||||
gint gimp_container_view_get_selected (GimpContainerView *view,
|
||||
GList **list);
|
||||
GList **items,
|
||||
GList **items_data);
|
||||
|
||||
/* protected */
|
||||
|
||||
|
@ -141,7 +147,8 @@ gpointer gimp_container_view_lookup (GimpContainerView *v
|
|||
gboolean gimp_container_view_item_selected (GimpContainerView *view,
|
||||
GimpViewable *item);
|
||||
gboolean gimp_container_view_multi_selected (GimpContainerView *view,
|
||||
GList *items);
|
||||
GList *items,
|
||||
GList *paths);
|
||||
void gimp_container_view_item_activated (GimpContainerView *view,
|
||||
GimpViewable *item);
|
||||
void gimp_container_view_item_context (GimpContainerView *view,
|
||||
|
|
|
@ -526,7 +526,7 @@ gimp_data_factory_view_select_item (GimpContainerEditor *editor,
|
|||
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (editor->view);
|
||||
GList *active_items = NULL;
|
||||
|
||||
gimp_container_view_get_selected (container_view, &active_items);
|
||||
gimp_container_view_get_selected (container_view, &active_items, NULL);
|
||||
gimp_tag_entry_set_selected_items (GIMP_TAG_ENTRY (view->priv->assign_tag_entry),
|
||||
active_items);
|
||||
g_list_free (active_items);
|
||||
|
|
|
@ -455,7 +455,7 @@ gimp_device_editor_delete_response (GtkWidget *dialog,
|
|||
GList *selected;
|
||||
|
||||
if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview),
|
||||
&selected))
|
||||
&selected, NULL))
|
||||
{
|
||||
GimpContainer *devices;
|
||||
|
||||
|
@ -479,7 +479,7 @@ gimp_device_editor_delete_clicked (GtkWidget *button,
|
|||
GList *selected;
|
||||
|
||||
if (! gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview),
|
||||
&selected))
|
||||
&selected, NULL))
|
||||
return;
|
||||
|
||||
dialog = gimp_message_dialog_new (_("Delete Device Settings"),
|
||||
|
|
|
@ -129,6 +129,9 @@ static void gimp_item_tree_view_insert_item_after (GimpContainerView *view,
|
|||
static gboolean gimp_item_tree_view_select_item (GimpContainerView *view,
|
||||
GimpViewable *item,
|
||||
gpointer insert_data);
|
||||
static gboolean gimp_item_tree_view_select_items (GimpContainerView *view,
|
||||
GList *items,
|
||||
GList *paths);
|
||||
static void gimp_item_tree_view_activate_item (GimpContainerView *view,
|
||||
GimpViewable *item,
|
||||
gpointer insert_data);
|
||||
|
@ -260,6 +263,7 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass)
|
|||
klass->get_container = NULL;
|
||||
klass->get_active_item = NULL;
|
||||
klass->set_active_item = NULL;
|
||||
klass->set_selected_items = NULL;
|
||||
klass->add_item = NULL;
|
||||
klass->remove_item = NULL;
|
||||
klass->new_item = NULL;
|
||||
|
@ -293,6 +297,7 @@ gimp_item_tree_view_view_iface_init (GimpContainerViewInterface *iface)
|
|||
iface->insert_item = gimp_item_tree_view_insert_item;
|
||||
iface->insert_item_after = gimp_item_tree_view_insert_item_after;
|
||||
iface->select_item = gimp_item_tree_view_select_item;
|
||||
iface->select_items = gimp_item_tree_view_select_items;
|
||||
iface->activate_item = gimp_item_tree_view_activate_item;
|
||||
iface->context_item = gimp_item_tree_view_context_item;
|
||||
}
|
||||
|
@ -1069,6 +1074,45 @@ gimp_item_tree_view_select_item (GimpContainerView *view,
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_item_tree_view_select_items (GimpContainerView *view,
|
||||
GList *selected_items,
|
||||
GList *paths)
|
||||
{
|
||||
GimpItemTreeView *tree_view = GIMP_ITEM_TREE_VIEW (view);
|
||||
GList *items = selected_items;
|
||||
gboolean options_sensitive = FALSE;
|
||||
gboolean success;
|
||||
|
||||
success = parent_view_iface->select_items (view, items, paths);
|
||||
|
||||
if (items)
|
||||
{
|
||||
GimpItemTreeViewClass *item_view_class;
|
||||
GList *iter;
|
||||
|
||||
item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (tree_view);
|
||||
if (TRUE) /* XXX: test if new selection same as old. */
|
||||
{
|
||||
item_view_class->set_selected_items (tree_view->priv->image,
|
||||
selected_items);
|
||||
gimp_image_flush (tree_view->priv->image);
|
||||
}
|
||||
|
||||
options_sensitive = TRUE;
|
||||
|
||||
for (iter = items; iter; iter = iter->next)
|
||||
gimp_item_tree_view_update_options (tree_view, iter->data);
|
||||
}
|
||||
|
||||
gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (tree_view)), tree_view);
|
||||
|
||||
if (tree_view->priv->options_box)
|
||||
gtk_widget_set_sensitive (tree_view->priv->options_box, options_sensitive);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_item_tree_view_activate_item (GimpContainerView *view,
|
||||
GimpViewable *item,
|
||||
|
|
|
@ -29,6 +29,8 @@ typedef GimpContainer * (* GimpGetContainerFunc) (GimpImage *image);
|
|||
typedef GimpItem * (* GimpGetItemFunc) (GimpImage *image);
|
||||
typedef void (* GimpSetItemFunc) (GimpImage *image,
|
||||
GimpItem *item);
|
||||
typedef void (* GimpSetItemsFunc) (GimpImage *image,
|
||||
GList *items);
|
||||
typedef void (* GimpAddItemFunc) (GimpImage *image,
|
||||
GimpItem *item,
|
||||
GimpItem *parent,
|
||||
|
@ -74,6 +76,7 @@ struct _GimpItemTreeViewClass
|
|||
GimpGetContainerFunc get_container;
|
||||
GimpGetItemFunc get_active_item;
|
||||
GimpSetItemFunc set_active_item;
|
||||
GimpSetItemsFunc set_selected_items;
|
||||
GimpAddItemFunc add_item;
|
||||
GimpRemoveItemFunc remove_item;
|
||||
GimpNewItemFunc new_item;
|
||||
|
|
|
@ -102,6 +102,9 @@ static gpointer gimp_layer_tree_view_insert_item (GimpContainer
|
|||
static gboolean gimp_layer_tree_view_select_item (GimpContainerView *view,
|
||||
GimpViewable *item,
|
||||
gpointer insert_data);
|
||||
static gboolean gimp_layer_tree_view_select_items (GimpContainerView *view,
|
||||
GList *items,
|
||||
GList *paths);
|
||||
static void gimp_layer_tree_view_set_view_size (GimpContainerView *view);
|
||||
static gboolean gimp_layer_tree_view_drop_possible (GimpContainerTreeView *view,
|
||||
GimpDndType src_type,
|
||||
|
@ -210,6 +213,7 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
|
|||
item_view_class->get_container = gimp_image_get_layers;
|
||||
item_view_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_layer;
|
||||
item_view_class->set_active_item = (GimpSetItemFunc) gimp_image_set_active_layer;
|
||||
item_view_class->set_selected_items = (GimpSetItemsFunc) gimp_image_set_selected_layers;
|
||||
item_view_class->add_item = (GimpAddItemFunc) gimp_image_add_layer;
|
||||
item_view_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_layer;
|
||||
item_view_class->new_item = gimp_layer_tree_view_item_new;
|
||||
|
@ -237,6 +241,7 @@ gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface)
|
|||
iface->set_context = gimp_layer_tree_view_set_context;
|
||||
iface->insert_item = gimp_layer_tree_view_insert_item;
|
||||
iface->select_item = gimp_layer_tree_view_select_item;
|
||||
iface->select_items = gimp_layer_tree_view_select_items;
|
||||
iface->set_view_size = gimp_layer_tree_view_set_view_size;
|
||||
|
||||
iface->model_is_tree = TRUE;
|
||||
|
@ -608,6 +613,48 @@ gimp_layer_tree_view_select_item (GimpContainerView *view,
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_layer_tree_view_select_items (GimpContainerView *view,
|
||||
GList *items,
|
||||
GList *paths)
|
||||
{
|
||||
GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
|
||||
GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view);
|
||||
GList *layers = items;
|
||||
GList *path = paths;
|
||||
gboolean success;
|
||||
|
||||
success = parent_view_iface->select_items (view, items, paths);
|
||||
|
||||
if (layers)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
for (layers = items, path = paths; layers && path; layers = layers->next, path = path->next)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_tree_model_get_iter (tree_view->model, &iter, path->data);
|
||||
gimp_layer_tree_view_update_borders (layer_view, &iter);
|
||||
gimp_layer_tree_view_update_options (layer_view, GIMP_LAYER (layers->data));
|
||||
gimp_layer_tree_view_update_menu (layer_view, GIMP_LAYER (layers->data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! success)
|
||||
{
|
||||
GimpEditor *editor = GIMP_EDITOR (view);
|
||||
|
||||
/* currently, select_item() only ever fails when there is a floating
|
||||
* selection, which can be committed/canceled through the editor buttons.
|
||||
*/
|
||||
gimp_widget_blink (GTK_WIDGET (gimp_editor_get_button_box (editor)));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint mask_column;
|
||||
|
|
|
@ -372,7 +372,7 @@ gimp_pickable_popup_get_pickable (GimpPickablePopup *popup)
|
|||
GList *selected;
|
||||
|
||||
if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (popup->priv->layer_view),
|
||||
&selected))
|
||||
&selected, NULL))
|
||||
{
|
||||
pickable = selected->data;
|
||||
g_list_free (selected);
|
||||
|
@ -383,7 +383,7 @@ gimp_pickable_popup_get_pickable (GimpPickablePopup *popup)
|
|||
GList *selected;
|
||||
|
||||
if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (popup->priv->channel_view),
|
||||
&selected))
|
||||
&selected, NULL))
|
||||
{
|
||||
pickable = selected->data;
|
||||
g_list_free (selected);
|
||||
|
|
Loading…
Reference in New Issue