From f96a7192cd1c2b187765ab1f799eea1a5add55a3 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Tue, 12 Aug 2025 11:53:26 +0200 Subject: [PATCH] app: add GimpRowFilter and GimpRowDrawableFilter and port the filters popover to GimpContainerListView. --- app/widgets/gimpdrawabletreeview-filters.c | 169 +++--------------- app/widgets/gimprow-utils.c | 18 +- app/widgets/gimprowdrawablefilter.c | 81 +++++++++ app/widgets/gimprowdrawablefilter.h | 30 ++++ app/widgets/gimprowfilter.c | 196 +++++++++++++++++++++ app/widgets/gimprowfilter.h | 42 +++++ app/widgets/meson.build | 2 + 7 files changed, 392 insertions(+), 146 deletions(-) create mode 100644 app/widgets/gimprowdrawablefilter.c create mode 100644 app/widgets/gimprowdrawablefilter.h create mode 100644 app/widgets/gimprowfilter.c create mode 100644 app/widgets/gimprowfilter.h diff --git a/app/widgets/gimpdrawabletreeview-filters.c b/app/widgets/gimpdrawabletreeview-filters.c index 871ab88bc4..81797ae0b2 100644 --- a/app/widgets/gimpdrawabletreeview-filters.c +++ b/app/widgets/gimpdrawabletreeview-filters.c @@ -40,25 +40,18 @@ #include "core/gimpdrawablefilter.h" #include "core/gimplist.h" #include "core/gimpimage.h" -#include "core/gimpimage-undo.h" #include "core/gimpimage-undo-push.h" -#include "core/gimptreehandler.h" #include "tools/tool_manager.h" /* FIXME */ -#include "gimpcontainertreestore.h" +#include "gimpcontainerlistview.h" #include "gimpcontainerview.h" -#include "gimpcontainerview-cruft.h" #include "gimpdrawabletreeview.h" #include "gimpdrawabletreeview-filters.h" -#include "gimpviewrenderer.h" #include "gimp-intl.h" -#define COLUMN_FILTERS_ACTIVE 3 - - struct _GimpDrawableTreeViewFiltersEditor { GimpDrawable *drawable; @@ -67,8 +60,8 @@ struct _GimpDrawableTreeViewFiltersEditor GtkWidget *popover; GtkWidget *vbox; GtkWidget *view; - GtkWidget *options; + GtkWidget *options; GtkWidget *visible_button; GtkWidget *edit_button; GtkWidget *raise_button; @@ -76,8 +69,7 @@ struct _GimpDrawableTreeViewFiltersEditor GtkWidget *merge_button; GtkWidget *remove_button; - GimpTreeHandler *active_changed_handler; - GimpTreeHandler *notify_temporary_handler; + GQuark notify_temporary_handler; }; @@ -91,15 +83,7 @@ static void gimp_drawable_filters_editor_view_item_activated (GtkWidget *widget, GimpViewable *viewable, GimpDrawableTreeView *view); -static void gimp_drawable_filters_editor_view_visible_cell_toggled - (GtkCellRendererToggle *toggle, - gchar *path_str, - GdkModifierType state, - GimpContainerTreeView *view); -static void gimp_drawable_filters_editor_active_changed - (GimpFilter *filter, - GimpContainerTreeView *view); static void gimp_drawable_filters_editor_temporary_changed (GimpFilter *filter, const GParamSpec *pspec, @@ -322,79 +306,35 @@ _gimp_drawable_tree_view_filter_editor_show (GimpDrawableTreeView *view, /* only show if we have at least one editable filter */ if (n_editable > 0) { - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GimpContainerTreeView *filter_tree_view; - GtkWidget *scrolled_window; + GtkWidget *scrolled_window; editor->drawable = drawable; - editor->view = gimp_container_tree_view_new (filters, + editor->view = gimp_container_list_view_new (filters, gimp_container_view_get_context (GIMP_CONTAINER_VIEW (view)), GIMP_VIEW_SIZE_SMALL, 0); - filter_tree_view = GIMP_CONTAINER_TREE_VIEW (editor->view); - - /* Connect filter active signal */ - editor->active_changed_handler = - gimp_tree_handler_connect (filters, "active-changed", - G_CALLBACK (gimp_drawable_filters_editor_active_changed), - editor->view); editor->notify_temporary_handler = - gimp_tree_handler_connect (filters, "notify::temporary", - G_CALLBACK (gimp_drawable_filters_editor_temporary_changed), - view); + gimp_container_add_handler (filters, "notify::temporary", + G_CALLBACK (gimp_drawable_filters_editor_temporary_changed), + view); g_signal_connect (drawable, "filters-changed", G_CALLBACK (gimp_drawable_filters_editor_filters_changed), view); - gimp_container_tree_store_columns_add (filter_tree_view->model_columns, - &filter_tree_view->n_model_columns, - G_TYPE_BOOLEAN); - - /* Set up individual visibility toggles */ - column = gtk_tree_view_column_new (); - renderer = gimp_cell_renderer_toggle_new (GIMP_ICON_VISIBLE); - gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE); - gtk_tree_view_column_pack_end (column, renderer, FALSE); - gtk_tree_view_column_set_attributes (column, renderer, - "active", - COLUMN_FILTERS_ACTIVE, - NULL); - - gtk_tree_view_append_column (filter_tree_view->view, column); - gtk_tree_view_move_column_after (filter_tree_view->view, column, NULL); - gimp_container_tree_view_add_toggle_cell (filter_tree_view, renderer); - - g_signal_connect_object (renderer, "clicked", - G_CALLBACK (gimp_drawable_filters_editor_view_visible_cell_toggled), - filter_tree_view, 0); - - /* Update filter visible icon */ - for (list = GIMP_LIST (filters)->queue->tail; - list; - list = g_list_previous (list)) - { - if (GIMP_IS_DRAWABLE_FILTER (list->data)) - { - gimp_drawable_filters_editor_active_changed (list->data, - filter_tree_view); - } - } - - g_signal_connect (filter_tree_view, "selection-changed", + g_signal_connect (editor->view, "selection-changed", G_CALLBACK (gimp_drawable_filters_editor_view_selection_changed), view); - g_signal_connect_object (filter_tree_view, "item-activated", + g_signal_connect_object (editor->view, "item-activated", G_CALLBACK (gimp_drawable_filters_editor_view_item_activated), view, 0); - gtk_box_pack_start (GTK_BOX (editor->vbox), - editor->view, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (editor->vbox), editor->view, + TRUE, TRUE, 0); gtk_widget_show (editor->view); - scrolled_window = gtk_widget_get_parent (GTK_WIDGET (filter_tree_view->view)); + scrolled_window = GIMP_CONTAINER_BOX (editor->view)->scrolled_win; gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); @@ -422,8 +362,10 @@ _gimp_drawable_tree_view_filter_editor_hide (GimpDrawableTreeView *view) if (! editor) return; - if (editor->active_changed_handler) + if (editor->notify_temporary_handler) { + GimpContainer *filters = gimp_drawable_get_filters (editor->drawable); + g_signal_handlers_disconnect_by_func (editor->popover, _gimp_drawable_tree_view_filter_editor_hide, view); @@ -432,10 +374,9 @@ _gimp_drawable_tree_view_filter_editor_hide (GimpDrawableTreeView *view) gimp_drawable_filters_editor_filters_changed, view); - g_clear_pointer (&editor->notify_temporary_handler, - gimp_tree_handler_disconnect); - g_clear_pointer (&editor->active_changed_handler, - gimp_tree_handler_disconnect); + gimp_container_remove_handler (filters, + editor->notify_temporary_handler); + editor->notify_temporary_handler = 0; } gtk_popover_popdown (GTK_POPOVER (editor->popover)); @@ -531,27 +472,22 @@ gimp_drawable_filters_editor_view_selection_changed (GimpContainerView *view, GimpDrawableTreeView *drawable_view) { GimpDrawableTreeViewFiltersEditor *editor = drawable_view->editor; - GList *items; - gint n_items; + GimpViewable *viewable; - n_items = gimp_container_view_get_selected (view, &items); - - g_warn_if_fail (n_items <= 1); + viewable = gimp_container_view_get_1_selected (view); editor->filter = NULL; - if (items) + if (viewable) { /* Don't set floating selection as active filter */ - if (GIMP_IS_DRAWABLE_FILTER (items->data)) + if (GIMP_IS_DRAWABLE_FILTER (viewable)) { - editor->filter = items->data; + editor->filter = GIMP_DRAWABLE_FILTER (viewable); } } gimp_drawable_filters_editor_set_sensitive (drawable_view); - - g_list_free (items); } static void @@ -565,63 +501,6 @@ gimp_drawable_filters_editor_view_item_activated (GtkWidget *widget, gimp_drawable_filters_editor_edit_clicked (widget, view); } -static void -gimp_drawable_filters_editor_view_visible_cell_toggled (GtkCellRendererToggle *toggle, - gchar *path_str, - GdkModifierType state, - GimpContainerTreeView *view) -{ - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new_from_string (path_str); - - if (gtk_tree_model_get_iter (view->model, &iter, path)) - { - GimpContainerTreeStore *store; - GimpViewRenderer *renderer; - GimpDrawableFilter *filter; - - store = GIMP_CONTAINER_TREE_STORE (view->model); - - renderer = gimp_container_tree_store_get_renderer (store, &iter); - filter = GIMP_DRAWABLE_FILTER (renderer->viewable); - g_object_unref (renderer); - - if (GIMP_IS_DRAWABLE_FILTER (filter)) - { - GimpDrawable *drawable; - gboolean active; - - g_object_get (toggle, - "active", &active, - NULL); - - drawable = gimp_drawable_filter_get_drawable (filter); - gimp_filter_set_active (GIMP_FILTER (filter), ! active); - - gimp_drawable_update (drawable, 0, 0, -1, -1); - gimp_image_flush (gimp_item_get_image (GIMP_ITEM (drawable))); - } - } -} - -static void -gimp_drawable_filters_editor_active_changed (GimpFilter *filter, - GimpContainerTreeView *view) -{ - GtkTreeIter *iter; - - iter = _gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view), - (GimpViewable *) filter); - - if (iter) - gtk_tree_store_set (GTK_TREE_STORE (view->model), iter, - COLUMN_FILTERS_ACTIVE, - gimp_filter_get_active (filter), - -1); -} - static void gimp_drawable_filters_editor_temporary_changed (GimpFilter *filter, const GParamSpec *pspec, diff --git a/app/widgets/gimprow-utils.c b/app/widgets/gimprow-utils.c index 120b14ed4b..1e2bbe56c9 100644 --- a/app/widgets/gimprow-utils.c +++ b/app/widgets/gimprow-utils.c @@ -26,6 +26,7 @@ #include "widgets-types.h" #include "core/gimpcontext.h" +#include "core/gimpdrawablefilter.h" #include "core/gimpsettings.h" #include "gimpcontainerview.h" @@ -33,6 +34,7 @@ #include "gimprow.h" #include "gimprow-utils.h" #include "gimprowdeviceinfo.h" +#include "gimprowdrawablefilter.h" #include "gimprowseparator.h" #include "gimprowsettings.h" @@ -44,7 +46,15 @@ gimp_row_type_from_viewable (GimpViewable *viewable) g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), G_TYPE_NONE); - if (GIMP_IS_SETTINGS (viewable)) + if (GIMP_IS_DRAWABLE_FILTER (viewable)) + { + row_type = GIMP_TYPE_ROW_DRAWABLE_FILTER; + } + else if (GIMP_IS_FILTER (viewable)) + { + row_type = GIMP_TYPE_ROW_FILTER; + } + else if (GIMP_IS_SETTINGS (viewable)) { if (gimp_object_get_name (viewable)) row_type = GIMP_TYPE_ROW_SETTINGS; @@ -56,6 +66,12 @@ gimp_row_type_from_viewable (GimpViewable *viewable) row_type = GIMP_TYPE_ROW_DEVICE_INFO; } +#if 0 + g_printerr ("viewable/row type: %s/%s\n", + g_type_name (G_OBJECT_TYPE (viewable)), + g_type_name (row_type)); +#endif + return row_type; } diff --git a/app/widgets/gimprowdrawablefilter.c b/app/widgets/gimprowdrawablefilter.c new file mode 100644 index 0000000000..5e84c1b56d --- /dev/null +++ b/app/widgets/gimprowdrawablefilter.c @@ -0,0 +1,81 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimprowdrawablefilter.c + * Copyright (C) 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "widgets-types.h" + +#include "core/gimpdrawable.h" +#include "core/gimpdrawablefilter.h" +#include "core/gimpimage.h" + +#include "gimprowdrawablefilter.h" + + +struct _GimpRowDrawableFilter +{ + GimpRowFilter parent_instance; +}; + + +static void gimp_row_filter_drawable_active_toggled (GimpRowFilter *row, + gboolean active); + + +G_DEFINE_TYPE (GimpRowDrawableFilter, + gimp_row_drawable_filter, + GIMP_TYPE_ROW_FILTER) + +#define parent_class gimp_row_drawable_filter_parent_class + + +static void +gimp_row_drawable_filter_class_init (GimpRowDrawableFilterClass *klass) +{ + GimpRowFilterClass *row_filter_class = GIMP_ROW_FILTER_CLASS (klass); + + row_filter_class->active_toggled = gimp_row_filter_drawable_active_toggled; +} + +static void +gimp_row_drawable_filter_init (GimpRowDrawableFilter *row) +{ +} + +static void +gimp_row_filter_drawable_active_toggled (GimpRowFilter *row, + gboolean active) +{ + GimpViewable *viewable = gimp_row_get_viewable (GIMP_ROW (row)); + + GIMP_ROW_FILTER_CLASS (parent_class)->active_toggled (row, active); + + if (viewable) + { + GimpDrawable *drawable = + gimp_drawable_filter_get_drawable (GIMP_DRAWABLE_FILTER (viewable)); + + gimp_drawable_update (drawable, 0, 0, -1, -1); + gimp_image_flush (gimp_item_get_image (GIMP_ITEM (drawable))); + } +} diff --git a/app/widgets/gimprowdrawablefilter.h b/app/widgets/gimprowdrawablefilter.h new file mode 100644 index 0000000000..2a8fbe65b6 --- /dev/null +++ b/app/widgets/gimprowdrawablefilter.h @@ -0,0 +1,30 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimprowdrawablefilter.h + * Copyright (C) 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "gimprowfilter.h" + + +#define GIMP_TYPE_ROW_DRAWABLE_FILTER (gimp_row_drawable_filter_get_type ()) +G_DECLARE_FINAL_TYPE (GimpRowDrawableFilter, + gimp_row_drawable_filter, + GIMP, ROW_DRAWABLE_FILTER, + GimpRowFilter) diff --git a/app/widgets/gimprowfilter.c b/app/widgets/gimprowfilter.c new file mode 100644 index 0000000000..251e651303 --- /dev/null +++ b/app/widgets/gimprowfilter.c @@ -0,0 +1,196 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimprowfilter.c + * Copyright (C) 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "widgets-types.h" + +#include "core/gimp-utils.h" +#include "core/gimpfilter.h" + +#include "gimprowfilter.h" + + +typedef struct _GimpRowFilterPrivate GimpRowFilterPrivate; + +struct _GimpRowFilterPrivate +{ + GtkWidget *active_toggle; + GtkWidget *active_icon; +}; + +#define GET_PRIVATE(obj) \ + ((GimpRowFilterPrivate *) \ + gimp_row_filter_get_instance_private ((GimpRowFilter *) obj)) + + +static void gimp_row_filter_set_viewable (GimpRow *row, + GimpViewable *viewable); +static void gimp_row_filter_set_view_size (GimpRow *row); + +static void gimp_row_filter_real_active_toggled (GimpRowFilter *row, + gboolean active); + +static void gimp_row_filter_active_changed (GimpFilter *filter, + GimpRowFilter *row); +static void gimp_row_filter_active_toggled (GtkToggleButton *button, + GimpRowFilter *row); + + +G_DEFINE_TYPE_WITH_PRIVATE (GimpRowFilter, + gimp_row_filter, + GIMP_TYPE_ROW) + +#define parent_class gimp_row_filter_parent_class + + +static void +gimp_row_filter_class_init (GimpRowFilterClass *klass) +{ + GimpRowClass *row_class = GIMP_ROW_CLASS (klass); + + row_class->set_viewable = gimp_row_filter_set_viewable; + row_class->set_view_size = gimp_row_filter_set_view_size; + + klass->active_property = "active"; + klass->active_changed_signal = "active-changed"; + + klass->active_toggled = gimp_row_filter_real_active_toggled; +} + +static void +gimp_row_filter_init (GimpRowFilter *row) +{ + GimpRowFilterPrivate *priv = GET_PRIVATE (row); + GtkWidget *box; + + box = _gimp_row_get_box (GIMP_ROW (row)); + + priv->active_toggle = gtk_toggle_button_new (); + gtk_box_pack_start (GTK_BOX (box), priv->active_toggle, FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (box), priv->active_toggle, 0); + gtk_widget_set_visible (priv->active_toggle, TRUE); + + g_signal_connect (priv->active_toggle, "toggled", + G_CALLBACK (gimp_row_filter_active_toggled), + row); + + priv->active_icon = gtk_image_new_from_icon_name (GIMP_ICON_VISIBLE, + GTK_ICON_SIZE_BUTTON); + gtk_container_add (GTK_CONTAINER (priv->active_toggle), + priv->active_icon); + gtk_widget_set_visible (priv->active_icon, TRUE); +} + +static void +gimp_row_filter_set_viewable (GimpRow *row, + GimpViewable *viewable) +{ + GimpViewable *old_viewable = gimp_row_get_viewable (row); + + if (old_viewable) + { + g_signal_handlers_disconnect_by_func (old_viewable, + gimp_row_filter_active_changed, + row); + } + + GIMP_ROW_CLASS (parent_class)->set_viewable (row, viewable); + + if (viewable) + { + g_signal_connect (viewable, + GIMP_ROW_FILTER_GET_CLASS (row)->active_changed_signal, + G_CALLBACK (gimp_row_filter_active_changed), + row); + + gimp_row_filter_active_changed (GIMP_FILTER (viewable), + GIMP_ROW_FILTER (row)); + } +} + +static void +gimp_row_filter_set_view_size (GimpRow *row) +{ + GimpRowFilterPrivate *priv = GET_PRIVATE (row); + gint view_size; + + GIMP_ROW_CLASS (parent_class)->set_view_size (row); + + view_size = gimp_row_get_view_size (row, NULL); + view_size = gimp_view_size_get_smaller (view_size); + + gtk_image_set_pixel_size (GTK_IMAGE (priv->active_icon), + view_size); +} + +static void +gimp_row_filter_real_active_toggled (GimpRowFilter *row, + gboolean active) +{ + GimpViewable *viewable = gimp_row_get_viewable (GIMP_ROW (row)); + + if (viewable) + g_object_set (viewable, + GIMP_ROW_FILTER_GET_CLASS (row)->active_property, active, + NULL); +} + +static void +gimp_row_filter_active_changed (GimpFilter *filter, + GimpRowFilter *row) +{ + GimpRowFilterPrivate *priv = GET_PRIVATE (row); + gboolean active; + + g_signal_handlers_block_by_func (priv->active_toggle, + gimp_row_filter_active_toggled, + row); + + g_object_get (filter, + GIMP_ROW_FILTER_GET_CLASS (row)->active_property, &active, + NULL); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->active_toggle), + active); + gtk_widget_set_opacity (priv->active_icon, active ? 1.0 : 0.0); + + g_signal_handlers_unblock_by_func (priv->active_toggle, + gimp_row_filter_active_toggled, + row); +} + +static void +gimp_row_filter_active_toggled (GtkToggleButton *button, + GimpRowFilter *row) +{ + GimpRowFilterPrivate *priv = GET_PRIVATE (row); + gboolean active; + + active = + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->active_toggle)); + + GIMP_ROW_FILTER_GET_CLASS (row)->active_toggled (row, active); +} diff --git a/app/widgets/gimprowfilter.h b/app/widgets/gimprowfilter.h new file mode 100644 index 0000000000..ef375e6e2c --- /dev/null +++ b/app/widgets/gimprowfilter.h @@ -0,0 +1,42 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimprowfilter.h + * Copyright (C) 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "gimprow.h" + + +#define GIMP_TYPE_ROW_FILTER (gimp_row_filter_get_type ()) +G_DECLARE_DERIVABLE_TYPE (GimpRowFilter, + gimp_row_filter, + GIMP, ROW_FILTER, + GimpRow) + + +struct _GimpRowFilterClass +{ + GimpRowClass parent_class; + + const gchar *active_property; + const gchar *active_changed_signal; + + void (* active_toggled) (GimpRowFilter *row, + gboolean active); +}; diff --git a/app/widgets/meson.build b/app/widgets/meson.build index fafa58d9bb..9e77b16d0f 100644 --- a/app/widgets/meson.build +++ b/app/widgets/meson.build @@ -193,6 +193,8 @@ libappwidgets_sources = [ 'gimprow.c', 'gimprow-utils.c', 'gimprowdeviceinfo.c', + 'gimprowdrawablefilter.c', + 'gimprowfilter.c', 'gimprowseparator.c', 'gimprowsettings.c', 'gimpsamplepointeditor.c',