diff --git a/app/actions/actions.c b/app/actions/actions.c index 8bb633d327..97ea4d0d17 100644 --- a/app/actions/actions.c +++ b/app/actions/actions.c @@ -490,10 +490,9 @@ action_data_sel_count (gpointer data) { if (GIMP_IS_CONTAINER_EDITOR (data)) { - GimpContainerEditor *editor; + GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data); - editor = GIMP_CONTAINER_EDITOR (data); - return gimp_container_view_get_selected (editor->view, NULL, NULL); + return gimp_container_view_get_selected (editor->view, NULL); } else { diff --git a/app/actions/palettes-commands.c b/app/actions/palettes-commands.c index 2a485c208b..eb07b739d3 100644 --- a/app/actions/palettes-commands.c +++ b/app/actions/palettes-commands.c @@ -117,9 +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, NULL); - - if (g_list_length (selected) < 2) + if (gimp_container_view_get_selected (editor->view, &selected) < 2) { gimp_message_literal (context->gimp, G_OBJECT (editor), GIMP_MESSAGE_WARNING, diff --git a/app/dialogs/layer-add-mask-dialog.c b/app/dialogs/layer-add-mask-dialog.c index 52d97c1910..6c02dcfea9 100644 --- a/app/dialogs/layer-add-mask-dialog.c +++ b/app/dialogs/layer-add-mask-dialog.c @@ -57,14 +57,12 @@ struct _LayerAddMaskDialog /* local function prototypes */ -static void layer_add_mask_dialog_free (LayerAddMaskDialog *private); -static void layer_add_mask_dialog_response (GtkWidget *dialog, - gint response_id, - LayerAddMaskDialog *private); -static gboolean layer_add_mask_dialog_channel_selected (GimpContainerView *view, - GList *viewables, - GList *paths, - LayerAddMaskDialog *private); +static void layer_add_mask_dialog_free (LayerAddMaskDialog *private); +static void layer_add_mask_dialog_response (GtkWidget *dialog, + gint response_id, + LayerAddMaskDialog *private); +static void layer_add_mask_dialog_channel_selected (GimpContainerView *view, + LayerAddMaskDialog *private); /* public functions */ @@ -166,7 +164,7 @@ layer_add_mask_dialog_new (GList *layers, GIMP_ADD_MASK_CHANNEL, TRUE); gtk_widget_show (combo); - g_signal_connect (combo, "select-items", + g_signal_connect (combo, "selection-changed", G_CALLBACK (layer_add_mask_dialog_channel_selected), private); @@ -179,8 +177,8 @@ layer_add_mask_dialog_new (GList *layers, else channel = GIMP_CHANNEL (gimp_container_get_first_child (gimp_image_get_channels (image))); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (combo), - GIMP_VIEWABLE (channel)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (combo), + GIMP_VIEWABLE (channel)); button = gtk_check_button_new_with_mnemonic (_("In_vert mask")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), private->invert); @@ -234,15 +232,9 @@ layer_add_mask_dialog_response (GtkWidget *dialog, } } -static gboolean +static void layer_add_mask_dialog_channel_selected (GimpContainerView *view, - GList *viewables, - GList *paths, LayerAddMaskDialog *private) { - g_return_val_if_fail (g_list_length (viewables) < 2, FALSE); - - private->channel = viewables? GIMP_CHANNEL (viewables->data) : NULL; - - return TRUE; + private->channel = GIMP_CHANNEL (gimp_container_view_get_1_selected (view)); } diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index 46b217181d..80e549f986 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -464,24 +464,20 @@ prefs_path_reset (GtkWidget *widget, gimp_config_reset_property (config, writable_property); } -static gboolean +static void prefs_template_select_callback (GimpContainerView *view, - GList *templates, - GList *paths, GimpTemplate *edit_template) { - g_return_val_if_fail (g_list_length (templates) < 2, FALSE); + GimpViewable *item = gimp_container_view_get_1_selected (view); - if (templates) + if (item) { /* make sure the resolution values are copied first (see bug #546924) */ - gimp_config_sync (G_OBJECT (templates->data), G_OBJECT (edit_template), + gimp_config_sync (G_OBJECT (item), G_OBJECT (edit_template), GIMP_TEMPLATE_PARAM_COPY_FIRST); - gimp_config_sync (G_OBJECT (templates->data), G_OBJECT (edit_template), + gimp_config_sync (G_OBJECT (item), G_OBJECT (edit_template), 0); } - - return TRUE; } static void @@ -1813,9 +1809,9 @@ prefs_dialog_new (Gimp *gimp, _("_Template:"), 0.0, 0.5, combo, 1); - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (combo), NULL); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (combo), NULL); - g_signal_connect (combo, "select-items", + g_signal_connect (combo, "selection-changed", G_CALLBACK (prefs_template_select_callback), core_config->default_image); } diff --git a/app/dialogs/quit-dialog.c b/app/dialogs/quit-dialog.c index 3c18a09260..a36f765fe2 100644 --- a/app/dialogs/quit-dialog.c +++ b/app/dialogs/quit-dialog.c @@ -94,9 +94,7 @@ static void quit_close_all_dialog_accel_marshal (GClosure *c static void quit_close_all_dialog_container_changed (GimpContainer *images, GimpObject *image, QuitDialog *private); -static gboolean quit_close_all_dialog_images_selected (GimpContainerView *view, - GList *images, - GList *paths, +static void quit_close_all_dialog_images_selected (GimpContainerView *view, QuitDialog *private); static void quit_close_all_dialog_name_cell_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, @@ -266,7 +264,7 @@ quit_close_all_dialog_new (Gimp *gimp, gtk_box_pack_start (GTK_BOX (private->box), view, TRUE, TRUE, 0); gtk_widget_show (view); - g_signal_connect (view, "select-items", + g_signal_connect (view, "selection-changed", G_CALLBACK (quit_close_all_dialog_images_selected), private); @@ -443,21 +441,15 @@ quit_close_all_dialog_container_changed (GimpContainer *images, g_free (accel_string); } -static gboolean +static void quit_close_all_dialog_images_selected (GimpContainerView *view, - GList *images, - GList *paths, QuitDialog *private) { - /* The signal allows for multiple selection cases, but this specific - * dialog only allows one image selected at a time. - */ - g_return_val_if_fail (g_list_length (images) <= 1, FALSE); + GimpViewable *image = gimp_container_view_get_1_selected (view); - if (images) + if (image) { - GimpImage *image = images->data; - GList *list; + GList *list; for (list = gimp_get_display_iter (private->gimp); list; @@ -465,7 +457,7 @@ quit_close_all_dialog_images_selected (GimpContainerView *view, { GimpDisplay *display = list->data; - if (gimp_display_get_image (display) == image) + if (gimp_display_get_image (display) == GIMP_IMAGE (image)) { gimp_display_shell_present (gimp_display_get_shell (display)); @@ -476,8 +468,6 @@ quit_close_all_dialog_images_selected (GimpContainerView *view, } } } - - return TRUE; } static void diff --git a/app/dialogs/stroke-dialog.c b/app/dialogs/stroke-dialog.c index 5efcd0253e..2156750af4 100644 --- a/app/dialogs/stroke-dialog.c +++ b/app/dialogs/stroke-dialog.c @@ -276,8 +276,8 @@ stroke_dialog_response (GtkWidget *dialog, gimp_config_reset (GIMP_CONFIG (private->options)); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (private->tool_combo), - GIMP_VIEWABLE (tool_info->paint_info)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (private->tool_combo), + GIMP_VIEWABLE (tool_info->paint_info)); } break; diff --git a/app/tools/gimpbucketfilloptions.c b/app/tools/gimpbucketfilloptions.c index 3753aa96ce..2a5303c6f5 100644 --- a/app/tools/gimpbucketfilloptions.c +++ b/app/tools/gimpbucketfilloptions.c @@ -103,10 +103,7 @@ static void gimp_bucket_fill_options_get_property (GObject guint property_id, GValue *value, GParamSpec *pspec); -static gboolean - gimp_bucket_fill_options_select_stroke_tool (GimpContainerView *view, - GList *items, - GList *paths, +static void gimp_bucket_fill_options_select_stroke_tool (GimpContainerView *view, GimpBucketFillOptions *options); static void gimp_bucket_fill_options_tool_cell_renderer (GtkCellLayout *layout, GtkCellRenderer *cell, @@ -481,24 +478,15 @@ gimp_bucket_fill_options_get_property (GObject *object, } } -static gboolean +static void gimp_bucket_fill_options_select_stroke_tool (GimpContainerView *view, - GList *items, - GList *paths, GimpBucketFillOptions *options) { - GList *iter; + GimpViewable *item = gimp_container_view_get_1_selected (view); - for (iter = items; iter; iter = iter->next) - { - g_object_set (options, - "line-art-stroke-tool", - iter->data ? gimp_object_get_name (iter->data) : NULL, - NULL); - break; - } - - return TRUE; + g_object_set (options, + "line-art-stroke-tool", item, + NULL); } static void @@ -851,7 +839,7 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options) GIMP_CONTAINER_COMBO_BOX (widget)->viewable_renderer, gimp_bucket_fill_options_tool_cell_renderer, options, NULL); - g_signal_connect (widget, "select-items", + g_signal_connect (widget, "selection-changed", G_CALLBACK (gimp_bucket_fill_options_select_stroke_tool), options); diff --git a/app/widgets/gimpcontainerbox.c b/app/widgets/gimpcontainerbox.c index 1699412665..7c65cc40c7 100644 --- a/app/widgets/gimpcontainerbox.c +++ b/app/widgets/gimpcontainerbox.c @@ -69,10 +69,10 @@ gimp_container_box_class_init (GimpContainerBoxClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = gimp_container_box_constructed; - object_class->set_property = gimp_container_view_set_property; - object_class->get_property = gimp_container_view_get_property; + object_class->set_property = _gimp_container_view_set_property; + object_class->get_property = _gimp_container_view_get_property; - gimp_container_view_install_properties (object_class); + _gimp_container_view_install_properties (object_class); } static void diff --git a/app/widgets/gimpcontainercombobox.c b/app/widgets/gimpcontainercombobox.c index 1b07cdc1ad..38fddc5738 100644 --- a/app/widgets/gimpcontainercombobox.c +++ b/app/widgets/gimpcontainercombobox.c @@ -60,6 +60,13 @@ static void gimp_container_combo_box_get_property (GObject *o static void gimp_container_combo_box_set_context (GimpContainerView *view, GimpContext *context); +static void gimp_container_combo_box_set_view_size (GimpContainerView *view); +static gboolean + gimp_container_combo_box_set_selected (GimpContainerView *view, + GList *items); +static gint gimp_container_combo_box_get_selected (GimpContainerView *view, + GList **items); + static gpointer gimp_container_combo_box_insert_item (GimpContainerView *view, GimpViewable *viewable, gpointer parent_insert_data, @@ -74,14 +81,7 @@ static void gimp_container_combo_box_reorder_item (GimpContainerView *v static void gimp_container_combo_box_rename_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); -static gboolean gimp_container_combo_box_select_items(GimpContainerView *view, - GList *viewables, - GList *paths); static void gimp_container_combo_box_clear_items (GimpContainerView *view); -static void gimp_container_combo_box_set_view_size (GimpContainerView *view); -static gint gimp_container_combo_box_get_selected (GimpContainerView *view, - GList **items, - GList **items_data); static void gimp_container_combo_box_changed (GtkComboBox *combo_box, GimpContainerView *view); @@ -105,7 +105,7 @@ gimp_container_combo_box_class_init (GimpContainerComboBoxClass *klass) object_class->set_property = gimp_container_combo_box_set_property; object_class->get_property = gimp_container_combo_box_get_property; - gimp_container_view_install_properties (object_class); + _gimp_container_view_install_properties (object_class); g_object_class_install_property (object_class, PROP_ELLIPSIZE, @@ -125,14 +125,15 @@ gimp_container_combo_box_view_iface_init (GimpContainerViewInterface *iface) parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW); iface->set_context = gimp_container_combo_box_set_context; + iface->set_view_size = gimp_container_combo_box_set_view_size; + iface->set_selected = gimp_container_combo_box_set_selected; + iface->get_selected = gimp_container_combo_box_get_selected; + iface->insert_item = gimp_container_combo_box_insert_item; iface->remove_item = gimp_container_combo_box_remove_item; iface->reorder_item = gimp_container_combo_box_reorder_item; iface->rename_item = gimp_container_combo_box_rename_item; - iface->select_items = gimp_container_combo_box_select_items; iface->clear_items = gimp_container_combo_box_clear_items; - iface->set_view_size = gimp_container_combo_box_set_view_size; - iface->get_selected = gimp_container_combo_box_get_selected; iface->insert_data_free = (GDestroyNotify) gtk_tree_iter_free; } @@ -205,7 +206,7 @@ gimp_container_combo_box_set_property (GObject *object, break; default: - gimp_container_view_set_property (object, property_id, value, pspec); + _gimp_container_view_set_property (object, property_id, value, pspec); break; } } @@ -226,7 +227,7 @@ gimp_container_combo_box_get_property (GObject *object, break; default: - gimp_container_view_get_property (object, property_id, value, pspec); + _gimp_container_view_get_property (object, property_id, value, pspec); break; } } @@ -275,6 +276,92 @@ gimp_container_combo_box_set_context (GimpContainerView *view, context); } +static void +gimp_container_combo_box_set_view_size (GimpContainerView *view) +{ + GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); + + if (model) + gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (model)); +} + +static gboolean +gimp_container_combo_box_set_selected (GimpContainerView *view, + GList *viewables) +{ + GtkComboBox *combo_box = GTK_COMBO_BOX (view); + + /* Only zero or one items may selected in a GimpContainerComboBox. */ + g_return_val_if_fail (g_list_length (viewables) < 2, FALSE); + + if (gtk_combo_box_get_model (GTK_COMBO_BOX (view))) + { + if (viewables) + { + GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); + GtkTreeIter iter; + gboolean iter_valid; + + for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); + iter_valid; + iter_valid = gtk_tree_model_iter_next (model, &iter)) + { + GimpViewRenderer *renderer; + + gtk_tree_model_get (model, &iter, + GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, + -1); + + if (renderer->viewable == viewables->data) + { + gtk_combo_box_set_active_iter (combo_box, &iter); + g_object_unref (renderer); + + break; + } + + g_object_unref (renderer); + } + } + else + { + gtk_combo_box_set_active (combo_box, -1); + } + } + + return TRUE; +} + +static gint +gimp_container_combo_box_get_selected (GimpContainerView *view, + GList **items) +{ + GtkComboBox *combo_box = GTK_COMBO_BOX (view); + GtkTreeIter iter; + gint selected = 0; + + if (gtk_combo_box_get_active_iter (combo_box, &iter)) + { + GimpViewRenderer *renderer; + + gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter, + GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, + -1); + + if (renderer && renderer->viewable) + { + selected = 1; + + if (items) + *items = g_list_prepend (NULL, renderer->viewable); + } + + g_clear_object (&renderer); + } + + return selected; +} + static gpointer gimp_container_combo_box_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -356,62 +443,6 @@ gimp_container_combo_box_rename_item (GimpContainerView *view, insert_data); } -static gboolean -gimp_container_combo_box_select_items (GimpContainerView *view, - GList *viewables, - GList *paths) -{ - GtkComboBox *combo_box = GTK_COMBO_BOX (view); - - g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE); - /* Only zero or one items may selected in a GimpContainerComboBox. */ - g_return_val_if_fail (g_list_length (viewables) < 2, FALSE); - - if (gtk_combo_box_get_model (GTK_COMBO_BOX (view))) - { - g_signal_handlers_block_by_func (combo_box, - gimp_container_combo_box_changed, - view); - - if (viewables) - { - GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); - GtkTreeIter iter; - gboolean iter_valid; - - for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); - iter_valid; - iter_valid = gtk_tree_model_iter_next (model, &iter)) - { - GimpViewRenderer *renderer; - - gtk_tree_model_get (model, &iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - if (renderer->viewable == viewables->data) - { - gtk_combo_box_set_active_iter (combo_box, &iter); - g_object_unref (renderer); - - break; - } - g_object_unref (renderer); - } - } - else - { - gtk_combo_box_set_active (combo_box, -1); - } - - g_signal_handlers_unblock_by_func (combo_box, - gimp_container_combo_box_changed, - view); - } - - return TRUE; -} - static void gimp_container_combo_box_clear_items (GimpContainerView *view) { @@ -425,62 +456,9 @@ gimp_container_combo_box_clear_items (GimpContainerView *view) parent_view_iface->clear_items (view); } -static void -gimp_container_combo_box_set_view_size (GimpContainerView *view) -{ - GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (view)); - - if (model) - gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (model)); -} - -static gint -gimp_container_combo_box_get_selected (GimpContainerView *view, - GList **items, - GList **items_data) -{ - GtkComboBox *combo_box = GTK_COMBO_BOX (view); - GimpViewRenderer *renderer = NULL; - GtkTreeIter iter; - gint selected = 0; - - if (gtk_combo_box_get_active_iter (combo_box, &iter)) - gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - if (items) - { - if (renderer != NULL && renderer->viewable != NULL) - { - *items = g_list_prepend (NULL, renderer->viewable); - selected = 1; - } - else - { - *items = NULL; - } - } - g_clear_object (&renderer); - - return selected; -} - static void gimp_container_combo_box_changed (GtkComboBox *combo, GimpContainerView *view) { - GtkTreeIter iter; - - if (gtk_combo_box_get_active_iter (combo, &iter)) - { - GimpViewRenderer *renderer; - - gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - gimp_container_view_item_selected (view, renderer->viewable); - g_object_unref (renderer); - } + _gimp_container_view_selection_changed (view); } diff --git a/app/widgets/gimpcontainereditor.c b/app/widgets/gimpcontainereditor.c index 3df0539de8..aedc04ae1d 100644 --- a/app/widgets/gimpcontainereditor.c +++ b/app/widgets/gimpcontainereditor.c @@ -85,13 +85,10 @@ static void gimp_container_editor_get_property (GObject *objec GValue *value, GParamSpec *pspec); -static gboolean gimp_container_editor_select_items (GimpContainerView *view, - GList *items, - GList *paths, +static void gimp_container_editor_selection_changed(GimpContainerView *view, GimpContainerEditor *editor); -static void gimp_container_editor_activate_item (GtkWidget *widget, +static void gimp_container_editor_item_activated (GtkWidget *widget, GimpViewable *viewable, - gpointer insert_data, GimpContainerEditor *editor); static GtkWidget * gimp_container_editor_get_preview (GimpDocked *docked, @@ -273,33 +270,13 @@ gimp_container_editor_constructed (GObject *object) editor->view, "visible", G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); - /* Connect "select-items" with G_CONNECT_AFTER because it's a - * RUN_LAST signal and the default handler selecting the row must - * run before signal connections. See bug #784176. - */ - g_signal_connect_object (editor->view, "select-items", - G_CALLBACK (gimp_container_editor_select_items), - editor, G_CONNECT_AFTER); - - g_signal_connect_object (editor->view, "activate-item", - G_CALLBACK (gimp_container_editor_activate_item), + g_signal_connect_object (editor->view, "selection-changed", + G_CALLBACK (gimp_container_editor_selection_changed), editor, 0); - /* g_signal_connect_object (editor->view, "context-item", XXX maybe listen to popup-menu? */ - /* G_CALLBACK (gimp_container_editor_context_item), */ - /* editor, 0); */ - { - GList *objects = NULL; - GimpObject *object = gimp_context_get_by_type (editor->priv->context, - gimp_container_get_child_type (editor->priv->container)); - - if (object) - objects = g_list_prepend (objects, object); - - gimp_container_editor_select_items (editor->view, objects, NULL, editor); - - g_list_free (objects); - } + g_signal_connect_object (editor->view, "item-activated", + G_CALLBACK (gimp_container_editor_item_activated), + editor, 0); } static void @@ -429,22 +406,25 @@ gimp_container_editor_set_selection_mode (GimpContainerEditor *editor, mode); } + /* private functions */ -static gboolean -gimp_container_editor_select_items (GimpContainerView *view, - GList *items, - GList *paths, - GimpContainerEditor *editor) +static void +gimp_container_editor_selection_changed (GimpContainerView *view, + GimpContainerEditor *editor) { GimpContainerEditorClass *klass = GIMP_CONTAINER_EDITOR_GET_CLASS (editor); GimpViewable *viewable = NULL; GimpEditor *editor_view = NULL; + GList *items; + + gimp_container_view_get_selected (view, &items); /* XXX Right now a GimpContainerEditor only supports 1 item selected * at once. Let's see later if we want to allow more. + * + * g_warn_if_fail (n_items < 2); */ - /*g_return_val_if_fail (g_list_length (items) < 2, FALSE);*/ /* The editor view may get destroyed through a chain of signals when * changing the context viewables with gimp_context_set_by_type(). @@ -459,19 +439,6 @@ gimp_container_editor_select_items (GimpContainerView *view, if (klass->select_item) klass->select_item (editor, viewable); - if (editor->priv->container) - { - const gchar *signal_name; - GType child_type; - - child_type = gimp_container_get_child_type (editor->priv->container); - signal_name = gimp_context_type_to_signal_name (child_type); - - if (signal_name) - gimp_context_set_by_type (editor->priv->context, child_type, - GIMP_OBJECT (viewable)); - } - if (viewable && editor_view) { gchar *desc = gimp_viewable_get_description (viewable, NULL); @@ -486,14 +453,13 @@ gimp_container_editor_select_items (GimpContainerView *view, g_clear_weak_pointer (&editor_view); - return TRUE; + g_list_free (items); } static void -gimp_container_editor_activate_item (GtkWidget *widget, - GimpViewable *viewable, - gpointer insert_data, - GimpContainerEditor *editor) +gimp_container_editor_item_activated (GtkWidget *widget, + GimpViewable *viewable, + GimpContainerEditor *editor) { GimpContainerEditorClass *klass = GIMP_CONTAINER_EDITOR_GET_CLASS (editor); diff --git a/app/widgets/gimpcontainerentry.c b/app/widgets/gimpcontainerentry.c index 1c060c596e..8343ec707b 100644 --- a/app/widgets/gimpcontainerentry.c +++ b/app/widgets/gimpcontainerentry.c @@ -46,6 +46,12 @@ static void gimp_container_entry_finalize (GObject *objec static void gimp_container_entry_set_context (GimpContainerView *view, GimpContext *context); +static void gimp_container_entry_set_view_size(GimpContainerView *view); +static gboolean gimp_container_entry_set_selected (GimpContainerView *view, + GList *items); +static gint gimp_container_entry_get_selected (GimpContainerView *view, + GList **items); + static gpointer gimp_container_entry_insert_item (GimpContainerView *view, GimpViewable *viewable, gpointer parent_insert_data, @@ -60,14 +66,7 @@ static void gimp_container_entry_reorder_item (GimpContainerView *view, static void gimp_container_entry_rename_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); -static gboolean gimp_container_entry_select_items(GimpContainerView *view, - GList *items, - GList *paths); static void gimp_container_entry_clear_items (GimpContainerView *view); -static void gimp_container_entry_set_view_size (GimpContainerView *view); -static gint gimp_container_entry_get_selected (GimpContainerView *view, - GList **items, - GList **items_data); static void gimp_container_entry_changed (GtkEntry *entry, GimpContainerView *view); @@ -92,11 +91,11 @@ gimp_container_entry_class_init (GimpContainerEntryClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->set_property = gimp_container_view_set_property; - object_class->get_property = gimp_container_view_get_property; + object_class->set_property = _gimp_container_view_set_property; + object_class->get_property = _gimp_container_view_get_property; object_class->finalize = gimp_container_entry_finalize; - gimp_container_view_install_properties (object_class); + _gimp_container_view_install_properties (object_class); } static void @@ -108,14 +107,15 @@ gimp_container_entry_view_iface_init (GimpContainerViewInterface *iface) parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW); iface->set_context = gimp_container_entry_set_context; + iface->set_view_size = gimp_container_entry_set_view_size; + iface->set_selected = gimp_container_entry_set_selected; + iface->get_selected = gimp_container_entry_get_selected; + iface->insert_item = gimp_container_entry_insert_item; iface->remove_item = gimp_container_entry_remove_item; iface->reorder_item = gimp_container_entry_reorder_item; iface->rename_item = gimp_container_entry_rename_item; - iface->select_items = gimp_container_entry_select_items; iface->clear_items = gimp_container_entry_clear_items; - iface->set_view_size = gimp_container_entry_set_view_size; - iface->get_selected = gimp_container_entry_get_selected; iface->insert_data_free = (GDestroyNotify) gtk_tree_iter_free; } @@ -242,6 +242,64 @@ gimp_container_entry_set_context (GimpContainerView *view, context); } +static void +gimp_container_entry_set_view_size (GimpContainerView *view) +{ + GtkTreeModel *model = gimp_container_entry_get_model (view); + + gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (model)); +} + +static gboolean +gimp_container_entry_set_selected (GimpContainerView *view, + GList *viewables) +{ + GimpContainerEntry *container_entry = GIMP_CONTAINER_ENTRY (view); + GtkEntry *entry = GTK_ENTRY (view); + GimpViewable *viewable = NULL; + + /* XXX Only support 1 selected viewable for now. */ + if (viewables) + viewable = viewables->data; + + g_set_weak_pointer (&container_entry->viewable, viewable); + + if (viewable) + { + gtk_entry_set_icon_from_icon_name (entry, + GTK_ENTRY_ICON_SECONDARY, + NULL); + } + else + { + /* The selected item does not exist. */ + gtk_entry_set_icon_from_icon_name (entry, + GTK_ENTRY_ICON_SECONDARY, + GIMP_ICON_WILBER_EEK); + } + + gtk_entry_set_text (entry, viewable ? gimp_object_get_name (viewable) : ""); + + return TRUE; +} + +static gint +gimp_container_entry_get_selected (GimpContainerView *view, + GList **items) +{ + GimpContainerEntry *container_entry = GIMP_CONTAINER_ENTRY (view); + + if (items) + { + if (container_entry->viewable) + *items = g_list_prepend (NULL, container_entry->viewable); + else + *items = NULL; + } + + return container_entry->viewable ? 1 : 0; +} + static gpointer gimp_container_entry_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -309,48 +367,6 @@ gimp_container_entry_rename_item (GimpContainerView *view, insert_data); } -static gboolean -gimp_container_entry_select_items (GimpContainerView *view, - GList *viewables, - GList *paths) -{ - GimpContainerEntry *container_entry = GIMP_CONTAINER_ENTRY (view); - GtkEntry *entry = GTK_ENTRY (view); - GimpViewable *viewable = NULL; - - /* XXX Only support 1 selected viewable for now. */ - if (viewables) - viewable = viewables->data; - - g_signal_handlers_block_by_func (entry, - gimp_container_entry_changed, - view); - - g_set_weak_pointer (&container_entry->viewable, viewable); - - if (viewable) - { - gtk_entry_set_icon_from_icon_name (entry, - GTK_ENTRY_ICON_SECONDARY, - NULL); - } - else - { - /* The selected item does not exist. */ - gtk_entry_set_icon_from_icon_name (entry, - GTK_ENTRY_ICON_SECONDARY, - GIMP_ICON_WILBER_EEK); - } - - gtk_entry_set_text (entry, viewable? gimp_object_get_name (viewable) : ""); - - g_signal_handlers_unblock_by_func (entry, - gimp_container_entry_changed, - view); - - return TRUE; -} - static void gimp_container_entry_clear_items (GimpContainerView *view) { @@ -363,32 +379,6 @@ gimp_container_entry_clear_items (GimpContainerView *view) parent_view_iface->clear_items (view); } -static void -gimp_container_entry_set_view_size (GimpContainerView *view) -{ - GtkTreeModel *model = gimp_container_entry_get_model (view); - - gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (model)); -} - -static gint -gimp_container_entry_get_selected (GimpContainerView *view, - GList **items, - GList **items_data) -{ - GimpContainerEntry *container_entry = GIMP_CONTAINER_ENTRY (view); - - if (items) - { - if (container_entry->viewable != NULL) - *items = g_list_prepend (NULL, container_entry->viewable); - else - *items = NULL; - } - - return container_entry->viewable == NULL ? 0 : 1; -} - static void gimp_container_entry_changed (GtkEntry *entry, GimpContainerView *view) @@ -406,10 +396,10 @@ gimp_container_entry_changed (GtkEntry *entry, g_set_weak_pointer (&container_entry->viewable, GIMP_VIEWABLE (object)); + _gimp_container_view_selection_changed (view); + if (container_entry->viewable) { - gimp_container_view_item_selected (view, container_entry->viewable); - gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL); @@ -429,12 +419,5 @@ gimp_container_entry_match_selected (GtkEntryCompletion *widget, GtkTreeIter *iter, GimpContainerView *view) { - GimpViewRenderer *renderer; - - gtk_tree_model_get (model, iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - gimp_container_view_item_selected (view, renderer->viewable); - g_object_unref (renderer); + _gimp_container_view_selection_changed (view); } diff --git a/app/widgets/gimpcontainericonview.c b/app/widgets/gimpcontainericonview.c index 556f7ab7e0..06b8216b95 100644 --- a/app/widgets/gimpcontainericonview.c +++ b/app/widgets/gimpcontainericonview.c @@ -65,6 +65,11 @@ static void gimp_container_icon_view_set_context (GimpContainerVi GimpContext *context); static void gimp_container_icon_view_set_selection_mode(GimpContainerView *view, GtkSelectionMode mode); +static void gimp_container_icon_view_set_view_size (GimpContainerView *view); +static gboolean gimp_container_icon_view_set_selected (GimpContainerView *view, + GList *items); +static gint gimp_container_icon_view_get_selected (GimpContainerView *view, + GList **items); static gpointer gimp_container_icon_view_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -80,11 +85,8 @@ static void gimp_container_icon_view_reorder_item (GimpContainerVi static void gimp_container_icon_view_rename_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); -static gboolean gimp_container_icon_view_select_items (GimpContainerView *view, - GList *items, - GList *paths); static void gimp_container_icon_view_clear_items (GimpContainerView *view); -static void gimp_container_icon_view_set_view_size (GimpContainerView *view); + static void gimp_container_icon_view_invalidate (GimpContainerIconView *view); static void gimp_container_icon_view_selection_changed (GtkIconView *view, @@ -105,15 +107,12 @@ static gboolean gimp_container_icon_view_tooltip (GtkWidget static GimpViewable * gimp_container_icon_view_drag_viewable (GtkWidget *widget, GimpContext **context, gpointer data); -static GdkPixbuf * gimp_container_icon_view_drag_pixbuf (GtkWidget *widget, - 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, - GList **paths); +static GdkPixbuf * gimp_container_icon_view_drag_pixbuf (GtkWidget *widget, + gpointer data); +static gboolean gimp_container_icon_view_get_1_selected (GimpContainerIconView *icon_view, + GtkTreeIter *iter); -static void gimp_container_icon_view_trigger_redraw (GimpContainerIconView *view); +static void gimp_container_icon_view_trigger_redraw (GimpContainerIconView *view); G_DEFINE_TYPE_WITH_CODE (GimpContainerIconView, gimp_container_icon_view, @@ -153,14 +152,15 @@ gimp_container_icon_view_view_iface_init (GimpContainerViewInterface *iface) iface->set_container = gimp_container_icon_view_set_container; iface->set_context = gimp_container_icon_view_set_context; iface->set_selection_mode = gimp_container_icon_view_set_selection_mode; + iface->set_view_size = gimp_container_icon_view_set_view_size; + iface->set_selected = gimp_container_icon_view_set_selected; + iface->get_selected = gimp_container_icon_view_get_selected; + iface->insert_item = gimp_container_icon_view_insert_item; iface->remove_item = gimp_container_icon_view_remove_item; iface->reorder_item = gimp_container_icon_view_reorder_item; iface->rename_item = gimp_container_icon_view_rename_item; - iface->select_items = gimp_container_icon_view_select_items; iface->clear_items = gimp_container_icon_view_clear_items; - iface->set_view_size = gimp_container_icon_view_set_view_size; - iface->get_selected = gimp_container_icon_view_get_selected; iface->insert_data_free = (GDestroyNotify) gtk_tree_iter_free; } @@ -259,7 +259,7 @@ gimp_container_icon_view_popup_menu (GtkWidget *widget) GtkTreePath *path; GdkRectangle rect; - if (!gimp_container_icon_view_get_selected_single (icon_view, &iter)) + if (! gimp_container_icon_view_get_1_selected (icon_view, &iter)) return FALSE; path = gtk_tree_model_get_path (icon_view->model, &iter); @@ -377,10 +377,11 @@ gimp_container_icon_view_set_context (GimpContainerView *view, if (context != NULL) { if (icon_view->priv->color_scheme_handler_id == 0) - icon_view->priv->color_scheme_handler_id = g_signal_connect_object (context->gimp->config, - "notify::theme-color-scheme", - G_CALLBACK (gimp_container_icon_view_trigger_redraw), - icon_view, G_CONNECT_SWAPPED); + icon_view->priv->color_scheme_handler_id = + g_signal_connect_object (context->gimp->config, + "notify::theme-color-scheme", + G_CALLBACK (gimp_container_icon_view_trigger_redraw), + icon_view, G_CONNECT_SWAPPED); } } @@ -395,6 +396,136 @@ gimp_container_icon_view_set_selection_mode (GimpContainerView *view, parent_view_iface->set_selection_mode (view, mode); } +static void +gimp_container_icon_view_set_view_size (GimpContainerView *view) +{ + GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); + + if (icon_view->model) + gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (icon_view->model)); + + if (icon_view->view) + { + gtk_icon_view_set_columns (icon_view->view, -1); + gtk_icon_view_set_item_width (icon_view->view, -1); + + /* ugly workaround to force the icon view to invalidate all its + * cached icon sizes + */ + gtk_icon_view_set_item_orientation (icon_view->view, + GTK_ORIENTATION_VERTICAL); + gtk_icon_view_set_item_orientation (icon_view->view, + GTK_ORIENTATION_HORIZONTAL); + } +} + +static gboolean +gimp_container_icon_view_set_selected (GimpContainerView *view, + GList *items) +{ + GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); + GList *list; + + if (items) + { + GList *paths = NULL; + + for (list = items; list; list = g_list_next (list)) + { + GtkTreeIter *iter; + GtkTreePath *path; + + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), + list->data); + if (! iter) + /* This may happen when the GimpContainerIconView only + * shows a subpart of the whole icons. We don't select + * what is not shown. + */ + continue; + + path = gtk_tree_model_get_path (icon_view->model, iter); + + paths = g_list_prepend (paths, path); + } + + paths = g_list_reverse (paths); + + g_signal_handlers_block_by_func (icon_view->view, + gimp_container_icon_view_selection_changed, + icon_view); + + gtk_icon_view_unselect_all (icon_view->view); + + for (list = paths; list; list = g_list_next (list)) + { + gtk_icon_view_select_path (icon_view->view, list->data); + } + + if (paths) + { + gtk_icon_view_set_cursor (icon_view->view, paths->data, NULL, FALSE); + gtk_icon_view_scroll_to_path (icon_view->view, paths->data, + FALSE, 0.0, 0.0); + } + + g_signal_handlers_unblock_by_func (icon_view->view, + gimp_container_icon_view_selection_changed, + icon_view); + + g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); + + _gimp_container_view_selection_changed (GIMP_CONTAINER_VIEW (icon_view)); + } + else + { + gtk_icon_view_unselect_all (icon_view->view); + } + + return TRUE; +} + +static gint +gimp_container_icon_view_get_selected (GimpContainerView *view, + GList **items) +{ + GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); + GList *paths; + gint n_selected; + + paths = gtk_icon_view_get_selected_items (icon_view->view); + n_selected = g_list_length (paths); + + if (items) + { + GList *list; + + for (list = paths; list; list = g_list_next (list)) + { + GtkTreeIter iter; + GimpViewRenderer *renderer; + + gtk_tree_model_get_iter (GTK_TREE_MODEL (icon_view->model), &iter, + (GtkTreePath *) list->data); + + gtk_tree_model_get (icon_view->model, &iter, + GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, + -1); + + if (renderer->viewable) + *items = g_list_prepend (*items, renderer->viewable); + + g_object_unref (renderer); + } + + *items = g_list_reverse (*items); + } + + g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); + + return n_selected; +} + static gpointer gimp_container_icon_view_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -449,8 +580,8 @@ gimp_container_icon_view_reorder_item (GimpContainerView *view, { GtkTreeIter selected_iter; - selected = gimp_container_icon_view_get_selected_single (icon_view, - &selected_iter); + selected = gimp_container_icon_view_get_1_selected (icon_view, + &selected_iter); if (selected) { @@ -473,7 +604,7 @@ gimp_container_icon_view_reorder_item (GimpContainerView *view, iter); if (selected) - gimp_container_view_select_item (view, viewable); + gimp_container_view_set_1_selected (view, viewable); } static void @@ -489,75 +620,6 @@ gimp_container_icon_view_rename_item (GimpContainerView *view, iter); } -static gboolean -gimp_container_icon_view_select_items (GimpContainerView *view, - GList *viewables, - GList *paths) -{ - GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); - GList *list; - - if (viewables) - { - gboolean free_paths = FALSE; - - if (g_list_length (paths) != g_list_length (viewables)) - { - free_paths = TRUE; - paths = NULL; - for (list = viewables; list; list = list->next) - { - GtkTreeIter *iter; - GtkTreePath *path; - - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), - list->data); - if (! iter) - /* This may happen when the GimpContainerIconView only - * shows a subpart of the whole icons. We don't select - * what is not shown. - */ - continue; - - path = gtk_tree_model_get_path (icon_view->model, iter); - - paths = g_list_prepend (paths, path); - } - paths = g_list_reverse (paths); - } - - g_signal_handlers_block_by_func (icon_view->view, - gimp_container_icon_view_selection_changed, - icon_view); - - gtk_icon_view_unselect_all (icon_view->view); - - for (list = paths; list; list = list->next) - { - gtk_icon_view_select_path (icon_view->view, list->data); - } - - if (list) - { - gtk_icon_view_set_cursor (icon_view->view, list->data, NULL, FALSE); - gtk_icon_view_scroll_to_path (icon_view->view, list->data, FALSE, 0.0, 0.0); - } - - g_signal_handlers_unblock_by_func (icon_view->view, - gimp_container_icon_view_selection_changed, - icon_view); - - if (free_paths) - g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); - } - else - { - gtk_icon_view_unselect_all (icon_view->view); - } - - return TRUE; -} - static void gimp_container_icon_view_clear_items (GimpContainerView *view) { @@ -568,29 +630,6 @@ gimp_container_icon_view_clear_items (GimpContainerView *view) parent_view_iface->clear_items (view); } -static void -gimp_container_icon_view_set_view_size (GimpContainerView *view) -{ - GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); - - if (icon_view->model) - gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (icon_view->model)); - - if (icon_view->view) - { - gtk_icon_view_set_columns (icon_view->view, -1); - gtk_icon_view_set_item_width (icon_view->view, -1); - - /* ugly workaround to force the icon view to invalidate all its - * cached icon sizes - */ - gtk_icon_view_set_item_orientation (icon_view->view, - GTK_ORIENTATION_VERTICAL); - gtk_icon_view_set_item_orientation (icon_view->view, - GTK_ORIENTATION_HORIZONTAL); - } -} - static void gimp_container_icon_view_invalidate (GimpContainerIconView *view) { @@ -620,35 +659,7 @@ static void gimp_container_icon_view_selection_changed (GtkIconView *gtk_icon_view, GimpContainerIconView *icon_view) { - GimpContainerView *view = GIMP_CONTAINER_VIEW (icon_view); - GList *items = NULL; - GList *paths; - GList *list; - - paths = gtk_icon_view_get_selected_items (icon_view->view); - - for (list = paths; list; list = list->next) - { - GtkTreeIter iter; - GimpViewRenderer *renderer; - - gtk_tree_model_get_iter (GTK_TREE_MODEL (icon_view->model), &iter, - (GtkTreePath *) list->data); - - gtk_tree_model_get (icon_view->model, &iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - if (renderer->viewable) - items = g_list_prepend (items, renderer->viewable); - - g_object_unref (renderer); - } - - gimp_container_view_multi_selected (view, items, paths); - - g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); - g_list_free (items); + _gimp_container_view_selection_changed (GIMP_CONTAINER_VIEW (icon_view)); } static void @@ -665,8 +676,8 @@ gimp_container_icon_view_item_activated (GtkIconView *view, GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, -1); - gimp_container_view_item_activated (GIMP_CONTAINER_VIEW (icon_view), - renderer->viewable); + _gimp_container_view_item_activated (GIMP_CONTAINER_VIEW (icon_view), + renderer->viewable); g_object_unref (renderer); } @@ -704,11 +715,16 @@ gimp_container_icon_view_button_press (GtkWidget *widget, * selection. Otherwise, we use the current selection. This * allows to not break multiple selection when right-clicking. */ - if (! gimp_container_view_is_item_selected (container_view, renderer->viewable)) - gimp_container_view_item_selected (container_view, renderer->viewable); + if (! gimp_container_view_is_item_selected (container_view, + renderer->viewable)) + { + gimp_container_view_set_1_selected (container_view, + renderer->viewable); + } /* Show the context menu. */ - handled = gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), (GdkEvent *) bevent); + handled = gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), + (GdkEvent *) bevent); } /* Else LMB down or similar. Propagate. */ @@ -721,7 +737,8 @@ gimp_container_icon_view_button_press (GtkWidget *widget, /* Button down outside any item. */ if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - (void) gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), (GdkEvent *) bevent); + (void) gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (icon_view), + (GdkEvent *) bevent); /* Discard result. Does not actually popup menu except for managed views, e.g. dockable. */ } @@ -864,8 +881,8 @@ gimp_container_icon_view_drag_pixbuf (GtkWidget *widget, } static gboolean -gimp_container_icon_view_get_selected_single (GimpContainerIconView *icon_view, - GtkTreeIter *iter) +gimp_container_icon_view_get_1_selected (GimpContainerIconView *icon_view, + GtkTreeIter *iter) { GList *selected_items; gboolean retval; @@ -875,7 +892,7 @@ gimp_container_icon_view_get_selected_single (GimpContainerIconView *icon_view, if (g_list_length (selected_items) == 1) { gtk_tree_model_get_iter (GTK_TREE_MODEL (icon_view->model), iter, - (GtkTreePath *) selected_items->data); + selected_items->data); retval = TRUE; } @@ -889,106 +906,6 @@ gimp_container_icon_view_get_selected_single (GimpContainerIconView *icon_view, return retval; } -static gint -gimp_container_icon_view_get_selected (GimpContainerView *view, - GList **items, - GList **paths) -{ - GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view); - GList *selected_paths; - gint selected_count; - GimpContainer *container; - - container = gimp_container_view_get_container (view); - - if (container) - { - const gchar *signal_name; - GimpContext *context; - GType child_type; - - context = gimp_container_view_get_context (view); - child_type = gimp_container_get_child_type (container); - signal_name = gimp_context_type_to_signal_name (child_type); - - /* As a special case, for containers tied to a context object, we - * look up this object as being selected. - * */ - if (signal_name && context) - { - GimpObject *object; - - object = gimp_context_get_by_type (context, child_type); - - selected_count = object ? 1 : 0; - if (items) - { - if (object) - *items = g_list_prepend (NULL, object); - else - *items = NULL; - } - if (paths) - *paths = NULL; - - return selected_count; - } - } - - 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_paths; - list; - list = g_list_next (list)) - { - GtkTreeIter iter; - GimpViewRenderer *renderer; - - gtk_tree_model_get_iter (GTK_TREE_MODEL (icon_view->model), &iter, - (GtkTreePath *) list->data); - - gtk_tree_model_get (icon_view->model, &iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - - 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); - } - - if (paths) - *paths = selected_paths; - else - g_list_free_full (selected_paths, (GDestroyNotify) gtk_tree_path_free); - - return selected_count; -} - static void gimp_container_icon_view_trigger_redraw (GimpContainerIconView *view) { diff --git a/app/widgets/gimpcontainerpopup.c b/app/widgets/gimpcontainerpopup.c index a93c62f65c..6741b8fd66 100644 --- a/app/widgets/gimpcontainerpopup.c +++ b/app/widgets/gimpcontainerpopup.c @@ -347,15 +347,11 @@ gimp_container_popup_create_view (GimpContainerPopup *popup) if (signal_name) { GimpObject *object; - GList *items = NULL; object = gimp_context_get_by_type (popup->orig_context, child_type); - if (object) - items = g_list_prepend (NULL, object); - gimp_container_view_select_items (popup->editor->view, items); - - g_list_free (items); + gimp_container_view_set_1_selected (popup->editor->view, + GIMP_VIEWABLE (object)); } } diff --git a/app/widgets/gimpcontainertreestore.c b/app/widgets/gimpcontainertreestore.c index 778f097ec9..93fb0eadbb 100644 --- a/app/widgets/gimpcontainertreestore.c +++ b/app/widgets/gimpcontainertreestore.c @@ -630,8 +630,8 @@ gimp_container_tree_store_renderer_update (GimpViewRenderer *renderer, GimpContainerTreeStorePrivate *private = GET_PRIVATE (store); GtkTreeIter *iter; - iter = gimp_container_view_lookup (private->container_view, - renderer->viewable); + iter = _gimp_container_view_lookup (private->container_view, + renderer->viewable); if (iter) { diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c index 7e91685ec6..15b965ff52 100644 --- a/app/widgets/gimpcontainertreeview.c +++ b/app/widgets/gimpcontainertreeview.c @@ -73,6 +73,11 @@ static void gimp_container_tree_view_set_context (GimpContainerVi GimpContext *context); static void gimp_container_tree_view_set_selection_mode(GimpContainerView *view, GtkSelectionMode mode); +static void gimp_container_tree_view_set_view_size (GimpContainerView *view); +static gboolean gimp_container_tree_view_set_selected (GimpContainerView *view, + GList *items); +static gint gimp_container_tree_view_get_selected (GimpContainerView *view, + GList **items); static gpointer gimp_container_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -91,11 +96,7 @@ static void gimp_container_tree_view_rename_item (GimpContainerVi static void gimp_container_tree_view_expand_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); static void gimp_container_tree_view_real_edit_name (GimpContainerTreeView *tree_view); @@ -138,11 +139,8 @@ static void gimp_container_tree_view_zoom_gesture_update (GtkGestureZoo GdkEventSequence *sequence, GimpContainerTreeView *tree_view); -static gboolean gimp_container_tree_view_get_selected_single (GimpContainerTreeView *tree_view, +static gboolean gimp_container_tree_view_get_1_selected (GimpContainerTreeView *tree_view, GtkTreeIter *iter); -static gint gimp_container_tree_view_get_selected (GimpContainerView *view, - GList **items, - GList **paths); static void gimp_container_tree_view_row_expanded (GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, @@ -153,14 +151,6 @@ static void gimp_container_tree_view_expand_rows (GtkTreeModel static void gimp_container_tree_view_monitor_changed (GimpContainerTreeView *view); -static gboolean gimp_container_tree_view_search_path_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data); -static GtkTreePath * gimp_container_tree_view_get_path (GimpContainerTreeView *tree_view, - GimpViewable *viewable); - - G_DEFINE_TYPE_WITH_CODE (GimpContainerTreeView, gimp_container_tree_view, GIMP_TYPE_CONTAINER_BOX, @@ -223,15 +213,16 @@ gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *iface) iface->set_container = gimp_container_tree_view_set_container; iface->set_context = gimp_container_tree_view_set_context; iface->set_selection_mode = gimp_container_tree_view_set_selection_mode; + iface->set_view_size = gimp_container_tree_view_set_view_size; + iface->set_selected = gimp_container_tree_view_set_selected; + iface->get_selected = gimp_container_tree_view_get_selected; + iface->insert_item = gimp_container_tree_view_insert_item; iface->remove_item = gimp_container_tree_view_remove_item; iface->reorder_item = gimp_container_tree_view_reorder_item; iface->rename_item = gimp_container_tree_view_rename_item; iface->expand_item = gimp_container_tree_view_expand_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; iface->insert_data_free = (GDestroyNotify) gtk_tree_iter_free; } @@ -450,7 +441,7 @@ gimp_container_tree_view_popup_menu (GtkWidget *widget) GtkTreePath *path; GdkRectangle rect; - if (!gimp_container_tree_view_get_selected_single (tree_view, &iter)) + if (! gimp_container_tree_view_get_1_selected (tree_view, &iter)) return FALSE; path = gtk_tree_model_get_path (tree_view->model, &iter); @@ -741,6 +732,289 @@ gimp_container_tree_view_set_selection_mode (GimpContainerView *view, parent_view_iface->set_selection_mode (view, mode); } +static void +gimp_container_tree_view_set_view_size (GimpContainerView *view) +{ + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); + GtkWidget *tree_widget; + GList *list; + gint view_size; + gint border_width; + + view_size = gimp_container_view_get_view_size (view, &border_width); + + if (tree_view->model) + gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (tree_view->model)); + + tree_widget = GTK_WIDGET (tree_view->view); + + if (! tree_widget) + return; + + for (list = tree_view->priv->toggle_cells; list; list = g_list_next (list)) + { + gchar *icon_name; + gint icon_size; + + g_object_get (list->data, "icon-name", &icon_name, NULL); + + if (icon_name) + { + GtkStyleContext *style = gtk_widget_get_style_context (tree_widget); + GtkBorder border; + + gtk_style_context_save (style); + gtk_style_context_add_class (style, GTK_STYLE_CLASS_BUTTON); + gtk_style_context_get_border (style, 0, &border); + gtk_style_context_restore (style); + + g_object_get (list->data, "icon-size", &icon_size, NULL); + icon_size = MIN (icon_size, MAX (view_size - (border.left + border.right), + view_size - (border.top + border.bottom))); + g_object_set (list->data, "icon-size", icon_size, NULL); + + g_free (icon_name); + } + } + + gtk_tree_view_columns_autosize (tree_view->view); +} + +static gboolean +gimp_container_tree_view_set_selected (GimpContainerView *view, + GList *items) +{ + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); + GList *item; + GList *paths = NULL; + GList *path; + gboolean scroll_to_first = TRUE; + GtkTreePath *focused_path = NULL; + + for (item = items; item; item = g_list_next (item)) + { + GtkTreeIter *iter = _gimp_container_view_lookup (view, item->data); + GtkTreePath *p; + + if (! iter) + /* This may happen when the view only shows a subpart of the + * whole items. We don't select what is not shown. + */ + continue; + + p = gtk_tree_model_get_path (tree_view->model, iter); + + paths = g_list_prepend (paths, p); + } + + paths = g_list_reverse (paths); + + g_signal_handlers_block_by_func (tree_view->priv->selection, + gimp_container_tree_view_selection_changed, + tree_view); + + gtk_tree_selection_unselect_all (tree_view->priv->selection); + gtk_tree_view_get_cursor (tree_view->view, &focused_path, NULL); + + if (focused_path != NULL) + { + GtkTreePath *closer_up = NULL; + GtkTreePath *closer_down = NULL; + + for (path = paths; path; path = g_list_next (path)) + { + if (gtk_tree_path_compare (path->data, focused_path) == 0) + { + break; + } + else if (gtk_tree_path_compare (path->data, focused_path) == -1) + { + if (closer_up == NULL || + gtk_tree_path_compare (path->data, closer_up) == 1) + { + closer_up = path->data; + } + } + else + { + if (closer_down == NULL || + gtk_tree_path_compare (path->data, closer_down) == -1) + { + closer_down = path->data; + } + } + } + + if (path == NULL) + { + /* The current cursor is not part of the selection. This may + * happen in particular with a ctrl-click interaction which + * would deselect the item the cursor is now on. + */ + g_clear_pointer (&focused_path, gtk_tree_path_free); + + if (closer_up != NULL || closer_down != NULL) + { + GtkTreePath *first = NULL; + GtkTreePath *last = NULL; + + if (gtk_tree_view_get_visible_range (tree_view->view, + &first, &last)) + { + if (closer_up != NULL && + gtk_tree_path_compare (closer_up, first) >= 0 && + gtk_tree_path_compare (closer_up, last) <= 0) + { + focused_path = gtk_tree_path_copy (closer_up); + } + else if (closer_down != NULL && + gtk_tree_path_compare (closer_down, first) >= 0 && + gtk_tree_path_compare (closer_down, last) <= 0) + { + focused_path = gtk_tree_path_copy (closer_down); + } + } + + if (focused_path == NULL) + { + if (closer_up != NULL) + focused_path = gtk_tree_path_copy (closer_up); + else + focused_path = gtk_tree_path_copy (closer_down); + } + + gtk_tree_path_free (first); + gtk_tree_path_free (last); + } + else if (paths != NULL) + { + focused_path = gtk_tree_path_copy (paths->data); + } + } + } + else if (paths != NULL) + { + focused_path = gtk_tree_path_copy (paths->data); + } + + /* Setting a cursor will reset the selection, so we must do it first. We don't + * want to change the cursor (which is likely the last clicked item), yet we + * also want to make sure that the cursor cannot end up out of the selected + * items, leading to discrepancy between pointer and keyboard navigation. This + * is why we set the cursor with this priority: + * 1. unchanged if it stays within selection; + * 2. closer item above the current cursor, if visible; + * 3. closer item below the current cursor, if visible; + * 4. closer item above the current cursor (even though invisible, which will + * make the view scroll up); + * 5. closer item below the current cursor if there are no items above (view + * will scroll down); + * 6. top selected item if there was no current cursor; + * 7. nothing if no selected items. + */ + if (focused_path != NULL) + { + gtk_tree_view_set_cursor (tree_view->view, focused_path, NULL, FALSE); + gtk_tree_path_free (focused_path); + } + + for (path = paths; path; path = g_list_next (path)) + { + GtkTreePath *parent_path = gtk_tree_path_copy (path->data); + + /* Expand the parent. */ + 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. */ + 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); + + if (paths) + { + GtkTreePath *first; + GtkTreePath *last; + + /* Scroll to the top item if and only if none of the selected + * items are already visible. Do nothing otherwise. + */ + if (gtk_tree_view_get_visible_range (tree_view->view, &first, &last)) + { + for (path = paths; path; path = g_list_next (path)) + { + if (gtk_tree_path_compare (first, path->data) <= 0 && + gtk_tree_path_compare (path->data, last) <= 0) + { + scroll_to_first = FALSE; + break; + } + } + + gtk_tree_path_free (first); + gtk_tree_path_free (last); + } + + if (scroll_to_first) + gtk_tree_view_scroll_to_cell (tree_view->view, paths->data, + NULL, FALSE, 0.0, 0.0); + } + + g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); + + _gimp_container_view_selection_changed (view); + + return TRUE; +} + +static gint +gimp_container_tree_view_get_selected (GimpContainerView *view, + GList **items) +{ + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); + GtkTreeSelection *selection; + gint n_selected; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view->view)); + n_selected = gtk_tree_selection_count_selected_rows (selection); + + if (items) + { + GList *paths; + GList *list; + + paths = gtk_tree_selection_get_selected_rows (selection, NULL); + + for (list = paths; list; list = g_list_next (list)) + { + GimpViewRenderer *renderer; + GtkTreeIter iter; + + gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->model), &iter, + list->data); + + renderer = gimp_container_tree_store_get_renderer + (GIMP_CONTAINER_TREE_STORE (tree_view->model), &iter); + + if (renderer->viewable) + *items = g_list_prepend (*items, renderer->viewable); + else + n_selected--; + + g_object_unref (renderer); + } + + *items = g_list_reverse (*items); + } + + return n_selected; +} + static gpointer gimp_container_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, @@ -787,37 +1061,12 @@ gimp_container_tree_view_reorder_item (GimpContainerView *view, GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter = (GtkTreeIter *) insert_data; GtkTreeIter parent_iter; - gboolean selected = FALSE; - - if (iter) - { - GtkTreeIter selected_iter; - - selected = gimp_container_tree_view_get_selected_single (tree_view, - &selected_iter); - - if (selected) - { - GimpViewRenderer *renderer; - - renderer = gimp_container_tree_store_get_renderer (GIMP_CONTAINER_TREE_STORE (tree_view->model), - &selected_iter); - - if (renderer->viewable != viewable) - selected = FALSE; - - g_object_unref (renderer); - } - } gimp_container_tree_store_reorder_item (GIMP_CONTAINER_TREE_STORE (tree_view->model), viewable, new_index, iter); - if (selected) - gimp_container_view_select_item (view, viewable); - if (gtk_tree_model_iter_parent (tree_view->model, &parent_iter, iter)) gimp_container_tree_view_expand_item (view, viewable, &parent_iter); } @@ -871,185 +1120,6 @@ gimp_container_tree_view_expand_item (GimpContainerView *view, } } -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; - gboolean free_paths = FALSE; - gboolean scroll_to_first = TRUE; - GtkTreePath *focused_path = NULL; - - /* If @paths is not set, compute it ourselves. */ - if (g_list_length (items) != g_list_length (paths)) - { - paths = NULL; - for (item = items; item; item = item->next) - { - GtkTreePath *path; - path = gimp_container_tree_view_get_path (tree_view, item->data); - if (path != NULL) - /* It may happen that some items have no paths when a tree - * view has some filtering logics (for instance Palette or - * Fonts dockables). Then an item which was selected at - * first might become unselected during filtering and has to - * be removed from selection. - */ - paths = g_list_prepend (paths, path); - } - - paths = g_list_reverse (paths); - free_paths = TRUE; - } - - g_signal_handlers_block_by_func (tree_view->priv->selection, - gimp_container_tree_view_selection_changed, - tree_view); - gtk_tree_selection_unselect_all (tree_view->priv->selection); - gtk_tree_view_get_cursor (tree_view->view, &focused_path, NULL); - if (focused_path != NULL) - { - GtkTreePath *closer_up = NULL; - GtkTreePath *closer_down = NULL; - - for (path = paths; path; path = path->next) - { - if (gtk_tree_path_compare (path->data, focused_path) == 0) - { - break; - } - else if (gtk_tree_path_compare (path->data, focused_path) == -1) - { - if (closer_up == NULL || gtk_tree_path_compare (path->data, closer_up) == 1) - closer_up = path->data; - } - else - { - if (closer_down == NULL || gtk_tree_path_compare (path->data, closer_down) == -1) - closer_down = path->data; - } - } - - if (path == NULL) - { - /* The current cursor is not part of the selection. This may happen in - * particular with a ctrl-click interaction which would deselect the - * item the cursor is now on. - */ - g_clear_pointer (&focused_path, gtk_tree_path_free); - - if (closer_up != NULL || closer_down != NULL) - { - GtkTreePath *first = NULL; - GtkTreePath *last = NULL; - - if (gtk_tree_view_get_visible_range (tree_view->view, &first, &last)) - { - if (closer_up != NULL && - gtk_tree_path_compare (closer_up, first) >= 0 && - gtk_tree_path_compare (closer_up, last) <= 0) - focused_path = gtk_tree_path_copy (closer_up); - else if (closer_down != NULL && - gtk_tree_path_compare (closer_down, first) >= 0 && - gtk_tree_path_compare (closer_down, last) <= 0) - focused_path = gtk_tree_path_copy (closer_down); - } - - if (focused_path == NULL) - { - if (closer_up != NULL) - focused_path = gtk_tree_path_copy (closer_up); - else - focused_path = gtk_tree_path_copy (closer_down); - } - - gtk_tree_path_free (first); - gtk_tree_path_free (last); - } - else if (paths != NULL) - { - focused_path = gtk_tree_path_copy (paths->data); - } - } - } - else if (paths != NULL) - { - focused_path = gtk_tree_path_copy (paths->data); - } - /* Setting a cursor will reset the selection, so we must do it first. We don't - * want to change the cursor (which is likely the last clicked item), yet we - * also want to make sure that the cursor cannot end up out of the selected - * items, leading to discrepancy between pointer and keyboard navigation. This - * is why we set the cursor with this priority: - * 1. unchanged if it stays within selection; - * 2. closer item above the current cursor, if visible; - * 3. closer item below the current cursor, if visible; - * 4. closer item above the current cursor (even though invisible, which will - * make the view scroll up); - * 5. closer item below the current cursor if there are no items above (view - * will scroll down); - * 6. top selected item if there was no current cursor; - * 7. nothing if no selected items. - */ - if (focused_path != NULL) - gtk_tree_view_set_cursor (tree_view->view, focused_path, NULL, FALSE); - gtk_tree_path_free (focused_path); - - 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. */ - 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); - - if (paths) - { - GtkTreePath *first; - GtkTreePath *last; - - /* Scroll to the top item if and only if none of the selected - * items are already visible. Do nothing otherwise. - */ - if (gtk_tree_view_get_visible_range (tree_view->view, &first, &last)) - { - for (item = items, path = paths; item && path; item = item->next, path = path->next) - { - if (gtk_tree_path_compare (first, path->data) <= 0 && - gtk_tree_path_compare (path->data, last) <= 0) - { - scroll_to_first = FALSE; - break; - } - } - - gtk_tree_path_free (first); - gtk_tree_path_free (last); - } - - if (scroll_to_first) - gtk_tree_view_scroll_to_cell (tree_view->view, paths->data, - NULL, FALSE, 0.0, 0.0); - } - - if (free_paths) - g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free); - - return TRUE; -} - static void gimp_container_tree_view_clear_items (GimpContainerView *view) { @@ -1077,54 +1147,6 @@ gimp_container_tree_view_clear_items (GimpContainerView *view) parent_view_iface->clear_items (view); } -static void -gimp_container_tree_view_set_view_size (GimpContainerView *view) -{ - GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); - GtkWidget *tree_widget; - GList *list; - gint view_size; - gint border_width; - - view_size = gimp_container_view_get_view_size (view, &border_width); - - if (tree_view->model) - gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (tree_view->model)); - - tree_widget = GTK_WIDGET (tree_view->view); - - if (! tree_widget) - return; - - for (list = tree_view->priv->toggle_cells; list; list = g_list_next (list)) - { - gchar *icon_name; - gint icon_size; - - g_object_get (list->data, "icon-name", &icon_name, NULL); - - if (icon_name) - { - GtkStyleContext *style = gtk_widget_get_style_context (tree_widget); - GtkBorder border; - - gtk_style_context_save (style); - gtk_style_context_add_class (style, GTK_STYLE_CLASS_BUTTON); - gtk_style_context_get_border (style, 0, &border); - gtk_style_context_restore (style); - - g_object_get (list->data, "icon-size", &icon_size, NULL); - icon_size = MIN (icon_size, MAX (view_size - (border.left + border.right), - view_size - (border.top + border.bottom))); - g_object_set (list->data, "icon-size", icon_size, NULL); - - g_free (icon_name); - } - } - - gtk_tree_view_columns_autosize (tree_view->view); -} - /* GimpContainerTreeView methods */ @@ -1136,8 +1158,8 @@ gimp_container_tree_view_real_edit_name (GimpContainerTreeView *tree_view) if (g_list_find (tree_view->priv->editable_cells, tree_view->priv->name_cell) && - gimp_container_tree_view_get_selected_single (tree_view, - &selected_iter)) + gimp_container_tree_view_get_1_selected (tree_view, + &selected_iter)) { GimpViewRenderer *renderer; @@ -1227,7 +1249,7 @@ gimp_container_tree_view_name_canceled (GtkCellRendererText *cell, { GtkTreeIter iter; - if (gimp_container_tree_view_get_selected_single (tree_view, &iter)) + if (gimp_container_tree_view_get_1_selected (tree_view, &iter)) { GimpViewRenderer *renderer; gchar *name; @@ -1249,14 +1271,7 @@ static void gimp_container_tree_view_selection_changed (GtkTreeSelection *selection, GimpContainerTreeView *tree_view) { - GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view); - GList *items; - GList *paths; - - 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); + _gimp_container_view_selection_changed (GIMP_CONTAINER_VIEW (tree_view)); } static GtkCellRenderer * @@ -1319,19 +1334,20 @@ gimp_container_tree_view_button (GtkWidget *widget, bevent->x, bevent->y, &path, &column, NULL, NULL)) { - GimpViewRenderer *renderer; - GtkCellRenderer *edit_cell = NULL; - GdkRectangle column_area; - GtkTreeIter iter; - gboolean multisel_mode; - GdkModifierType modifiers = (bevent->state & gimp_get_all_modifiers_mask ()); + GimpViewRenderer *renderer; + GtkCellRenderer *edit_cell = NULL; + GdkRectangle column_area; + GtkTreeIter iter; + gboolean multisel_mode; + GdkModifierType modifiers = (bevent->state & gimp_get_all_modifiers_mask ()); handled = TRUE; multisel_mode = (gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE); if (! modifiers || - (modifiers & ~(gimp_get_extend_selection_mask () | gimp_get_modify_selection_mask ()))) + (modifiers & ~(gimp_get_extend_selection_mask () | + gimp_get_modify_selection_mask ()))) { /* don't chain up for multi-selection handling if none of * the participating modifiers is pressed, we implement @@ -1357,12 +1373,14 @@ gimp_container_tree_view_button (GtkWidget *widget, * in this function. * See also commit 3e101922, MR !1128 and #10281. */ - if (multisel_mode && bevent->type == GDK_BUTTON_PRESS && ! gtk_widget_has_focus (widget)) + if (multisel_mode && bevent->type == GDK_BUTTON_PRESS && + ! gtk_widget_has_focus (widget)) gtk_widget_grab_focus (widget); gtk_tree_model_get_iter (tree_view->model, &iter, path); - renderer = gimp_container_tree_store_get_renderer (GIMP_CONTAINER_TREE_STORE (tree_view->model), &iter); + renderer = gimp_container_tree_store_get_renderer + (GIMP_CONTAINER_TREE_STORE (tree_view->model), &iter); tree_view->priv->dnd_renderer = renderer; @@ -1525,18 +1543,29 @@ gimp_container_tree_view_button (GtkWidget *widget, { /* If the clicked item is not selected, it becomes the new * selection. Otherwise, we use the current selection. This - * allows to not break multiple selection when right-clicking. + * allows to not break multiple selection when + * right-clicking. */ - if (! gimp_container_view_is_item_selected (container_view, renderer->viewable)) - gimp_container_view_item_selected (container_view, renderer->viewable); + if (! gimp_container_view_is_item_selected (container_view, + renderer->viewable)) + { + gimp_container_view_set_1_selected (container_view, + renderer->viewable); + } + /* Show the context menu. */ if (gimp_container_view_get_container (container_view)) - gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), (GdkEvent *) bevent); + { + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), + (GdkEvent *) bevent); + } } else if (bevent->button == 1) { handled = TRUE; - if (bevent->type == GDK_BUTTON_PRESS || bevent->type == GDK_BUTTON_RELEASE) + + if (bevent->type == GDK_BUTTON_PRESS || + bevent->type == GDK_BUTTON_RELEASE) { /* don't select item if a toggle was clicked */ if (! toggled_cell) @@ -1561,8 +1590,8 @@ gimp_container_tree_view_button (GtkWidget *widget, * click becomes a drag'n drop action. */ handled = - gimp_container_view_item_selected (container_view, - renderer->viewable); + gimp_container_view_set_1_selected (container_view, + renderer->viewable); } /* Multi selection will be handled by gimp_container_tree_view_selection_changed() */ @@ -1617,8 +1646,10 @@ gimp_container_tree_view_button (GtkWidget *widget, /* don't select item if a toggle was clicked */ if (bevent->type == GDK_BUTTON_RELEASE && ! toggled_cell) - success = gimp_container_view_item_selected (container_view, - renderer->viewable); + { + success = gimp_container_view_set_1_selected (container_view, + renderer->viewable); + } if (success) { @@ -1642,8 +1673,8 @@ gimp_container_tree_view_button (GtkWidget *widget, /* Only activate if we're not in a toggled cell * and no modifier keys are pressed */ - gimp_container_view_item_activated (container_view, - renderer->viewable); + _gimp_container_view_item_activated (container_view, + renderer->viewable); } } } @@ -1670,21 +1701,28 @@ gimp_container_tree_view_button (GtkWidget *widget, gtk_tree_path_free (path); g_object_unref (renderer); - handled = (multisel_mode ? handled : (bevent->type == GDK_BUTTON_RELEASE ? FALSE : TRUE)); + handled = (multisel_mode ? handled : + (bevent->type == GDK_BUTTON_RELEASE ? FALSE : TRUE)); } else { if (gdk_event_triggers_context_menu ((GdkEvent *) bevent)) { - gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), (GdkEvent *) bevent); + gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (tree_view), + (GdkEvent *) bevent); } handled = TRUE; } - if (handled && bevent->type == GDK_BUTTON_PRESS && ! gtk_widget_has_focus (widget) && - ! toggled_cell && ! clicked_cell) - gtk_widget_grab_focus (widget); + if (handled && + bevent->type == GDK_BUTTON_PRESS && + ! gtk_widget_has_focus (widget) && + ! toggled_cell && + ! clicked_cell) + { + gtk_widget_grab_focus (widget); + } return handled; } @@ -1810,7 +1848,7 @@ gimp_container_tree_view_drag_viewable_list (GtkWidget *widget, if (context) *context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (data)); - gimp_container_tree_view_get_selected (GIMP_CONTAINER_VIEW (data), &items, NULL); + gimp_container_tree_view_get_selected (GIMP_CONTAINER_VIEW (data), &items); return items; } @@ -1877,8 +1915,8 @@ gimp_container_tree_view_zoom_gesture_update (GtkGestureZoom *gesture, } static gboolean -gimp_container_tree_view_get_selected_single (GimpContainerTreeView *tree_view, - GtkTreeIter *iter) +gimp_container_tree_view_get_1_selected (GimpContainerTreeView *tree_view, + GtkTreeIter *iter) { GtkTreeSelection *selection; @@ -1903,74 +1941,6 @@ gimp_container_tree_view_get_selected_single (GimpContainerTreeView *tree_view, } } -static gint -gimp_container_tree_view_get_selected (GimpContainerView *view, - GList **items, - GList **paths) -{ - GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); - GtkTreeSelection *selection; - gint selected_count; - GList *selected_paths; - GList *removed_paths = NULL; - GList *current_row; - GtkTreeIter iter; - GimpViewRenderer *renderer; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view->view)); - selected_count = gtk_tree_selection_count_selected_rows (selection); - - if (items == NULL) - { - if (paths) - *paths = NULL; - - /* just provide selected count */ - return selected_count; - } - - selected_paths = gtk_tree_selection_get_selected_rows (selection, NULL); - *items = NULL; - - for (current_row = selected_paths; - current_row; - current_row = g_list_next (current_row)) - { - gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->model), &iter, - (GtkTreePath *) current_row->data); - - renderer = gimp_container_tree_store_get_renderer (GIMP_CONTAINER_TREE_STORE (tree_view->model), - &iter); - - 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); - } - *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; -} - static void gimp_container_tree_view_row_expanded (GtkTreeView *tree_view, GtkTreeIter *iter, @@ -2064,45 +2034,3 @@ gimp_container_tree_view_monitor_changed (GimpContainerTreeView *view) gimp_container_tree_view_monitor_changed_foreach, NULL); } - -typedef struct -{ - GimpViewable *viewable; - GtkTreePath *path; -} SearchData; - -static gboolean -gimp_container_tree_view_search_path_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -{ - SearchData *search_data = data; - GimpViewRenderer *renderer; - - renderer = gimp_container_tree_store_get_renderer (GIMP_CONTAINER_TREE_STORE (model), - iter); - - if (renderer->viewable == search_data->viewable) - search_data->path = gtk_tree_path_copy (path); - - g_object_unref (renderer); - - return (search_data->path != NULL); -} - -static GtkTreePath * -gimp_container_tree_view_get_path (GimpContainerTreeView *tree_view, - GimpViewable *viewable) -{ - SearchData search_data; - - search_data.viewable = viewable; - search_data.path = NULL; - - gtk_tree_model_foreach (GTK_TREE_MODEL (tree_view->model), - (GtkTreeModelForeachFunc) gimp_container_tree_view_search_path_foreach, - &search_data); - - return search_data.path; -} diff --git a/app/widgets/gimpcontainerview-cruft.c b/app/widgets/gimpcontainerview-cruft.c index 6bb63d9984..65d7917f77 100644 --- a/app/widgets/gimpcontainerview-cruft.c +++ b/app/widgets/gimpcontainerview-cruft.c @@ -193,7 +193,6 @@ gimp_container_view_add_foreach (GimpViewable *viewable, insert_data = view_iface->insert_item (view, viewable, parent_insert_data, -1); - g_hash_table_insert (private->item_hash, viewable, insert_data); children = gimp_viewable_get_children (viewable); @@ -363,7 +362,7 @@ gimp_container_view_thaw (GimpContainerView *view, object = gimp_context_get_by_type (private->context, child_type); - gimp_container_view_select_item (view, GIMP_VIEWABLE (object)); + gimp_container_view_set_1_selected (view, GIMP_VIEWABLE (object)); } } } diff --git a/app/widgets/gimpcontainerview.c b/app/widgets/gimpcontainerview.c index ed835c59d6..cd4a253ef6 100644 --- a/app/widgets/gimpcontainerview.c +++ b/app/widgets/gimpcontainerview.c @@ -2,7 +2,7 @@ * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * gimpcontainerview.c - * Copyright (C) 2001-2010 Michael Natterer + * Copyright (C) 2001-2025 Michael Natterer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,14 +44,19 @@ enum { - SELECT_ITEMS, - ACTIVATE_ITEM, + SELECTION_CHANGED, + ITEM_ACTIVATED, LAST_SIGNAL }; /* local function prototypes */ +static void gimp_container_view_real_selection_changed + (GimpContainerView *view); +static void gimp_container_view_real_item_activated + (GimpContainerView *view, + GimpViewable *item); static void gimp_container_view_real_set_container (GimpContainerView *view, GimpContainer *container); static void gimp_container_view_real_set_context (GimpContainerView *view, @@ -59,10 +64,11 @@ static void gimp_container_view_real_set_context (GimpContainerView *view, static void gimp_container_view_real_set_selection_mode (GimpContainerView *view, GtkSelectionMode mode); - +static gboolean + gimp_container_view_real_set_selected (GimpContainerView *view, + GList *list); static gint gimp_container_view_real_get_selected (GimpContainerView *view, - GList **list, - GList **paths); + GList **list); static void gimp_container_view_connect_context (GimpContainerView *view); static void gimp_container_view_disconnect_context (GimpContainerView *view); @@ -98,34 +104,35 @@ static guint view_signals[LAST_SIGNAL] = { 0 }; static void gimp_container_view_default_init (GimpContainerViewInterface *iface) { - 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", + view_signals[SELECTION_CHANGED] = + g_signal_new ("selection-changed", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpContainerViewInterface, activate_item), + G_STRUCT_OFFSET (GimpContainerViewInterface, selection_changed), NULL, NULL, - gimp_marshal_VOID__OBJECT_POINTER, - G_TYPE_NONE, 2, - GIMP_TYPE_OBJECT, - G_TYPE_POINTER); + NULL, + G_TYPE_NONE, 0); - iface->select_items = NULL; - iface->activate_item = NULL; + view_signals[ITEM_ACTIVATED] = + g_signal_new ("item-activated", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpContainerViewInterface, item_activated), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + GIMP_TYPE_OBJECT); + + iface->selection_changed = gimp_container_view_real_selection_changed; + iface->item_activated = gimp_container_view_real_item_activated; iface->set_container = gimp_container_view_real_set_container; iface->set_context = gimp_container_view_real_set_context; iface->set_selection_mode = gimp_container_view_real_set_selection_mode; + iface->set_view_size = NULL; + iface->set_selected = gimp_container_view_real_set_selected; + iface->get_selected = gimp_container_view_real_get_selected; + iface->insert_item = NULL; iface->insert_items_after = NULL; iface->remove_item = NULL; @@ -133,8 +140,6 @@ gimp_container_view_default_init (GimpContainerViewInterface *iface) iface->rename_item = NULL; iface->expand_item = NULL; iface->clear_items = _gimp_container_view_real_clear_items; - iface->set_view_size = NULL; - iface->get_selected = gimp_container_view_real_get_selected; iface->insert_data_free = NULL; iface->model_is_tree = FALSE; @@ -183,39 +188,8 @@ gimp_container_view_default_init (GimpContainerViewInterface *iface) G_PARAM_CONSTRUCT)); } -/** - * gimp_container_view_install_properties: - * @klass: the class structure for a type deriving from #GObject - * - * Installs the necessary properties for a class implementing - * #GimpContainerView. A #GimpContainerViewProp property is installed - * for each property, using the values from the #GimpContainerViewProp - * enumeration. The caller must make sure itself that the enumeration - * values don't collide with some other property values they - * are using (that's what %GIMP_CONTAINER_VIEW_PROP_LAST is good for). - **/ -void -gimp_container_view_install_properties (GObjectClass *klass) -{ - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_CONTAINER, - "container"); - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_CONTEXT, - "context"); - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_SELECTION_MODE, - "selection-mode"); - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_REORDERABLE, - "reorderable"); - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_VIEW_SIZE, - "view-size"); - g_object_class_override_property (klass, - GIMP_CONTAINER_VIEW_PROP_VIEW_BORDER_WIDTH, - "view-border-width"); -} + +/* public functions */ GimpContainer * gimp_container_view_get_container (GimpContainerView *view) @@ -418,66 +392,105 @@ gimp_container_view_enable_dnd (GimpContainerView *view, } gboolean -gimp_container_view_select_items (GimpContainerView *view, +gimp_container_view_set_selected (GimpContainerView *view, GList *viewables) { GimpContainerViewPrivate *private; - gboolean success = FALSE; g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE); private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); if (gimp_container_frozen (private->container)) - return TRUE; + return FALSE; - g_signal_emit (view, view_signals[SELECT_ITEMS], 0, - viewables, NULL, &success); - - return success; + return GIMP_CONTAINER_VIEW_GET_IFACE (view)->set_selected (view, viewables); } gboolean -gimp_container_view_select_item (GimpContainerView *view, - GimpViewable *viewable) +gimp_container_view_set_1_selected (GimpContainerView *view, + GimpViewable *viewable) { GList *viewables = NULL; gboolean success; + g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE); + if (viewable) viewables = g_list_prepend (viewables, viewable); - success = gimp_container_view_select_items (view, viewables); + success = gimp_container_view_set_selected (view, viewables); g_list_free (viewables); return success; } -void -gimp_container_view_activate_item (GimpContainerView *view, - GimpViewable *viewable) +/** + * gimp_container_view_get_selected: + * @view: + * @items: + * + * Get the selected items in @view. + * + * If @items is not %NULL, fills it with a newly allocated #GList of the + * selected items. + * + * Note that by default, the interface only implements some basic single + * selection. Override select_items() signal to get more complete + * selection support. + * + * Returns: the number of selected items. + */ +gint +gimp_container_view_get_selected (GimpContainerView *view, + GList **items) { - GimpContainerViewPrivate *private; - gpointer insert_data; + g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), 0); - g_return_if_fail (GIMP_IS_CONTAINER_VIEW (view)); - g_return_if_fail (GIMP_IS_VIEWABLE (viewable)); + if (items) + *items = NULL; - private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); - - if (gimp_container_frozen (private->container)) - return; - - insert_data = g_hash_table_lookup (private->item_hash, viewable); - - g_signal_emit (view, view_signals[ACTIVATE_ITEM], 0, - viewable, insert_data); + return GIMP_CONTAINER_VIEW_GET_IFACE (view)->get_selected (view, items); } +GimpViewable * +gimp_container_view_get_1_selected (GimpContainerView *view) +{ + GimpViewable *item = NULL; + GList *items; + + g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), NULL); + + if (gimp_container_view_get_selected (view, &items) == 1) + item = items->data; + + g_list_free (items); + + return item; +} + +gboolean +gimp_container_view_is_item_selected (GimpContainerView *view, + GimpViewable *viewable) +{ + GList *items; + gboolean found; + + gimp_container_view_get_selected (view, &items); + found = (g_list_find (items, viewable) != NULL); + + g_list_free (items); + + return found; +} + + +/* protected functions, only to be used by implementors */ + gpointer -gimp_container_view_lookup (GimpContainerView *view, - GimpViewable *viewable) +_gimp_container_view_lookup (GimpContainerView *view, + GimpViewable *viewable) { GimpContainerViewPrivate *private; @@ -494,8 +507,8 @@ gimp_container_view_lookup (GimpContainerView *view, } gboolean -gimp_container_view_contains (GimpContainerView *view, - GList *viewables) +_gimp_container_view_contains (GimpContainerView *view, + GList *viewables) { GimpContainerViewPrivate *private; GList *iter; @@ -514,143 +527,64 @@ gimp_container_view_contains (GimpContainerView *view, return TRUE; } -gboolean -gimp_container_view_item_selected (GimpContainerView *view, - GimpViewable *viewable) +void +_gimp_container_view_selection_changed (GimpContainerView *view) { - GimpContainerViewPrivate *private; - gboolean success; + g_return_if_fail (GIMP_IS_CONTAINER_VIEW (view)); - g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE); - g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), FALSE); - - private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); - - /* HACK */ - if (private->container && private->context) - { - GType child_type; - const gchar *signal_name; - - child_type = gimp_container_get_child_type (private->container); - signal_name = gimp_context_type_to_signal_name (child_type); - - if (signal_name) - { - gimp_context_set_by_type (private->context, child_type, - GIMP_OBJECT (viewable)); - return TRUE; - } - } - - success = gimp_container_view_select_item (view, viewable); - -#if 0 - if (success && private->container && private->context) - { - GimpContext *context; - GType child_type; - - /* ref and remember the context because private->context may - * become NULL by calling gimp_context_set_by_type() - */ - context = g_object_ref (private->context); - child_type = gimp_container_get_child_type (private->container); - - g_signal_handlers_block_by_func (context, - gimp_container_view_context_changed, - view); - - gimp_context_set_by_type (context, child_type, GIMP_OBJECT (viewable)); - - g_signal_handlers_unblock_by_func (context, - gimp_container_view_context_changed, - view); - - g_object_unref (context); - } -#endif - - return success; -} - -gboolean -gimp_container_view_multi_selected (GimpContainerView *view, - GList *items, - GList *items_data) -{ - gboolean success = FALSE; - - g_return_val_if_fail (GIMP_IS_CONTAINER_VIEW (view), FALSE); - - 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_items() signal to get more complete - * selection support. - * - * Returns: the number of selected items. - */ -gint -gimp_container_view_get_selected (GimpContainerView *view, - 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, items, - items_data); -} - -gboolean -gimp_container_view_is_item_selected (GimpContainerView *view, - GimpViewable *viewable) -{ - GList *items; - gboolean found; - - gimp_container_view_get_selected (view, &items, NULL); - found = (g_list_find (items, viewable) != NULL); - - g_list_free (items); - - return found; + g_signal_emit (view, view_signals[SELECTION_CHANGED], 0); } void -gimp_container_view_item_activated (GimpContainerView *view, - GimpViewable *viewable) +_gimp_container_view_item_activated (GimpContainerView *view, + GimpViewable *viewable) { g_return_if_fail (GIMP_IS_CONTAINER_VIEW (view)); g_return_if_fail (GIMP_IS_VIEWABLE (viewable)); - gimp_container_view_activate_item (view, viewable); + g_signal_emit (view, view_signals[ITEM_ACTIVATED], 0, + viewable); +} + +/** + * gimp_container_view_install_properties: + * @klass: the class structure for a type deriving from #GObject + * + * Installs the necessary properties for a class implementing + * #GimpContainerView. A #GimpContainerViewProp property is installed + * for each property, using the values from the #GimpContainerViewProp + * enumeration. The caller must make sure itself that the enumeration + * values don't collide with some other property values they + * are using (that's what %GIMP_CONTAINER_VIEW_PROP_LAST is good for). + **/ +void +_gimp_container_view_install_properties (GObjectClass *klass) +{ + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_CONTAINER, + "container"); + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_CONTEXT, + "context"); + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_SELECTION_MODE, + "selection-mode"); + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_REORDERABLE, + "reorderable"); + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_VIEW_SIZE, + "view-size"); + g_object_class_override_property (klass, + GIMP_CONTAINER_VIEW_PROP_VIEW_BORDER_WIDTH, + "view-border-width"); } void -gimp_container_view_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +_gimp_container_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { GimpContainerView *view = GIMP_CONTAINER_VIEW (object); @@ -684,6 +618,7 @@ gimp_container_view_set_property (GObject *object, gimp_container_view_set_view_size (view, size, border); } break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -691,10 +626,10 @@ gimp_container_view_set_property (GObject *object, } void -gimp_container_view_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) +_gimp_container_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { GimpContainerView *view = GIMP_CONTAINER_VIEW (object); @@ -726,6 +661,7 @@ gimp_container_view_get_property (GObject *object, g_value_set_int (value, border); } break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -735,6 +671,58 @@ gimp_container_view_get_property (GObject *object, /* Private functions */ +static void +gimp_container_view_real_selection_changed (GimpContainerView *view) +{ + GimpContainerViewPrivate *private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); + + if (private->container && private->context) + { + GType child_type = gimp_container_get_child_type (private->container); + + if (gimp_context_type_to_signal_name (child_type)) + { + GList *items = NULL; + gint n_items; + + n_items = gimp_container_view_get_selected (view, &items); + + if (n_items == 1 && + gimp_context_get_by_type (private->context, child_type) != + GIMP_OBJECT (items->data)) + { + GimpContext *context; + + /* ref and remember the context because + * private->context may become NULL by calling + * gimp_context_set_by_type() + */ + context = g_object_ref (private->context); + + g_signal_handlers_block_by_func (context, + gimp_container_view_context_changed, + view); + + gimp_context_set_by_type (context, child_type, items->data); + + g_signal_handlers_unblock_by_func (context, + gimp_container_view_context_changed, + view); + + g_object_unref (context); + } + + g_list_free (items); + } + } +} + +static void +gimp_container_view_real_item_activated (GimpContainerView *view, + GimpViewable *item) +{ +} + static void gimp_container_view_real_set_container (GimpContainerView *view, GimpContainer *container) @@ -746,7 +734,10 @@ gimp_container_view_real_set_container (GimpContainerView *view, if (private->context) gimp_container_view_disconnect_context (view); - gimp_container_view_select_items (view, NULL); +#if 0 + /* needed? */ + gimp_container_view_set_selected (view, NULL); +#endif if (! GIMP_CONTAINER_VIEW_GET_IFACE (view)->use_list_model) _gimp_container_view_disconnect_cruft (view); @@ -792,53 +783,21 @@ gimp_container_view_real_set_selection_mode (GimpContainerView *view, private->selection_mode = mode; } +static gboolean +gimp_container_view_real_set_selected (GimpContainerView *view, + GList *items) +{ + return FALSE; +} + static gint gimp_container_view_real_get_selected (GimpContainerView *view, - GList **items, - GList **items_data) + GList **items) { - GimpContainerViewPrivate *private = GIMP_CONTAINER_VIEW_GET_PRIVATE (view); - GType child_type; - GimpObject *object; - - if (items) + 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; - - child_type = gimp_container_get_child_type (private->container); - if (gimp_context_type_to_property (child_type) == -1) - { - /* If you experience this warning, it means you should implement - * your own definition for get_selected() because the default one - * won't work for you (only made for context properties). - */ - g_warning ("%s: TODO: implement GimpContainerViewInterface's get_selected() for type '%s'.\n", - G_STRFUNC, g_type_name (G_OBJECT_TYPE (view))); - return 0; - } - - object = gimp_context_get_by_type (private->context, - child_type); - - /* 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; + return 0; } static void @@ -869,7 +828,7 @@ gimp_container_view_connect_context (GimpContainerView *view) GimpObject *object = gimp_context_get_by_type (private->context, child_type); - gimp_container_view_select_item (view, GIMP_VIEWABLE (object)); + gimp_container_view_set_1_selected (view, GIMP_VIEWABLE (object)); } } } @@ -904,23 +863,7 @@ gimp_container_view_context_changed (GimpContext *context, GimpViewable *viewable, GimpContainerView *view) { - GList *viewables = NULL; - - if (viewable) - viewables = g_list_prepend (viewables, viewable); - - g_signal_handlers_block_by_func (context, - gimp_container_view_context_changed, - view); - - if (! gimp_container_view_select_items (view, viewables)) - g_warning ("%s: select_items() failed (should not happen)", G_STRFUNC); - - g_signal_handlers_unblock_by_func (context, - gimp_container_view_context_changed, - view); - - g_list_free (viewables); + gimp_container_view_set_1_selected (view, viewable); } static void @@ -936,7 +879,7 @@ gimp_container_view_viewable_dropped (GtkWidget *widget, if (viewable && private->container && gimp_container_have (private->container, GIMP_OBJECT (viewable))) { - gimp_container_view_item_selected (view, viewable); + gimp_container_view_set_1_selected (view, viewable); } } @@ -951,7 +894,7 @@ gimp_container_view_button_viewables_dropped (GtkWidget *widget, if (viewables) { - gimp_container_view_multi_selected (view, viewables, NULL); + gimp_container_view_set_selected (view, viewables); gtk_button_clicked (GTK_BUTTON (widget)); } @@ -966,9 +909,9 @@ gimp_container_view_button_viewable_dropped (GtkWidget *widget, { GimpContainerView *view = GIMP_CONTAINER_VIEW (data); - if (viewable && gimp_container_view_lookup (view, viewable)) + if (viewable && _gimp_container_view_lookup (view, viewable)) { - gimp_container_view_item_selected (view, viewable); + gimp_container_view_set_1_selected (view, viewable); gtk_button_clicked (GTK_BUTTON (widget)); } diff --git a/app/widgets/gimpcontainerview.h b/app/widgets/gimpcontainerview.h index 8eb4693e73..6ea1b6d48f 100644 --- a/app/widgets/gimpcontainerview.h +++ b/app/widgets/gimpcontainerview.h @@ -2,7 +2,7 @@ * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * gimpcontainerview.h - * Copyright (C) 2001-2010 Michael Natterer + * Copyright (C) 2001-2025 Michael Natterer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +35,10 @@ typedef enum #define GIMP_TYPE_CONTAINER_VIEW (gimp_container_view_get_type ()) -G_DECLARE_INTERFACE (GimpContainerView, gimp_container_view, GIMP, CONTAINER_VIEW, GtkWidget) +G_DECLARE_INTERFACE (GimpContainerView, + gimp_container_view, + GIMP, CONTAINER_VIEW, + GtkWidget) struct _GimpContainerViewInterface @@ -43,22 +46,25 @@ struct _GimpContainerViewInterface GTypeInterface base_iface; /* signals */ - gboolean (* select_items) (GimpContainerView *view, - GList *items, - GList *paths); - - void (* activate_item) (GimpContainerView *view, - GimpViewable *object, - gpointer insert_data); + void (* selection_changed) (GimpContainerView *view); + void (* item_activated) (GimpContainerView *view, + GimpViewable *object); /* virtual functions */ - void (* set_container) (GimpContainerView *view, - GimpContainer *container); - void (* set_context) (GimpContainerView *view, - GimpContext *context); - void (* set_selection_mode) (GimpContainerView *view, - GtkSelectionMode mode); + void (* set_container) (GimpContainerView *view, + GimpContainer *container); + void (* set_context) (GimpContainerView *view, + GimpContext *context); + void (* set_selection_mode) (GimpContainerView *view, + GtkSelectionMode mode); + void (* set_view_size) (GimpContainerView *view); + gboolean (* set_selected) (GimpContainerView *view, + GList *items); + gint (* get_selected) (GimpContainerView *view, + GList **items); + + /* cruft */ gpointer (* insert_item) (GimpContainerView *view, GimpViewable *object, gpointer parent_insert_data, @@ -78,11 +84,6 @@ struct _GimpContainerViewInterface GimpViewable *object, gpointer insert_data); void (* clear_items) (GimpContainerView *view); - void (* set_view_size) (GimpContainerView *view); - gint (* get_selected) (GimpContainerView *view, - GList **items, - GList **insert_data); - /* the destroy notifier for private->hash_table's values */ GDestroyNotify insert_data_free; @@ -121,42 +122,37 @@ void gimp_container_view_enable_dnd (GimpContainerView *e GtkButton *button, GType child_type); -gboolean gimp_container_view_select_items (GimpContainerView *view, +gboolean gimp_container_view_set_selected (GimpContainerView *view, GList *viewables); -gboolean gimp_container_view_select_item (GimpContainerView *view, - GimpViewable *viewable); -void gimp_container_view_activate_item (GimpContainerView *view, +gboolean gimp_container_view_set_1_selected (GimpContainerView *view, GimpViewable *viewable); + gint gimp_container_view_get_selected (GimpContainerView *view, - GList **items, - GList **items_data); + GList **items); +GimpViewable * gimp_container_view_get_1_selected (GimpContainerView *view); + gboolean gimp_container_view_is_item_selected (GimpContainerView *view, GimpViewable *viewable); + /* protected */ -gpointer gimp_container_view_lookup (GimpContainerView *view, +gpointer _gimp_container_view_lookup (GimpContainerView *view, GimpViewable *viewable); -gboolean gimp_container_view_contains (GimpContainerView *view, +gboolean _gimp_container_view_contains (GimpContainerView *view, GList *viewables); -gboolean gimp_container_view_item_selected (GimpContainerView *view, - GimpViewable *item); -gboolean gimp_container_view_multi_selected (GimpContainerView *view, - GList *items, - GList *paths); -void gimp_container_view_item_activated (GimpContainerView *view, +void _gimp_container_view_selection_changed (GimpContainerView *view); +void _gimp_container_view_item_activated (GimpContainerView *view, GimpViewable *item); -/* convenience functions */ - -void gimp_container_view_install_properties (GObjectClass *klass); -void gimp_container_view_set_property (GObject *object, +void _gimp_container_view_install_properties(GObjectClass *klass); +void _gimp_container_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -void gimp_container_view_get_property (GObject *object, +void _gimp_container_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); diff --git a/app/widgets/gimpdatafactoryview.c b/app/widgets/gimpdatafactoryview.c index 0a5b3a230a..2210cb1534 100644 --- a/app/widgets/gimpdatafactoryview.c +++ b/app/widgets/gimpdatafactoryview.c @@ -567,7 +567,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, NULL); + gimp_container_view_get_selected (container_view, &active_items); gimp_tag_entry_set_selected_items (GIMP_TAG_ENTRY (view->priv->assign_tag_entry), active_items); g_list_free (active_items); diff --git a/app/widgets/gimpdeviceeditor.c b/app/widgets/gimpdeviceeditor.c index 07fc59f267..0d22cc2a74 100644 --- a/app/widgets/gimpdeviceeditor.c +++ b/app/widgets/gimpdeviceeditor.c @@ -97,10 +97,8 @@ static void gimp_device_editor_remove_device (GimpContainer *container, static void gimp_device_editor_device_changed (GimpDeviceInfo *info, GimpDeviceEditor *editor); -static gboolean gimp_device_editor_select_device (GimpContainerView *view, - GList *viewables, - GList *paths, - GimpDeviceEditor *editor); +static void gimp_device_editor_select_device (GimpContainerView *view, + GimpDeviceEditor *editor); static void gimp_device_editor_delete_clicked (GtkWidget *button, GimpDeviceEditor *editor); @@ -150,7 +148,7 @@ gimp_device_editor_init (GimpDeviceEditor *editor) gtk_paned_pack1 (GTK_PANED (editor), private->treeview, TRUE, FALSE); gtk_widget_show (private->treeview); - g_signal_connect_object (private->treeview, "select-items", + g_signal_connect_object (private->treeview, "selection-changed", G_CALLBACK (gimp_device_editor_select_device), G_OBJECT (editor), 0); @@ -367,8 +365,8 @@ gimp_device_editor_add_device (GimpContainer *container, gimp_object_get_name (info)); gtk_widget_show (widget); - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), - GIMP_VIEWABLE (info)); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), + GIMP_VIEWABLE (info)); if (iter) { @@ -392,8 +390,8 @@ gimp_device_editor_remove_device (GimpContainer *container, GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor); GtkTreeIter *iter; - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), - GIMP_VIEWABLE (info)); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), + GIMP_VIEWABLE (info)); if (iter) { @@ -418,8 +416,8 @@ gimp_device_editor_device_changed (GimpDeviceInfo *info, GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor); GtkTreeIter *iter; - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), - GIMP_VIEWABLE (info)); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (private->treeview), + GIMP_VIEWABLE (info)); if (iter) { @@ -434,17 +432,16 @@ gimp_device_editor_device_changed (GimpDeviceInfo *info, } } -static gboolean +static void gimp_device_editor_select_device (GimpContainerView *view, - GList *viewables, - GList *paths, GimpDeviceEditor *editor) { GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor); + GimpViewable *item; - g_return_val_if_fail (g_list_length (viewables) < 2, FALSE); + item = gimp_container_view_get_1_selected (view); - if (viewables) + if (item) { GimpContainerTreeView *treeview; GtkWidget *widget; @@ -463,14 +460,15 @@ gimp_device_editor_select_device (GimpContainerView *view, GIMP_CONTAINER_TREE_STORE_COLUMN_USER_DATA, &widget, GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, -1); - if (renderer->viewable == viewables->data && widget) + + if (renderer->viewable == item && widget) { GimpDeviceInfo *info; gboolean delete_sensitive = FALSE; gtk_stack_set_visible_child (GTK_STACK (private->stack), widget); - g_object_get (widget ,"info", &info, NULL); + g_object_get (widget, "info", &info, NULL); gtk_label_set_text (GTK_LABEL (private->label), gimp_object_get_name (info)); @@ -488,11 +486,10 @@ gimp_device_editor_select_device (GimpContainerView *view, break; } + g_object_unref (renderer); } } - - return TRUE; } static void @@ -506,18 +503,17 @@ gimp_device_editor_delete_response (GtkWidget *dialog, if (response_id == GTK_RESPONSE_OK) { - GList *selected; + GimpViewable *item; - if (gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview), - &selected, NULL)) + item = gimp_container_view_get_1_selected (GIMP_CONTAINER_VIEW (private->treeview)); + + if (item) { GimpContainer *devices; devices = GIMP_CONTAINER (gimp_devices_get_manager (private->gimp)); - gimp_container_remove (devices, selected->data); - - g_list_free (selected); + gimp_container_remove (devices, GIMP_OBJECT (item)); } } @@ -530,10 +526,11 @@ gimp_device_editor_delete_clicked (GtkWidget *button, { GimpDeviceEditorPrivate *private = GIMP_DEVICE_EDITOR_GET_PRIVATE (editor); GtkWidget *dialog; - GList *selected; + GimpViewable *item; - if (! gimp_container_view_get_selected (GIMP_CONTAINER_VIEW (private->treeview), - &selected, NULL)) + item = gimp_container_view_get_1_selected (GIMP_CONTAINER_VIEW (private->treeview)); + + if (! item) return; dialog = gimp_message_dialog_new (_("Delete Device Settings"), @@ -558,15 +555,13 @@ gimp_device_editor_delete_clicked (GtkWidget *button, gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box, _("Delete \"%s\"?"), - gimp_object_get_name (selected->data)); + gimp_object_get_name (item)); gimp_message_box_set_text (GIMP_MESSAGE_DIALOG (dialog)->box, _("You are about to delete this device's " "stored settings.\n" "The next time this device is plugged, " "default settings will be used.")); - g_list_free (selected); - gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE); gtk_widget_show (dialog); diff --git a/app/widgets/gimpdrawabletreeview-filters.c b/app/widgets/gimpdrawabletreeview-filters.c index f532fb95ec..d416161193 100644 --- a/app/widgets/gimpdrawabletreeview-filters.c +++ b/app/widgets/gimpdrawabletreeview-filters.c @@ -83,16 +83,12 @@ struct _GimpDrawableTreeViewFiltersEditor static void gimp_drawable_filters_editor_set_sensitive (GimpDrawableTreeView *view); -static gboolean - gimp_drawable_filters_editor_view_select_items +static void gimp_drawable_filters_editor_view_selection_changed (GimpContainerView *view, - GList *filters, - GList *paths, GimpDrawableTreeView *drawable_view); -static void gimp_drawable_filters_editor_view_activate_item +static void gimp_drawable_filters_editor_view_item_activated (GtkWidget *widget, GimpViewable *viewable, - gpointer insert_data, GimpDrawableTreeView *view); static void gimp_drawable_filters_editor_view_visible_cell_toggled (GtkCellRendererToggle *toggle, @@ -386,11 +382,11 @@ _gimp_drawable_tree_view_filter_editor_show (GimpDrawableTreeView *view, } } - g_signal_connect (filter_tree_view, "select-items", - G_CALLBACK (gimp_drawable_filters_editor_view_select_items), + g_signal_connect (filter_tree_view, "selection-changed", + G_CALLBACK (gimp_drawable_filters_editor_view_selection_changed), view); - g_signal_connect_object (filter_tree_view, "activate-item", - G_CALLBACK (gimp_drawable_filters_editor_view_activate_item), + g_signal_connect_object (filter_tree_view, "item-activated", + G_CALLBACK (gimp_drawable_filters_editor_view_item_activated), view, 0); gtk_box_pack_start (GTK_BOX (editor->vbox), @@ -446,10 +442,10 @@ _gimp_drawable_tree_view_filter_editor_hide (GimpDrawableTreeView *view) if (editor->view) { g_signal_handlers_disconnect_by_func (editor->view, - gimp_drawable_filters_editor_view_select_items, + gimp_drawable_filters_editor_view_selection_changed, view); g_signal_handlers_disconnect_by_func (editor->view, - gimp_drawable_filters_editor_view_activate_item, + gimp_drawable_filters_editor_view_item_activated, view); g_clear_pointer (&editor->view, gtk_widget_destroy); @@ -529,37 +525,38 @@ gimp_drawable_filters_editor_set_sensitive (GimpDrawableTreeView *view) } } -static gboolean -gimp_drawable_filters_editor_view_select_items (GimpContainerView *view, - GList *filters, - GList *paths, - GimpDrawableTreeView *drawable_view) +static void +gimp_drawable_filters_editor_view_selection_changed (GimpContainerView *view, + GimpDrawableTreeView *drawable_view) { GimpDrawableTreeViewFiltersEditor *editor = drawable_view->editor; + GList *items; + gint n_items; - g_return_val_if_fail (g_list_length (filters) <= 1, FALSE); + n_items = gimp_container_view_get_selected (view, &items); + + g_warn_if_fail (n_items <= 1); editor->filter = NULL; - if (filters) + if (items) { /* Don't set floating selection as active filter */ - if (GIMP_IS_DRAWABLE_FILTER (filters->data)) + if (GIMP_IS_DRAWABLE_FILTER (items->data)) { - editor->filter = filters->data; + editor->filter = items->data; } } gimp_drawable_filters_editor_set_sensitive (drawable_view); - return FALSE; + g_list_free (items); } static void -gimp_drawable_filters_editor_view_activate_item (GtkWidget *widget, - GimpViewable *viewable, - gpointer insert_data, - GimpDrawableTreeView *view) +gimp_drawable_filters_editor_view_item_activated (GtkWidget *widget, + GimpViewable *viewable, + GimpDrawableTreeView *view) { GimpDrawableTreeViewFiltersEditor *editor = view->editor; @@ -614,8 +611,8 @@ gimp_drawable_filters_editor_active_changed (GimpFilter *filter, { GtkTreeIter *iter; - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), - (GimpViewable *) filter); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), + (GimpViewable *) filter); if (iter) gtk_tree_store_set (GTK_TREE_STORE (view->model), iter, diff --git a/app/widgets/gimpdrawabletreeview.c b/app/widgets/gimpdrawabletreeview.c index 71e931eb14..070afc73d9 100644 --- a/app/widgets/gimpdrawabletreeview.c +++ b/app/widgets/gimpdrawabletreeview.c @@ -76,15 +76,14 @@ static void gimp_drawable_tree_view_style_updated (GtkWidget static void gimp_drawable_tree_view_set_container (GimpContainerView *view, GimpContainer *container); +static gboolean gimp_drawable_tree_view_set_selected (GimpContainerView *view, + GList *items); + static gpointer gimp_drawable_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, gpointer parent_insert_data, gint index); -static gboolean gimp_drawable_tree_view_select_items (GimpContainerView *view, - GList *items, - GList *paths); - static gboolean gimp_drawable_tree_view_drop_possible (GimpContainerTreeView *view, GimpDndType src_type, GList *src_viewables, @@ -182,8 +181,9 @@ gimp_drawable_tree_view_view_iface_init (GimpContainerViewInterface *iface) parent_view_iface = g_type_interface_peek_parent (iface); iface->set_container = gimp_drawable_tree_view_set_container; + iface->set_selected = gimp_drawable_tree_view_set_selected; + iface->insert_item = gimp_drawable_tree_view_insert_item; - iface->select_items = gimp_drawable_tree_view_select_items; } static void @@ -340,36 +340,9 @@ gimp_drawable_tree_view_set_container (GimpContainerView *view, view); } -static gpointer -gimp_drawable_tree_view_insert_item (GimpContainerView *view, - GimpViewable *viewable, - gpointer parent_insert_data, - gint index) -{ - GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); - GimpDrawableTreeView *drawable_view = GIMP_DRAWABLE_TREE_VIEW (view); - GimpContainer *filters; - GtkTreeIter *iter; - gint n_filters; - - iter = parent_view_iface->insert_item (view, viewable, - parent_insert_data, index); - - filters = gimp_drawable_get_filters (GIMP_DRAWABLE (viewable)); - n_filters = gimp_container_get_n_children (filters); - - gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, - drawable_view->priv->model_column_filters, - n_filters > 0, - -1); - - return iter; -} - static gboolean -gimp_drawable_tree_view_select_items (GimpContainerView *view, - GList *items, - GList *paths) +gimp_drawable_tree_view_set_selected (GimpContainerView *view, + GList *items) { GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view); GimpImage *image = gimp_item_tree_view_get_image (item_view); @@ -397,11 +370,38 @@ gimp_drawable_tree_view_select_items (GimpContainerView *view, } if (success) - success = parent_view_iface->select_items (view, items, paths); + success = parent_view_iface->set_selected (view, items); return success; } +static gpointer +gimp_drawable_tree_view_insert_item (GimpContainerView *view, + GimpViewable *viewable, + gpointer parent_insert_data, + gint index) +{ + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); + GimpDrawableTreeView *drawable_view = GIMP_DRAWABLE_TREE_VIEW (view); + GimpContainer *filters; + GtkTreeIter *iter; + gint n_filters; + + iter = parent_view_iface->insert_item (view, viewable, + parent_insert_data, index); + + filters = gimp_drawable_get_filters (GIMP_DRAWABLE (viewable)); + n_filters = gimp_container_get_n_children (filters); + + gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, + drawable_view->priv->model_column_filters, + n_filters > 0, + -1); + + return iter; +} + + /* GimpContainerTreeView methods */ static gboolean @@ -567,7 +567,7 @@ gimp_drawable_tree_view_floating_selection_changed (GimpImage *image, items = g_list_copy (items); /* update button states */ - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (view), items); + gimp_container_view_set_selected (GIMP_CONTAINER_VIEW (view), items); g_list_free (items); } @@ -582,8 +582,8 @@ gimp_drawable_tree_view_filters_changed (GimpDrawable *drawable, GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), - (GimpViewable *) drawable); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), + (GimpViewable *) drawable); if (iter) { diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 545fe434a6..f15afcc0eb 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -105,6 +105,8 @@ struct _GimpItemTreeViewPrivate GtkWidget *multi_selection_label; GtkWidget *search_button; + + gint block_selection_changed; }; typedef struct @@ -153,6 +155,10 @@ static void gimp_item_tree_view_image_flush (GimpImage *image, static gboolean gimp_item_tree_view_image_flush_idle (gpointer user_data); +static void gimp_item_tree_view_selection_changed (GimpContainerView *view); +static void gimp_item_tree_view_item_activated (GimpContainerView *view, + GimpViewable *item); + static void gimp_item_tree_view_set_container (GimpContainerView *view, GimpContainer *container); static void gimp_item_tree_view_set_context (GimpContainerView *view, @@ -163,12 +169,6 @@ static gpointer gimp_item_tree_view_insert_item (GimpContainerView *view, gpointer parent_insert_data, gint index); static void gimp_item_tree_view_insert_items_after (GimpContainerView *view); -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); static gboolean gimp_item_tree_view_drop_possible (GimpContainerTreeView *view, GimpDndType src_type, @@ -194,7 +194,7 @@ static void gimp_item_tree_view_new_list_dropped (GtkWidget *widget, GList *viewables, gpointer data); -static void gimp_item_tree_view_item_changed (GimpImage *image, +static void gimp_item_tree_view_items_changed (GimpImage *image, GimpItemTreeView *view); static void gimp_item_tree_view_size_changed (GimpImage *image, GimpItemTreeView *view); @@ -346,12 +346,13 @@ gimp_item_tree_view_view_iface_init (GimpContainerViewInterface *iface) { parent_view_iface = g_type_interface_peek_parent (iface); + iface->selection_changed = gimp_item_tree_view_selection_changed; + iface->item_activated = gimp_item_tree_view_item_activated; iface->set_container = gimp_item_tree_view_set_container; iface->set_context = gimp_item_tree_view_set_context; + iface->insert_item = gimp_item_tree_view_insert_item; iface->insert_items_after = gimp_item_tree_view_insert_items_after; - iface->select_items = gimp_item_tree_view_select_items; - iface->activate_item = gimp_item_tree_view_activate_item; } static void @@ -862,8 +863,6 @@ gimp_item_tree_view_set_image (GimpItemTreeView *view, g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image)); g_signal_emit (view, view_signals[SET_IMAGE], 0, image); - - gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (view)), view); } GimpImage * @@ -1022,8 +1021,8 @@ gimp_item_tree_view_blink_lock (GimpItemTreeView *view, g_return_if_fail (GIMP_IS_ITEM (item)); /* Find the item in the tree view. */ - iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), - (GimpViewable *) item); + iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), + GIMP_VIEWABLE (item)); path = gtk_tree_model_get_path (GIMP_CONTAINER_TREE_VIEW (view)->model, iter); /* Scroll dockable to make sure the cell is showing. */ @@ -1113,7 +1112,7 @@ gimp_item_tree_view_real_set_image (GimpItemTreeView *view, if (view->priv->image) { g_signal_handlers_disconnect_by_func (view->priv->image, - gimp_item_tree_view_item_changed, + gimp_item_tree_view_items_changed, view); g_signal_handlers_disconnect_by_func (view->priv->image, gimp_item_tree_view_size_changed, @@ -1148,7 +1147,7 @@ gimp_item_tree_view_real_set_image (GimpItemTreeView *view, g_signal_connect (view->priv->image, GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->signal_name, - G_CALLBACK (gimp_item_tree_view_item_changed), + G_CALLBACK (gimp_item_tree_view_items_changed), view); g_signal_connect (view->priv->image, "size-changed", G_CALLBACK (gimp_item_tree_view_size_changed), @@ -1167,7 +1166,7 @@ gimp_item_tree_view_real_set_image (GimpItemTreeView *view, G_CALLBACK (gimp_item_tree_view_floating_selection_changed), view); - gimp_item_tree_view_item_changed (view->priv->image, view); + gimp_item_tree_view_items_changed (view->priv->image, view); } /* Call this even with no image, allowing to empty the link list. */ @@ -1244,6 +1243,44 @@ gimp_item_tree_view_image_flush_idle (gpointer user_data) /* GimpContainerView methods */ +static void +gimp_item_tree_view_selection_changed (GimpContainerView *view) +{ + GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view); + GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view); + + parent_view_iface->selection_changed (view); + + if (item_view->priv->block_selection_changed == 0) + { + GList *items; + + gimp_container_view_get_selected (view, &items); + + gimp_image_set_selected_items (item_view->priv->image, + item_view_class->item_type, + items); + + g_list_free (items); + } +} + +static void +gimp_item_tree_view_item_activated (GimpContainerView *view, + GimpViewable *item) +{ + GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view); + + parent_view_iface->item_activated (view, item); + + if (item_view_class->activate_action) + { + gimp_ui_manager_activate_action (gimp_editor_get_ui_manager (GIMP_EDITOR (view)), + item_view_class->action_group, + item_view_class->activate_action); + } +} + static void gimp_item_tree_view_set_container (GimpContainerView *view, GimpContainer *container) @@ -1409,79 +1446,7 @@ gimp_item_tree_view_insert_items_after (GimpContainerView *view) selected_items = gimp_image_get_selected_items (item_view->priv->image, item_view_class->item_type); - gimp_container_view_select_items (view, selected_items); -} - -static gboolean -gimp_item_tree_view_select_items (GimpContainerView *view, - GList *items, - GList *paths) -{ - GimpItemTreeView *tree_view = GIMP_ITEM_TREE_VIEW (view); - gboolean options_sensitive = FALSE; - gboolean success; - - success = parent_view_iface->select_items (view, items, paths); - - if (items) - { - GimpItemTreeViewClass *item_view_class; - - item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (tree_view); - - if (TRUE) /* XXX: test if new selection same as old. */ - { - gimp_image_set_selected_items (tree_view->priv->image, - item_view_class->item_type, - items); - - items = gimp_image_get_selected_items (tree_view->priv->image, - item_view_class->item_type); - } - - options_sensitive = TRUE; - } - - 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); - - if (g_list_length (items) > 1) - { - gchar *str; - - str = g_strdup_printf (ngettext ("%d item selected", "%d items selected", - g_list_length (items)), - g_list_length (items)); - gtk_label_set_text (GTK_LABEL (tree_view->priv->multi_selection_label), str); - g_free (str); - gtk_widget_set_opacity (tree_view->priv->multi_selection_label, 1.0); - } - else - { - gtk_widget_set_opacity (tree_view->priv->multi_selection_label, 0.0); - } - - return success; -} - -static void -gimp_item_tree_view_activate_item (GimpContainerView *view, - GimpViewable *item, - gpointer insert_data) -{ - GimpItemTreeViewClass *item_view_class = GIMP_ITEM_TREE_VIEW_GET_CLASS (view); - - if (parent_view_iface->activate_item) - parent_view_iface->activate_item (view, item, insert_data); - - if (item_view_class->activate_action) - { - gimp_ui_manager_activate_action (gimp_editor_get_ui_manager (GIMP_EDITOR (view)), - item_view_class->action_group, - item_view_class->activate_action); - } + gimp_container_view_set_selected (view, selected_items); } static gboolean @@ -1707,7 +1672,7 @@ gimp_item_tree_view_new_dropped (GtkWidget *widget, GimpContainerView *view = GIMP_CONTAINER_VIEW (data); if (item_view_class->new_default_action && - viewable && gimp_container_view_lookup (view, viewable)) + viewable && _gimp_container_view_lookup (view, viewable)) { GimpAction *action; @@ -1740,24 +1705,52 @@ gimp_item_tree_view_new_list_dropped (GtkWidget *widget, item_view_class->new_default_action); if (item_view_class->new_default_action && viewables && action && - gimp_container_view_contains (view, viewables)) + _gimp_container_view_contains (view, viewables)) gimp_action_activate (action); } + /* GimpImage callbacks */ static void -gimp_item_tree_view_item_changed (GimpImage *image, - GimpItemTreeView *view) +gimp_item_tree_view_items_changed (GimpImage *image, + GimpItemTreeView *item_view) { GType item_type; GList *items; - item_type = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->item_type; + item_type = GIMP_ITEM_TREE_VIEW_GET_CLASS (item_view)->item_type; - items = gimp_image_get_selected_items (view->priv->image, item_type); + items = gimp_image_get_selected_items (item_view->priv->image, item_type); - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (view), items); + item_view->priv->block_selection_changed++; + + gimp_container_view_set_selected (GIMP_CONTAINER_VIEW (item_view), items); + + item_view->priv->block_selection_changed--; + + gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (item_view)), + item_view); + + if (item_view->priv->options_box) + gtk_widget_set_sensitive (item_view->priv->options_box, items != NULL); + + if (g_list_length (items) > 1) + { + gchar *str; + + str = g_strdup_printf (ngettext ("%d item selected", "%d items selected", + g_list_length (items)), + g_list_length (items)); + gtk_label_set_text (GTK_LABEL (item_view->priv->multi_selection_label), + str); + g_free (str); + gtk_widget_set_opacity (item_view->priv->multi_selection_label, 1.0); + } + else + { + gtk_widget_set_opacity (item_view->priv->multi_selection_label, 0.0); + } } static void @@ -1842,8 +1835,7 @@ gimp_item_tree_view_visible_changed (GimpItem *item, GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (container_view, - (GimpViewable *) item); + iter = _gimp_container_view_lookup (container_view, GIMP_VIEWABLE (item)); if (iter) { @@ -1980,8 +1972,7 @@ gimp_item_tree_view_color_tag_changed (GimpItem *item, GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (container_view, - (GimpViewable *) item); + iter = _gimp_container_view_lookup (container_view, GIMP_VIEWABLE (item)); if (iter) { @@ -2024,8 +2015,7 @@ gimp_item_tree_view_lock_changed (GimpItem *item, const gchar *icon_name; gint n_locks; - iter = gimp_container_view_lookup (container_view, - (GimpViewable *) item); + iter = _gimp_container_view_lookup (container_view, GIMP_VIEWABLE (item)); n_locks = gimp_item_tree_view_get_n_locks (view, item, &icon_name); @@ -2291,7 +2281,7 @@ gimp_item_tree_view_row_expanded (GtkTreeView *tree_view, GimpViewRenderer *renderer; GimpItem *expanded_item; - store = GIMP_CONTAINER_TREE_STORE (GIMP_CONTAINER_TREE_VIEW (item_view)->model); + store = GIMP_CONTAINER_TREE_STORE (GIMP_CONTAINER_TREE_VIEW (item_view)->model); renderer = gimp_container_tree_store_get_renderer (store, iter); expanded_item = GIMP_ITEM (renderer->viewable); g_object_unref (renderer); @@ -2299,8 +2289,8 @@ gimp_item_tree_view_row_expanded (GtkTreeView *tree_view, for (list = selected_items; list; list = list->next) { /* don't select an item while it is being inserted */ - if (! gimp_container_view_lookup (GIMP_CONTAINER_VIEW (item_view), - list->data)) + if (! _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (item_view), + list->data)) return; /* select items only if they were made visible by expanding @@ -2310,8 +2300,12 @@ gimp_item_tree_view_row_expanded (GtkTreeView *tree_view, return; } - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (item_view), + item_view->priv->block_selection_changed++; + + gimp_container_view_set_selected (GIMP_CONTAINER_VIEW (item_view), selected_items); + + item_view->priv->block_selection_changed--; } } diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c index b43be582bc..9ef6b8f376 100644 --- a/app/widgets/gimplayertreeview.c +++ b/app/widgets/gimplayertreeview.c @@ -100,14 +100,14 @@ static void gimp_layer_tree_view_set_container (GimpContainer GimpContainer *container); static void gimp_layer_tree_view_set_context (GimpContainerView *view, GimpContext *context); +static void gimp_layer_tree_view_set_view_size (GimpContainerView *view); +static gboolean gimp_layer_tree_view_set_selected (GimpContainerView *view, + GList *items); + static gpointer gimp_layer_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, gpointer parent_insert_data, gint index); -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, GList *src_viewables, @@ -242,9 +242,10 @@ gimp_layer_tree_view_view_iface_init (GimpContainerViewInterface *iface) iface->set_container = gimp_layer_tree_view_set_container; iface->set_context = gimp_layer_tree_view_set_context; - iface->insert_item = gimp_layer_tree_view_insert_item; - iface->select_items = gimp_layer_tree_view_select_items; iface->set_view_size = gimp_layer_tree_view_set_view_size; + iface->set_selected = gimp_layer_tree_view_set_selected; + + iface->insert_item = gimp_layer_tree_view_insert_item; iface->model_is_tree = TRUE; } @@ -539,114 +540,6 @@ gimp_layer_tree_view_set_context (GimpContainerView *view, } } -static gpointer -gimp_layer_tree_view_insert_item (GimpContainerView *view, - GimpViewable *viewable, - gpointer parent_insert_data, - gint index) -{ - GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view); - GimpLayer *layer; - GtkTreeIter *iter; - - iter = parent_view_iface->insert_item (view, viewable, - parent_insert_data, index); - - layer = GIMP_LAYER (viewable); - - if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) - gimp_layer_tree_view_alpha_update (layer_view, iter, layer); - - gimp_layer_tree_view_mask_update (layer_view, iter, layer); - - if (GIMP_IS_LAYER (viewable) && gimp_layer_is_floating_sel (GIMP_LAYER (viewable))) - { - GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); - GimpLayer *floating = GIMP_LAYER (viewable); - GimpDrawable *drawable = gimp_layer_get_floating_sel_drawable (floating); - - if (GIMP_IS_LAYER_MASK (drawable)) - { - /* Display floating mask in the mask column. */ - GimpViewRenderer *renderer = NULL; - - gtk_tree_model_get (GTK_TREE_MODEL (tree_view->model), iter, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, - -1); - if (renderer) - { - gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, - layer_view->priv->model_column_mask, renderer, - layer_view->priv->model_column_mask_visible, TRUE, - GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, NULL, - -1); - g_object_unref (renderer); - } - } - } - - return iter; -} - -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) - { - if (g_list_length (items) == 1) - { - GtkTreeIter *iter = NULL; - - iter = - gimp_container_view_lookup (GIMP_CONTAINER_VIEW (layer_view), - GIMP_VIEWABLE (layers->data)); - - if (iter) - gimp_layer_tree_view_update_borders (layer_view, iter); - } - else - { - 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, items); - } - } - - if (! success) - { - GimpEditor *editor = GIMP_EDITOR (view); - - /* currently, select_items() 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; @@ -702,6 +595,95 @@ gimp_layer_tree_view_set_view_size (GimpContainerView *view) parent_view_iface->set_view_size (view); } +static gboolean +gimp_layer_tree_view_set_selected (GimpContainerView *view, + GList *items) +{ + GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view); + gboolean success; + + success = parent_view_iface->set_selected (view, items); + + if (items && success) + { + GList *list; + + for (list = items; list; list = g_list_next (list)) + { + GtkTreeIter *iter; + + iter = _gimp_container_view_lookup (view, list->data); + + if (iter) + gimp_layer_tree_view_update_borders (layer_view, iter); + } + + gimp_layer_tree_view_update_options (layer_view, items); + } + + if (! success) + { + GimpEditor *editor = GIMP_EDITOR (view); + + /* currently, select_items() 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; +} + +static gpointer +gimp_layer_tree_view_insert_item (GimpContainerView *view, + GimpViewable *viewable, + gpointer parent_insert_data, + gint index) +{ + GimpLayerTreeView *layer_view = GIMP_LAYER_TREE_VIEW (view); + GimpLayer *layer; + GtkTreeIter *iter; + + iter = parent_view_iface->insert_item (view, viewable, + parent_insert_data, index); + + layer = GIMP_LAYER (viewable); + + if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) + gimp_layer_tree_view_alpha_update (layer_view, iter, layer); + + gimp_layer_tree_view_mask_update (layer_view, iter, layer); + + if (GIMP_IS_LAYER (viewable) && gimp_layer_is_floating_sel (GIMP_LAYER (viewable))) + { + GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); + GimpLayer *floating = GIMP_LAYER (viewable); + GimpDrawable *drawable = gimp_layer_get_floating_sel_drawable (floating); + + if (GIMP_IS_LAYER_MASK (drawable)) + { + /* Display floating mask in the mask column. */ + GimpViewRenderer *renderer = NULL; + + gtk_tree_model_get (GTK_TREE_MODEL (tree_view->model), iter, + GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer, + -1); + if (renderer) + { + gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, + layer_view->priv->model_column_mask, renderer, + layer_view->priv->model_column_mask_visible, TRUE, + GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, NULL, + -1); + g_object_unref (renderer); + } + } + } + + return iter; +} + /* GimpContainerTreeView methods */ @@ -963,7 +945,7 @@ gimp_layer_tree_view_floating_selection_changed (GimpImage *image, if (floating_sel) { - iter = gimp_container_view_lookup (view, (GimpViewable *) floating_sel); + iter = _gimp_container_view_lookup (view, (GimpViewable *) floating_sel); if (iter) gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, @@ -982,7 +964,7 @@ gimp_layer_tree_view_floating_selection_changed (GimpImage *image, { GimpDrawable *drawable = list->data; - iter = gimp_container_view_lookup (view, (GimpViewable *) drawable); + iter = _gimp_container_view_lookup (view, (GimpViewable *) drawable); if (iter) gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), iter, @@ -1333,7 +1315,7 @@ gimp_layer_tree_view_mask_changed (GimpLayer *layer, GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (view, GIMP_VIEWABLE (layer)); + iter = _gimp_container_view_lookup (view, GIMP_VIEWABLE (layer)); if (iter) gimp_layer_tree_view_mask_update (layer_view, iter, layer); @@ -1350,8 +1332,8 @@ gimp_layer_tree_view_renderer_update (GimpViewRenderer *renderer, mask = GIMP_LAYER_MASK (renderer->viewable); - iter = gimp_container_view_lookup (view, (GimpViewable *) - gimp_layer_mask_get_layer (mask)); + iter = _gimp_container_view_lookup (view, (GimpViewable *) + gimp_layer_mask_get_layer (mask)); if (iter) { @@ -1440,7 +1422,7 @@ gimp_layer_tree_view_mask_callback (GimpLayer *layer, GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (view, (GimpViewable *) layer); + iter = _gimp_container_view_lookup (view, (GimpViewable *) layer); gimp_layer_tree_view_update_borders (layer_view, iter); } @@ -1667,18 +1649,22 @@ gimp_layer_tree_view_alpha_changed (GimpLayer *layer, GimpContainerView *view = GIMP_CONTAINER_VIEW (layer_view); GtkTreeIter *iter; - iter = gimp_container_view_lookup (view, (GimpViewable *) layer); + iter = _gimp_container_view_lookup (view, (GimpViewable *) layer); if (iter) { GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view); + GimpImage *image; + GList *layers; gimp_layer_tree_view_alpha_update (layer_view, iter, layer); + image = gimp_item_tree_view_get_image (item_view); + layers = gimp_image_get_selected_layers (image); + /* update button states */ - if (g_list_find (gimp_image_get_selected_layers (gimp_item_tree_view_get_image (item_view)), - layer)) - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (view), - gimp_image_get_selected_layers (gimp_item_tree_view_get_image (item_view))); + if (g_list_find (layers, layer)) + gimp_container_view_set_selected (GIMP_CONTAINER_VIEW (view), + layers); } } diff --git a/app/widgets/gimppickablechooser.c b/app/widgets/gimppickablechooser.c index 82692c53af..85ba483b44 100644 --- a/app/widgets/gimppickablechooser.c +++ b/app/widgets/gimppickablechooser.c @@ -91,13 +91,10 @@ static void gimp_pickable_chooser_get_property (GObject *object, static void gimp_pickable_chooser_image_changed (GimpContext *context, GimpImage *image, GimpPickableChooser *chooser); -static void gimp_pickable_chooser_item_activate (GimpContainerView *view, +static void gimp_pickable_chooser_item_activated (GimpContainerView *view, GimpPickable *pickable, - gpointer unused, GimpPickableChooser *chooser); static void gimp_pickable_chooser_items_selected (GimpContainerView *view, - GList *items, - GList *paths, GimpPickableChooser *chooser); @@ -122,7 +119,7 @@ gimp_pickable_chooser_class_init (GimpPickableChooserClass *klass) * @chooser: * * Emitted when a pickable is activated, which is mostly forwarding when - * "activate-item" signal is emitted from any of either the image, layer or + * "item-activated" signal is emitted from any of either the image, layer or * channel view. E.g. this happens when one double-click on one of the * pickables. */ @@ -229,10 +226,10 @@ gimp_pickable_chooser_constructed (GObject *object) gtk_box_pack_start (GTK_BOX (vbox), chooser->priv->image_view, TRUE, TRUE, 0); gtk_widget_show (chooser->priv->image_view); - g_signal_connect_object (chooser->priv->image_view, "activate-item", - G_CALLBACK (gimp_pickable_chooser_item_activate), + g_signal_connect_object (chooser->priv->image_view, "item-activated", + G_CALLBACK (gimp_pickable_chooser_item_activated), G_OBJECT (chooser), 0); - g_signal_connect_object (chooser->priv->image_view, "select-items", + g_signal_connect_object (chooser->priv->image_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); @@ -270,10 +267,10 @@ gimp_pickable_chooser_constructed (GObject *object) gtk_label_new (_("Layers"))); gtk_widget_show (chooser->priv->layer_view); - g_signal_connect_object (chooser->priv->layer_view, "activate-item", - G_CALLBACK (gimp_pickable_chooser_item_activate), + g_signal_connect_object (chooser->priv->layer_view, "item-activated", + G_CALLBACK (gimp_pickable_chooser_item_activated), G_OBJECT (chooser), 0); - g_signal_connect_object (chooser->priv->layer_view, "select-items", + g_signal_connect_object (chooser->priv->layer_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } @@ -295,10 +292,10 @@ gimp_pickable_chooser_constructed (GObject *object) gtk_label_new (_("Channels"))); gtk_widget_show (chooser->priv->channel_view); - g_signal_connect_object (chooser->priv->channel_view, "activate-item", - G_CALLBACK (gimp_pickable_chooser_item_activate), + g_signal_connect_object (chooser->priv->channel_view, "item-activated", + G_CALLBACK (gimp_pickable_chooser_item_activated), G_OBJECT (chooser), 0); - g_signal_connect_object (chooser->priv->channel_view, "select-items", + g_signal_connect_object (chooser->priv->channel_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } @@ -456,37 +453,37 @@ gimp_pickable_chooser_set_pickable (GimpPickableChooser *chooser, if (GIMP_IS_IMAGE (pickable)) { - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (chooser->priv->image_view), - GIMP_VIEWABLE (pickable)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->image_view), + GIMP_VIEWABLE (pickable)); gimp_context_set_image (chooser->priv->context, GIMP_IMAGE (pickable)); } else if (GIMP_IS_LAYER (pickable)) { gimp_context_set_image (chooser->priv->context, gimp_item_get_image (GIMP_ITEM (pickable))); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (chooser->priv->layer_view), - GIMP_VIEWABLE (pickable)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->layer_view), + GIMP_VIEWABLE (pickable)); } else if (GIMP_IS_CHANNEL (pickable)) { gimp_context_set_image (chooser->priv->context, gimp_item_get_image (GIMP_ITEM (pickable))); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (chooser->priv->channel_view), - GIMP_VIEWABLE (pickable)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->channel_view), + GIMP_VIEWABLE (pickable)); } else { g_return_if_fail (pickable == NULL); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (chooser->priv->image_view), NULL); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (chooser->priv->image_view), NULL); gimp_context_set_image (chooser->priv->context, NULL); } - g_signal_connect_object (chooser->priv->image_view, "select-items", + g_signal_connect_object (chooser->priv->image_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); if (chooser->priv->layer_view != NULL) - g_signal_connect_object (chooser->priv->layer_view, "select-items", + g_signal_connect_object (chooser->priv->layer_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); if (chooser->priv->channel_view != NULL) - g_signal_connect_object (chooser->priv->channel_view, "select-items", + g_signal_connect_object (chooser->priv->channel_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } @@ -537,7 +534,7 @@ gimp_pickable_chooser_image_changed (GimpContext *context, chooser); gimp_container_view_set_container (GIMP_CONTAINER_VIEW (chooser->priv->layer_view), layers); - g_signal_connect_object (chooser->priv->layer_view, "select-items", + g_signal_connect_object (chooser->priv->layer_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } @@ -548,35 +545,36 @@ gimp_pickable_chooser_image_changed (GimpContext *context, chooser); gimp_container_view_set_container (GIMP_CONTAINER_VIEW (chooser->priv->channel_view), channels); - g_signal_connect_object (chooser->priv->channel_view, "select-items", + g_signal_connect_object (chooser->priv->channel_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } - g_signal_connect_object (chooser->priv->image_view, "select-items", + g_signal_connect_object (chooser->priv->image_view, "selection-changed", G_CALLBACK (gimp_pickable_chooser_items_selected), G_OBJECT (chooser), 0); } static void -gimp_pickable_chooser_item_activate (GimpContainerView *view, - GimpPickable *pickable, - gpointer unused, - GimpPickableChooser *chooser) +gimp_pickable_chooser_item_activated (GimpContainerView *view, + GimpPickable *pickable, + GimpPickableChooser *chooser) { g_signal_emit (chooser, signals[ACTIVATE], 0, pickable); } static void gimp_pickable_chooser_items_selected (GimpContainerView *view, - GList *items, - GList *paths, GimpPickableChooser *chooser) { GimpPickable *pickable = NULL; + gint n_items; + GList *items; - g_return_if_fail (g_list_length (items) <= 1); + n_items = gimp_container_view_get_selected (view, &items); - if (items != NULL) + g_return_if_fail (n_items <= 1); + + if (items) pickable = items->data; gimp_pickable_chooser_set_pickable (chooser, pickable); diff --git a/app/widgets/gimpsettingsbox.c b/app/widgets/gimpsettingsbox.c index d1adb8e161..2588d27c28 100644 --- a/app/widgets/gimpsettingsbox.c +++ b/app/widgets/gimpsettingsbox.c @@ -90,7 +90,8 @@ struct _GimpSettingsBoxPrivate GFile *last_file; }; -#define GET_PRIVATE(item) ((GimpSettingsBoxPrivate *) gimp_settings_box_get_instance_private ((GimpSettingsBox *) (item))) +#define GET_PRIVATE(item) \ + ((GimpSettingsBoxPrivate *) gimp_settings_box_get_instance_private ((GimpSettingsBox *) (item))) static void gimp_settings_box_constructed (GObject *object); @@ -112,10 +113,7 @@ static gboolean gimp_settings_box_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data); -static gboolean - gimp_settings_box_setting_selected (GimpContainerView *view, - GList *objects, - GList *paths, +static void gimp_settings_box_setting_selected (GimpContainerView *view, GimpSettingsBox *box); static gboolean gimp_settings_box_menu_press (GtkWidget *widget, GdkEventButton *bevent, @@ -304,7 +302,7 @@ gimp_settings_box_constructed (GObject *object) gimp_help_set_help_data (private->combo, _("Pick a preset from the list"), NULL); - g_signal_connect_after (private->combo, "select-items", + g_signal_connect_after (private->combo, "selection_changed", G_CALLBACK (gimp_settings_box_setting_selected), box); @@ -541,19 +539,22 @@ gimp_settings_box_row_separator_func (GtkTreeModel *model, return name == NULL; } -static gboolean +static void gimp_settings_box_setting_selected (GimpContainerView *view, - GList *objects, - GList *paths, GimpSettingsBox *box) { - g_return_val_if_fail (g_list_length (objects) < 2, FALSE); + GList *items; + gint n_items; - if (objects) + n_items = gimp_container_view_get_selected (view, &items); + + g_warn_if_fail (n_items < 2); + + if (items) g_signal_emit (box, settings_box_signals[SELECTED], 0, - objects->data); + items->data); - return TRUE; + g_list_free (items); } static gboolean @@ -920,14 +921,12 @@ void gimp_settings_box_add_current (GimpSettingsBox *box, gint max_recent) { - GimpSettingsBoxPrivate *private; - GimpConfig *config = NULL; + GimpSettingsBoxPrivate *private = GET_PRIVATE (box); + GimpConfig *config = NULL; GList *list; g_return_if_fail (GIMP_IS_SETTINGS_BOX (box)); - private = GET_PRIVATE (box); - for (list = GIMP_LIST (private->container)->queue->head; list; list = g_list_next (list)) @@ -977,11 +976,9 @@ gimp_settings_box_add_current (GimpSettingsBox *box, void gimp_settings_box_unset (GimpSettingsBox *box) { - GimpSettingsBoxPrivate *private; + GimpSettingsBoxPrivate *private = GET_PRIVATE (box);; g_return_if_fail (GIMP_IS_SETTINGS_BOX (box)); - private = GET_PRIVATE (box); - - gimp_container_view_select_items (GIMP_CONTAINER_VIEW (private->combo), NULL); + gimp_container_view_set_selected (GIMP_CONTAINER_VIEW (private->combo), NULL); } diff --git a/app/widgets/gimpsettingseditor.c b/app/widgets/gimpsettingseditor.c index 76946b7f4e..f32d0823eb 100644 --- a/app/widgets/gimpsettingseditor.c +++ b/app/widgets/gimpsettingseditor.c @@ -89,9 +89,8 @@ static gboolean gimp_settings_editor_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data); -static gboolean gimp_settings_editor_select_items (GimpContainerView *view, - GList *viewables, - GList *paths, +static void gimp_settings_editor_selection_changed + (GimpContainerView *view, GimpSettingsEditor *editor); static void gimp_settings_editor_import_clicked (GtkWidget *widget, GimpSettingsEditor *editor); @@ -178,8 +177,8 @@ gimp_settings_editor_constructed (GObject *object) gimp_settings_editor_row_separator_func, private->view, NULL); - g_signal_connect (tree_view, "select-items", - G_CALLBACK (gimp_settings_editor_select_items), + g_signal_connect (tree_view, "selection-changed", + G_CALLBACK (gimp_settings_editor_selection_changed), editor); gimp_container_tree_view_connect_name_edited (tree_view, @@ -298,26 +297,31 @@ gimp_settings_editor_row_separator_func (GtkTreeModel *model, return name == NULL; } -static gboolean -gimp_settings_editor_select_items (GimpContainerView *view, - GList *viewables, - GList *paths, - GimpSettingsEditor *editor) +static void +gimp_settings_editor_selection_changed (GimpContainerView *view, + GimpSettingsEditor *editor) { GimpSettingsEditorPrivate *private = GET_PRIVATE (editor); gboolean sensitive; + GList *items; + gint n_items; - g_return_val_if_fail (g_list_length (viewables) < 2, FALSE); + n_items = gimp_container_view_get_selected (view, &items); - private->selected_setting = viewables ? G_OBJECT (viewables->data) : NULL; + g_warn_if_fail (n_items < 2); + + if (n_items == 1) + private->selected_setting = items->data; + else + private->selected_setting = NULL; + + g_list_free (items); sensitive = (private->selected_setting != NULL && gimp_object_get_name (private->selected_setting)); gtk_widget_set_sensitive (private->export_button, sensitive); gtk_widget_set_sensitive (private->delete_button, sensitive); - - return TRUE; } static void @@ -352,8 +356,8 @@ gimp_settings_editor_delete_clicked (GtkWidget *widget, gimp_container_remove (private->container, GIMP_OBJECT (private->selected_setting)); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (private->view), - GIMP_VIEWABLE (new)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (private->view), + GIMP_VIEWABLE (new)); gimp_operation_config_serialize (private->gimp, private->container, NULL); } diff --git a/app/widgets/gimptooleditor.c b/app/widgets/gimptooleditor.c index a79b41b46c..cc033a693d 100644 --- a/app/widgets/gimptooleditor.c +++ b/app/widgets/gimptooleditor.c @@ -76,13 +76,12 @@ static void gimp_tool_editor_view_iface_init (GimpContainer static void gimp_tool_editor_constructed (GObject *object); -static gboolean gimp_tool_editor_select_items (GimpContainerView *view, - GList *items, - GList *paths); static void gimp_tool_editor_set_container (GimpContainerView *container_view, GimpContainer *container); static void gimp_tool_editor_set_context (GimpContainerView *container_view, GimpContext *context); +static gboolean gimp_tool_editor_set_selected (GimpContainerView *view, + GList *items); static gboolean gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view, GimpDndType src_type, @@ -169,9 +168,9 @@ gimp_tool_editor_view_iface_init (GimpContainerViewInterface *iface) if (! parent_view_iface) parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW); - iface->select_items = gimp_tool_editor_select_items; iface->set_container = gimp_tool_editor_set_container; iface->set_context = gimp_tool_editor_set_context; + iface->set_selected = gimp_tool_editor_set_selected; } static void @@ -278,22 +277,6 @@ gimp_tool_editor_constructed (GObject *object) gimp_tool_editor_update_sensitivity (tool_editor); } -static gboolean -gimp_tool_editor_select_items (GimpContainerView *container_view, - GList *viewables, - GList *paths) -{ - GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view); - gboolean result; - - result = parent_view_iface->select_items (container_view, - viewables, paths); - - gimp_tool_editor_update_sensitivity (tool_editor); - - return result; -} - static void gimp_tool_editor_set_container (GimpContainerView *container_view, GimpContainer *container) @@ -316,6 +299,20 @@ gimp_tool_editor_set_context (GimpContainerView *container_view, gimp_tool_editor_update_container (tool_editor); } +static gboolean +gimp_tool_editor_set_selected (GimpContainerView *container_view, + GList *items) +{ + GimpToolEditor *tool_editor = GIMP_TOOL_EDITOR (container_view); + gboolean result; + + result = parent_view_iface->set_selected (container_view, items); + + gimp_tool_editor_update_sensitivity (tool_editor); + + return result; +} + static gboolean gimp_tool_editor_drop_possible (GimpContainerTreeView *tree_view, GimpDndType src_type, @@ -367,7 +364,7 @@ gimp_tool_editor_drop_viewables (GimpContainerTreeView *tree_view, drop_pos); if (src_viewables) - gimp_container_view_select_items (container_view, src_viewables); + gimp_container_view_set_selected (container_view, src_viewables); } static void @@ -406,7 +403,8 @@ gimp_tool_editor_new_group_clicked (GtkButton *button, g_object_unref (group); - gimp_container_view_select_item (container_view, GIMP_VIEWABLE (group)); + gimp_container_view_set_1_selected (container_view, + GIMP_VIEWABLE (group)); } } @@ -566,10 +564,10 @@ gimp_tool_editor_delete_clicked (GtkButton *button, gimp_container_thaw (dest_container); gimp_container_thaw (src_container); - gimp_container_view_select_item ( - container_view, - GIMP_VIEWABLE (gimp_container_get_child_by_index (dest_container, - index))); + gimp_container_view_set_1_selected + (container_view, + GIMP_VIEWABLE (gimp_container_get_child_by_index (dest_container, + index))); g_object_unref (tool_item); } @@ -593,7 +591,7 @@ gimp_tool_editor_tool_item_notify (GimpToolItem *tool_item, GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tool_editor); GtkTreeIter *iter; - iter = gimp_container_view_lookup (container_view, + iter = _gimp_container_view_lookup (container_view, GIMP_VIEWABLE (tool_item)); if (iter) diff --git a/app/widgets/gimpundoeditor.c b/app/widgets/gimpundoeditor.c index 52e8ef51aa..eb0ea51227 100644 --- a/app/widgets/gimpundoeditor.c +++ b/app/widgets/gimpundoeditor.c @@ -72,9 +72,8 @@ static void gimp_undo_editor_undo_event (GimpImage *image, GimpUndo *undo, GimpUndoEditor *editor); -static gboolean gimp_undo_editor_select_items (GimpContainerView *view, - GList *undos, - GList *paths, +static void gimp_undo_editor_selection_changed + (GimpContainerView *view, GimpUndoEditor *editor); @@ -138,8 +137,8 @@ gimp_undo_editor_constructed (GObject *object) gtk_box_pack_start (GTK_BOX (undo_editor), undo_editor->view, TRUE, TRUE, 0); gtk_widget_show (undo_editor->view); - g_signal_connect (undo_editor->view, "select-items", - G_CALLBACK (gimp_undo_editor_select_items), + g_signal_connect (undo_editor->view, "selection-changed", + G_CALLBACK (gimp_undo_editor_selection_changed), undo_editor); undo_editor->undo_button = @@ -299,25 +298,25 @@ gimp_undo_editor_fill (GimpUndoEditor *editor) top_undo_item = gimp_undo_stack_peek (undo_stack); g_signal_handlers_block_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); /* select the current state of the image */ if (top_undo_item) { - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view), - GIMP_VIEWABLE (top_undo_item)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (editor->view), + GIMP_VIEWABLE (top_undo_item)); gimp_undo_create_preview (top_undo_item, editor->context, FALSE); } else { - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view), - GIMP_VIEWABLE (editor->base_item)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (editor->view), + GIMP_VIEWABLE (editor->base_item)); gimp_undo_create_preview (editor->base_item, editor->context, TRUE); } g_signal_handlers_unblock_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); } @@ -347,16 +346,16 @@ gimp_undo_editor_undo_event (GimpImage *image, { case GIMP_UNDO_EVENT_UNDO_PUSHED: g_signal_handlers_block_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); gimp_container_insert (editor->container, GIMP_OBJECT (undo), -1); - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view), - GIMP_VIEWABLE (undo)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (editor->view), + GIMP_VIEWABLE (undo)); gimp_undo_create_preview (undo, editor->context, FALSE); g_signal_handlers_unblock_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); break; @@ -368,24 +367,24 @@ gimp_undo_editor_undo_event (GimpImage *image, case GIMP_UNDO_EVENT_UNDO: case GIMP_UNDO_EVENT_REDO: g_signal_handlers_block_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); if (top_undo_item) { - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view), - GIMP_VIEWABLE (top_undo_item)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (editor->view), + GIMP_VIEWABLE (top_undo_item)); gimp_undo_create_preview (top_undo_item, editor->context, FALSE); } else { - gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view), - GIMP_VIEWABLE (editor->base_item)); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (editor->view), + GIMP_VIEWABLE (editor->base_item)); gimp_undo_create_preview (editor->base_item, editor->context, TRUE); } g_signal_handlers_unblock_by_func (editor->view, - gimp_undo_editor_select_items, + gimp_undo_editor_selection_changed, editor); break; @@ -404,11 +403,9 @@ gimp_undo_editor_undo_event (GimpImage *image, } } -static gboolean -gimp_undo_editor_select_items (GimpContainerView *view, - GList *undos, - GList *paths, - GimpUndoEditor *editor) +static void +gimp_undo_editor_selection_changed (GimpContainerView *view, + GimpUndoEditor *editor) { GimpImage *image = GIMP_IMAGE_EDITOR (editor)->image; GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image); @@ -416,12 +413,10 @@ gimp_undo_editor_select_items (GimpContainerView *view, GimpUndo *top_undo_item; GimpUndo *undo; - g_return_val_if_fail (g_list_length (undos) < 2, FALSE); + undo = GIMP_UNDO (gimp_container_view_get_1_selected (view)); - if (! undos) - return TRUE; - - undo = undos->data; + if (! undo) + return; top_undo_item = gimp_undo_stack_peek (undo_stack); @@ -465,6 +460,4 @@ gimp_undo_editor_select_items (GimpContainerView *view, } gimp_image_flush (image); - - return TRUE; }