[gimp] app: allow filter actions to have hardcoded default operation settings



commit adb826fb392a4985bcea41c19bed428aa7cb8cf6
Author: Michael Natterer <mitch gimp org>
Date:   Sat Jun 3 21:59:08 2017 +0200

    app: allow filter actions to have hardcoded default operation settings
    
    by encoding them directly in the string attached to all filter
    actions. The code now supports both "gegl:some-operation" and
    "gegl:some-operation\n<serialized config>".
    
    Add "default_settings" to GimpGeglProcedure to store the settings of
    the invoking action, much like the "default_run_mode" member.
    
    Change filters-commands.c to parse the new operation string, create
    GimpGeglProcedures with the deserialized settings, and use those
    settings when the procedures are ran.
    
    Change the filter history to be smarter about what is already in the
    history, there can now be several different procedures with the same
    name.
    
    Remove the dilate and erode actions from the drawable group, and add
    them to filters, they are just special cases of value-propagate with
    fixed settings.

 app/actions/drawable-actions.c  |   14 ----
 app/actions/drawable-commands.c |   64 ----------------
 app/actions/drawable-commands.h |    4 -
 app/actions/filters-actions.c   |  101 +++++++++++++++++++-------
 app/actions/filters-commands.c  |  153 ++++++++++++++++++++++++++++-----------
 app/actions/gimpgeglprocedure.c |   20 ++++--
 app/actions/gimpgeglprocedure.h |    2 +
 app/core/gimp-filter-history.c  |   32 ++++++++-
 app/widgets/gimphelp-ids.h      |    4 +-
 menus/image-menu.xml.in         |    4 +-
 10 files changed, 234 insertions(+), 164 deletions(-)
---
diff --git a/app/actions/drawable-actions.c b/app/actions/drawable-actions.c
index 8a45a99..5b6cbc7 100644
--- a/app/actions/drawable-actions.c
+++ b/app/actions/drawable-actions.c
@@ -53,18 +53,6 @@ static const GimpActionEntry drawable_actions[] =
     G_CALLBACK (drawable_levels_stretch_cmd_callback),
     GIMP_HELP_LAYER_WHITE_BALANCE },
 
-  { "drawable-dilate", GIMP_ICON_GEGL,
-    NC_("drawable-action", "_Dilate"), NULL,
-    NC_("drawable-action", "Grow lighter areas of the image"),
-    G_CALLBACK (drawable_dilate_cmd_callback),
-    GIMP_HELP_LAYER_DILATE },
-
-  { "drawable-erode", GIMP_ICON_GEGL,
-    NC_("drawable-action", "E_rode"), NULL,
-    NC_("drawable-action", "Grow darker areas of the image"),
-    G_CALLBACK (drawable_erode_cmd_callback),
-    GIMP_HELP_LAYER_ERODE },
-
   { "drawable-offset", NULL,
     NC_("drawable-action", "_Offset..."), "<primary><shift>O",
     NC_("drawable-action",
@@ -229,8 +217,6 @@ drawable_actions_update (GimpActionGroup *group,
 
   SET_SENSITIVE ("drawable-equalize",       writable && !children);
   SET_SENSITIVE ("drawable-levels-stretch", writable && !children && is_rgb);
-  SET_SENSITIVE ("drawable-dilate",         writable && !children);
-  SET_SENSITIVE ("drawable-erode",          writable && !children);
   SET_SENSITIVE ("drawable-offset",         writable && !children);
 
   SET_SENSITIVE ("drawable-visible",       drawable);
diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c
index 378be6c..7553f1c 100644
--- a/app/actions/drawable-commands.c
+++ b/app/actions/drawable-commands.c
@@ -96,70 +96,6 @@ drawable_levels_stretch_cmd_callback (GtkAction *action,
 }
 
 void
-drawable_dilate_cmd_callback (GtkAction *action,
-                              gpointer   data)
-{
-  GimpImage    *image;
-  GimpDrawable *drawable;
-  GimpDisplay  *display;
-  GeglNode     *node;
-  return_if_no_drawable (image, drawable, data);
-  return_if_no_display (display, data);
-
-  node = gegl_node_new_child (NULL,
-                              "operation",       "gegl:value-propagate",
-                              "mode",            0, /* GEGL_VALUE_PROPAGATE_MODE_WHITE */
-                              "lower-threshold", 0.0,
-                              "upper-threshold", 1.0,
-                              "rate",            1.0,
-                              "top",             TRUE,
-                              "left",            TRUE,
-                              "right",           TRUE,
-                              "bottom",          TRUE,
-                              "value",           TRUE,
-                              "alpha",           FALSE,
-                              NULL);
-
-  gimp_drawable_apply_operation (drawable, GIMP_PROGRESS (display),
-                                 _("Dilate"), node);
-  g_object_unref (node);
-
-  gimp_image_flush (image);
-}
-
-void
-drawable_erode_cmd_callback (GtkAction *action,
-                             gpointer   data)
-{
-  GimpImage    *image;
-  GimpDrawable *drawable;
-  GimpDisplay  *display;
-  GeglNode     *node;
-  return_if_no_drawable (image, drawable, data);
-  return_if_no_display (display, data);
-
-  node = gegl_node_new_child (NULL,
-                              "operation",       "gegl:value-propagate",
-                              "mode",            1, /* GEGL_VALUE_PROPAGATE_MODE_BLACK */
-                              "lower-threshold", 0.0,
-                              "upper-threshold", 1.0,
-                              "rate",            1.0,
-                              "top",             TRUE,
-                              "left",            TRUE,
-                              "right",           TRUE,
-                              "bottom",          TRUE,
-                              "value",           TRUE,
-                              "alpha",           FALSE,
-                              NULL);
-
-  gimp_drawable_apply_operation (drawable, GIMP_PROGRESS (display),
-                                 _("Erode"), node);
-  g_object_unref (node);
-
-  gimp_image_flush (image);
-}
-
-void
 drawable_offset_cmd_callback (GtkAction *action,
                               gpointer   data)
 {
diff --git a/app/actions/drawable-commands.h b/app/actions/drawable-commands.h
index ae437e1..4a2ec5b 100644
--- a/app/actions/drawable-commands.h
+++ b/app/actions/drawable-commands.h
@@ -23,10 +23,6 @@ void   drawable_equalize_cmd_callback       (GtkAction *action,
                                              gpointer   data);
 void   drawable_levels_stretch_cmd_callback (GtkAction *action,
                                              gpointer   data);
-void   drawable_dilate_cmd_callback         (GtkAction *action,
-                                             gpointer   data);
-void   drawable_erode_cmd_callback          (GtkAction *action,
-                                             gpointer   data);
 void   drawable_offset_cmd_callback         (GtkAction *action,
                                              gpointer   data);
 
diff --git a/app/actions/filters-actions.c b/app/actions/filters-actions.c
index f895e20..cf2a893 100644
--- a/app/actions/filters-actions.c
+++ b/app/actions/filters-actions.c
@@ -43,8 +43,11 @@
 
 /*  local function prototypes  */
 
-static void   filters_actions_history_changed (Gimp            *gimp,
-                                               GimpActionGroup *group);
+static void   filters_actions_set_tooltips    (GimpActionGroup             *group,
+                                               const GimpStringActionEntry *entries,
+                                               gint                         n_entries);
+static void   filters_actions_history_changed (Gimp                        *gimp,
+                                               GimpActionGroup             *group);
 
 
 /*  private variables  */
@@ -128,6 +131,41 @@ static const GimpStringActionEntry filters_actions[] =
     GIMP_HELP_FILTER_STRETCH_CONTRAST_HSV }
 };
 
+static const GimpStringActionEntry filters_settings_actions[] =
+{
+  { "filters-dilate", GIMP_ICON_GEGL,
+    NC_("filters-action", "_Dilate"), NULL,
+    NC_("drawable-action", "Grow lighter areas of the image"),
+    "gegl:value-propagate\n"
+    "(mode white)"
+    "(lower-threshold 0.000000)"
+    "(upper-threshold 1.000000)"
+    "(rate 1.000000)"
+    "(top yes)"
+    "(left yes)"
+    "(right yes)"
+    "(bottom yes)"
+    "(value yes)"
+    "(alpha no)",
+    GIMP_HELP_FILTER_DILATE },
+
+  { "filters-erode", GIMP_ICON_GEGL,
+    NC_("filters-action", "_Erode"), NULL,
+    NC_("drawable-action", "Grow darker areas of the image"),
+    "gegl:value-propagate\n"
+    "(mode black)"
+    "(lower-threshold 0.000000)"
+    "(upper-threshold 1.000000)"
+    "(rate 1.000000)"
+    "(top yes)"
+    "(left yes)"
+    "(right yes)"
+    "(bottom yes)"
+    "(value yes)"
+    "(alpha no)",
+    GIMP_HELP_FILTER_ERODE }
+};
+
 static const GimpStringActionEntry filters_interactive_actions[] =
 {
   { "filters-alien-map", GIMP_ICON_GEGL,
@@ -643,41 +681,28 @@ filters_actions_setup (GimpActionGroup *group)
                                         filters_actions,
                                         G_N_ELEMENTS (filters_actions),
                                         G_CALLBACK (filters_apply_cmd_callback));
+  filters_actions_set_tooltips (group, filters_actions,
+                                G_N_ELEMENTS (filters_actions));
+
+  gimp_action_group_add_string_actions (group, "filters-action",
+                                        filters_settings_actions,
+                                        G_N_ELEMENTS (filters_settings_actions),
+                                        G_CALLBACK (filters_apply_cmd_callback));
+  filters_actions_set_tooltips (group, filters_settings_actions,
+                                G_N_ELEMENTS (filters_settings_actions));
 
   gimp_action_group_add_string_actions (group, "filters-action",
                                         filters_interactive_actions,
                                         G_N_ELEMENTS (filters_interactive_actions),
                                         G_CALLBACK (filters_apply_interactive_cmd_callback));
+  filters_actions_set_tooltips (group, filters_interactive_actions,
+                                G_N_ELEMENTS (filters_interactive_actions));
 
   gimp_action_group_add_enum_actions (group, "filters-action",
                                       filters_repeat_actions,
                                       G_N_ELEMENTS (filters_repeat_actions),
                                       G_CALLBACK (filters_repeat_cmd_callback));
 
-  for (i = 0; i < G_N_ELEMENTS (filters_actions); i++)
-    {
-      const GimpStringActionEntry *entry = &filters_actions[i];
-      const gchar                 *description;
-
-      description = gegl_operation_get_key (entry->value, "description");
-
-      if (description)
-        gimp_action_group_set_action_tooltip (group, entry->name,
-                                              description);
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (filters_interactive_actions); i++)
-    {
-      const GimpStringActionEntry *entry = &filters_interactive_actions[i];
-      const gchar                 *description;
-
-      description = gegl_operation_get_key (entry->value, "description");
-
-      if (description)
-        gimp_action_group_set_action_tooltip (group, entry->name,
-                                              description);
-    }
-
   n_entries = gimp_filter_history_size (group->gimp);
 
   entries = g_new0 (GimpProcedureActionEntry, n_entries);
@@ -771,6 +796,7 @@ filters_actions_update (GimpActionGroup *group,
   SET_SENSITIVE ("filters-desaturate",              writable && !gray);
   SET_SENSITIVE ("filters-difference-of-gaussians", writable);
   SET_SENSITIVE ("filters-diffraction-patterns",    writable);
+  SET_SENSITIVE ("filters-dilate",                  writable);
   SET_SENSITIVE ("filters-displace",                writable);
   SET_SENSITIVE ("filters-distance-map",            writable);
   SET_SENSITIVE ("filters-dropshadow",              writable && alpha);
@@ -780,6 +806,7 @@ filters_actions_update (GimpActionGroup *group,
   SET_SENSITIVE ("filters-edge-sobel",              writable);
   SET_SENSITIVE ("filters-emboss",                  writable);
   SET_SENSITIVE ("filters-engrave",                 writable);
+  SET_SENSITIVE ("filters-erode",                   writable);
   SET_SENSITIVE ("filters-exposure",                writable);
   SET_SENSITIVE ("filters-fattal-2002",             writable);
   SET_SENSITIVE ("filters-fractal-trace",           writable);
@@ -882,7 +909,27 @@ filters_actions_update (GimpActionGroup *group,
 
         g_free (name);
       }
- }
+  }
+}
+
+static void
+filters_actions_set_tooltips (GimpActionGroup             *group,
+                              const GimpStringActionEntry *entries,
+                              gint                         n_entries)
+{
+  gint i;
+
+  for (i = 0; i < n_entries; i++)
+    {
+      const GimpStringActionEntry *entry = entries + i;
+      const gchar                 *description;
+
+      description = gegl_operation_get_key (entry->value, "description");
+
+      if (description)
+        gimp_action_group_set_action_tooltip (group, entry->name,
+                                              description);
+    }
 }
 
 static GimpActionGroup *
diff --git a/app/actions/filters-commands.c b/app/actions/filters-commands.c
index 4d1de87..9f3296b 100644
--- a/app/actions/filters-commands.c
+++ b/app/actions/filters-commands.c
@@ -17,17 +17,23 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "actions-types.h"
 
+#include "operations/gimp-operation-config.h"
+
 #include "core/gimp.h"
 #include "core/gimp-filter-history.h"
 #include "core/gimpprogress.h"
+#include "core/gimpsettings.h"
 
 #include "actions.h"
 #include "filters-commands.h"
@@ -35,19 +41,39 @@
 #include "procedure-commands.h"
 
 
+/*  local function prototypes  */
+
+static gchar * filters_parse_operation (Gimp          *gimp,
+                                        const gchar   *operation_str,
+                                        const gchar   *icon_name,
+                                        GimpObject   **settings);
+
+static void    filters_run_procedure   (Gimp          *gimp,
+                                        GimpDisplay   *display,
+                                        GimpProcedure *procedure,
+                                        GimpRunMode    run_mode);
+
+
 /*  public functions  */
 
 void
 filters_apply_cmd_callback (GtkAction   *action,
-                            const gchar *operation,
+                            const gchar *operation_str,
                             gpointer     data)
 {
   GimpDisplay   *display;
+  gchar         *operation;
+  GimpObject    *settings;
   GimpProcedure *procedure;
   return_if_no_display (display, data);
 
+  operation = filters_parse_operation (action_data_get_gimp (data),
+                                       operation_str,
+                                       gtk_action_get_icon_name (action),
+                                       &settings);
+
   procedure = gimp_gegl_procedure_new (action_data_get_gimp (data),
-                                       GIMP_RUN_NONINTERACTIVE,
+                                       GIMP_RUN_NONINTERACTIVE, settings,
                                        operation,
                                        gtk_action_get_name (action),
                                        gtk_action_get_label (action),
@@ -56,6 +82,11 @@ filters_apply_cmd_callback (GtkAction   *action,
                                        g_object_get_qdata (G_OBJECT (action),
                                                            GIMP_HELP_ID));
 
+  g_free (operation);
+
+  if (settings)
+    g_object_unref (settings);
+
   gimp_filter_history_add (action_data_get_gimp (data), procedure);
   filters_history_cmd_callback (NULL, procedure, data);
 
@@ -72,7 +103,7 @@ filters_apply_interactive_cmd_callback (GtkAction   *action,
   return_if_no_display (display, data);
 
   procedure = gimp_gegl_procedure_new (action_data_get_gimp (data),
-                                       GIMP_RUN_INTERACTIVE,
+                                       GIMP_RUN_INTERACTIVE, NULL,
                                        operation,
                                        gtk_action_get_name (action),
                                        gtk_action_get_label (action),
@@ -94,70 +125,106 @@ filters_repeat_cmd_callback (GtkAction *action,
 {
   Gimp          *gimp;
   GimpDisplay   *display;
-  GimpRunMode    run_mode;
   GimpProcedure *procedure;
   return_if_no_gimp (gimp, data);
   return_if_no_display (display, data);
 
-  run_mode = (GimpRunMode) value;
-
   procedure = gimp_filter_history_nth (gimp, 0);
 
   if (procedure)
+    filters_run_procedure (gimp, display, procedure, (GimpRunMode) value);
+}
+
+void
+filters_history_cmd_callback (GtkAction     *action,
+                              GimpProcedure *procedure,
+                              gpointer       data)
+{
+  Gimp        *gimp;
+  GimpDisplay *display;
+  return_if_no_gimp (gimp, data);
+  return_if_no_display (display, data);
+
+  filters_run_procedure (gimp, display, procedure, GIMP_RUN_INTERACTIVE);
+}
+
+
+/*  private functions  */
+
+static gchar *
+filters_parse_operation (Gimp         *gimp,
+                         const gchar  *operation_str,
+                         const gchar  *icon_name,
+                         GimpObject  **settings)
+{
+  const gchar *newline = strchr (operation_str, '\n');
+
+  *settings = NULL;
+
+  if (newline)
     {
-      GimpValueArray *args;
-      gboolean        success = FALSE;
+      gchar       *operation;
+      const gchar *serialized;
 
-      args = procedure_commands_get_display_args (procedure, display, NULL);
+      operation  = g_strndup (operation_str, newline - operation_str);
+      serialized = newline + 1;
 
-      if (args)
+      if (*serialized)
         {
-          if (GIMP_IS_GEGL_PROCEDURE (procedure) &&
-              GIMP_GEGL_PROCEDURE (procedure)->default_run_mode ==
-              GIMP_RUN_NONINTERACTIVE)
-            {
-              success =
-                procedure_commands_run_procedure (procedure, gimp,
-                                                  GIMP_PROGRESS (display),
-                                                  args);
-            }
-          else
-            {
-              success =
-                procedure_commands_run_procedure_async (procedure, gimp,
-                                                        GIMP_PROGRESS (display),
-                                                        run_mode, args,
-                                                        display);
-            }
+          GError *error = NULL;
+
+          *settings =
+            g_object_new (gimp_operation_config_get_type (gimp, operation,
+                                                          icon_name,
+                                                          GIMP_TYPE_SETTINGS),
+                          NULL);
 
-          if (success)
-            gimp_filter_history_add (gimp, procedure);
+          if (! gimp_config_deserialize_string (GIMP_CONFIG (*settings),
+                                                serialized, -1, NULL,
+                                                &error))
+            {
+              g_warning ("filters_parse_operation: deserializing hardcoded "
+                         "operation settings failed: %s",
+                         error->message);
+              g_clear_error (&error);
 
-          gimp_value_array_unref (args);
+              g_object_unref (*settings);
+              *settings = NULL;
+            }
         }
+
+      return operation;
     }
+
+  return g_strdup (operation_str);
 }
 
-void
-filters_history_cmd_callback (GtkAction     *action,
-                              GimpProcedure *procedure,
-                              gpointer       data)
+static void
+filters_run_procedure (Gimp          *gimp,
+                       GimpDisplay   *display,
+                       GimpProcedure *procedure,
+                       GimpRunMode    run_mode)
 {
-  Gimp           *gimp;
-  GimpDisplay    *display;
+  GimpObject     *settings = NULL;
   GimpValueArray *args;
-  return_if_no_gimp (gimp, data);
-  return_if_no_display (display, data);
 
-  args = procedure_commands_get_display_args (procedure, display, NULL);
+  if (GIMP_IS_GEGL_PROCEDURE (procedure))
+    {
+      GimpGeglProcedure *gegl_procedure = GIMP_GEGL_PROCEDURE (procedure);
+
+      if (gegl_procedure->default_run_mode == GIMP_RUN_NONINTERACTIVE)
+        run_mode = GIMP_RUN_NONINTERACTIVE;
+
+      settings = gegl_procedure->default_settings;
+    }
+
+  args = procedure_commands_get_display_args (procedure, display, settings);
 
   if (args)
     {
       gboolean success = FALSE;
 
-      if (GIMP_IS_GEGL_PROCEDURE (procedure) &&
-          GIMP_GEGL_PROCEDURE (procedure)->default_run_mode ==
-          GIMP_RUN_NONINTERACTIVE)
+      if (run_mode == GIMP_RUN_NONINTERACTIVE)
         {
           success =
             procedure_commands_run_procedure (procedure, gimp,
@@ -169,7 +236,7 @@ filters_history_cmd_callback (GtkAction     *action,
           success =
             procedure_commands_run_procedure_async (procedure, gimp,
                                                     GIMP_PROGRESS (display),
-                                                    GIMP_RUN_INTERACTIVE, args,
+                                                    run_mode, args,
                                                     display);
         }
 
diff --git a/app/actions/gimpgeglprocedure.c b/app/actions/gimpgeglprocedure.c
index 28d6e4e..6850f8a 100644
--- a/app/actions/gimpgeglprocedure.c
+++ b/app/actions/gimpgeglprocedure.c
@@ -119,6 +119,9 @@ gimp_gegl_procedure_finalize (GObject *object)
 {
   GimpGeglProcedure *proc = GIMP_GEGL_PROCEDURE (object);
 
+  if (proc->default_settings)
+    g_object_unref (proc->default_settings);
+
   g_free (proc->menu_label);
   g_free (proc->label);
   g_free (proc->help_id);
@@ -374,6 +377,7 @@ gimp_gegl_procedure_execute_async (GimpProcedure  *procedure,
 GimpProcedure *
 gimp_gegl_procedure_new (Gimp        *gimp,
                          GimpRunMode  default_run_mode,
+                         GimpObject  *default_settings,
                          const gchar *operation,
                          const gchar *name,
                          const gchar *menu_label,
@@ -381,8 +385,9 @@ gimp_gegl_procedure_new (Gimp        *gimp,
                          const gchar *icon_name,
                          const gchar *help_id)
 {
-  GimpProcedure *procedure;
-  GType          config_type;
+  GimpProcedure     *procedure;
+  GimpGeglProcedure *gegl_procedure;
+  GType              config_type;
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (operation != NULL, NULL);
@@ -394,9 +399,14 @@ gimp_gegl_procedure_new (Gimp        *gimp,
 
   procedure = g_object_new (GIMP_TYPE_GEGL_PROCEDURE, NULL);
 
-  GIMP_GEGL_PROCEDURE (procedure)->default_run_mode = default_run_mode;
-  GIMP_GEGL_PROCEDURE (procedure)->menu_label       = g_strdup (menu_label);
-  GIMP_GEGL_PROCEDURE (procedure)->help_id          = g_strdup (help_id);
+  gegl_procedure = GIMP_GEGL_PROCEDURE (procedure);
+
+  gegl_procedure->default_run_mode = default_run_mode;
+  gegl_procedure->menu_label       = g_strdup (menu_label);
+  gegl_procedure->help_id          = g_strdup (help_id);
+
+  if (default_settings)
+    gegl_procedure->default_settings = g_object_ref (default_settings);
 
   gimp_object_set_name (GIMP_OBJECT (procedure), name);
   gimp_viewable_set_icon_name (GIMP_VIEWABLE (procedure), icon_name);
diff --git a/app/actions/gimpgeglprocedure.h b/app/actions/gimpgeglprocedure.h
index 62371a7..4f94a1e 100644
--- a/app/actions/gimpgeglprocedure.h
+++ b/app/actions/gimpgeglprocedure.h
@@ -41,6 +41,7 @@ struct _GimpGeglProcedure
   GimpProcedure  parent_instance;
 
   GimpRunMode    default_run_mode;
+  GimpObject    *default_settings;
 
   gchar         *menu_label;
   gchar         *label;
@@ -57,6 +58,7 @@ GType           gimp_gegl_procedure_get_type (void) G_GNUC_CONST;
 
 GimpProcedure * gimp_gegl_procedure_new      (Gimp        *gimp,
                                               GimpRunMode  default_run_mode,
+                                              GimpObject  *default_settings,
                                               const gchar *operation,
                                               const gchar *name,
                                               const gchar *menu_label,
diff --git a/app/core/gimp-filter-history.c b/app/core/gimp-filter-history.c
index 140b49d..f5fe321 100644
--- a/app/core/gimp-filter-history.c
+++ b/app/core/gimp-filter-history.c
@@ -19,6 +19,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
@@ -34,6 +36,14 @@
 #include "pdb/gimpprocedure.h"
 
 
+/*  local function prototypes  */
+
+static gint   gimp_filter_history_compare (GimpProcedure *proc1,
+                                           GimpProcedure *proc2);
+
+
+/*  public functions  */
+
 gint
 gimp_filter_history_size (Gimp *gimp)
 {
@@ -70,14 +80,14 @@ gimp_filter_history_add (Gimp          *gimp,
 
   /* return early if the procedure is already at the top */
   if (gimp->filter_history &&
-      gimp_procedure_name_compare (gimp->filter_history->data, procedure) == 0)
+      gimp_filter_history_compare (gimp->filter_history->data, procedure) == 0)
     return;
 
   /* ref new first then unref old, they might be the same */
   g_object_ref (procedure);
 
   link = g_list_find_custom (gimp->filter_history, procedure,
-                             (GCompareFunc) gimp_procedure_name_compare);
+                             (GCompareFunc) gimp_filter_history_compare);
 
   if (link)
     {
@@ -108,7 +118,7 @@ gimp_filter_history_remove (Gimp          *gimp,
   g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
 
   link = g_list_find_custom (gimp->filter_history, procedure,
-                             (GCompareFunc) gimp_procedure_name_compare);
+                             (GCompareFunc) gimp_filter_history_compare);
 
   if (link)
     {
@@ -132,3 +142,19 @@ gimp_filter_history_clear (Gimp *gimp)
       gimp_filter_history_changed (gimp);
     }
 }
+
+
+/*  private functions  */
+
+static gint
+gimp_filter_history_compare (GimpProcedure *proc1,
+                             GimpProcedure *proc2)
+{
+  /*  the procedures can have the same name, but could still be two
+   *  different filters using the same operation, so also compare
+   *  their menu labels
+   */
+  return (gimp_procedure_name_compare (proc1, proc2) ||
+          strcmp (gimp_procedure_get_menu_label (proc1),
+                  gimp_procedure_get_menu_label (proc2)));
+}
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index c9d9a11..c5a318f 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -186,8 +186,6 @@
 #define GIMP_HELP_LAYER_LOWER_TO_BOTTOM           "gimp-layer-lower-to-bottom"
 #define GIMP_HELP_LAYER_WHITE_BALANCE             "gimp-layer-white-balance"
 #define GIMP_HELP_LAYER_EQUALIZE                  "gimp-layer-equalize"
-#define GIMP_HELP_LAYER_DILATE                    "gimp-layer-dilate"
-#define GIMP_HELP_LAYER_ERODE                     "gimp-layer-erode"
 #define GIMP_HELP_LAYER_VISIBLE                   "gimp-layer-visible"
 #define GIMP_HELP_LAYER_LINKED                    "gimp-layer-linked"
 #define GIMP_HELP_LAYER_COLOR_TAG                 "gimp-layer-color-tag"
@@ -352,6 +350,7 @@
 #define GIMP_HELP_FILTER_DESATURATE               "gimp-filter-desaturate"
 #define GIMP_HELP_FILTER_DIFFERENCE_OF_GAUSSIANS  "gimp-filter-difference-of-gaussians"
 #define GIMP_HELP_FILTER_DIFFRACTION_PATTERNS     "gimp-filter-diffraction-patterns"
+#define GIMP_HELP_FILTER_DILATE                   "gimp-filter-dilate"
 #define GIMP_HELP_FILTER_DISPLACE                 "gimp-filter-displace"
 #define GIMP_HELP_FILTER_DISTANCE_MAP             "gimp-filter-distance-map"
 #define GIMP_HELP_FILTER_DITHER                   "gimp-filter-dither"
@@ -362,6 +361,7 @@
 #define GIMP_HELP_FILTER_EDGE_SOBEL               "gimp-filter-edge-sobel"
 #define GIMP_HELP_FILTER_EMBOSS                   "gimp-filter-emboss"
 #define GIMP_HELP_FILTER_ENGRAVE                  "gimp-filter-engrave"
+#define GIMP_HELP_FILTER_ERODE                    "gimp-filter-erode"
 #define GIMP_HELP_FILTER_EXPOSURE                 "gimp-filter-exposure"
 #define GIMP_HELP_FILTER_FATTAL_2002              "gimp-filter-fattal-2002"
 #define GIMP_HELP_FILTER_FRACTAL_TRACE            "gimp-filter-fractal-trace"
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 160f7dd..d921ff4 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -761,8 +761,8 @@
         <menuitem action="filters-convolution-matrix" />
         <menuitem action="filters-distance-map" />
         <menuitem action="filters-gegl-graph" />
-        <menuitem action="drawable-dilate" />
-        <menuitem action="drawable-erode" />
+        <menuitem action="filters-dilate" />
+        <menuitem action="filters-erode" />
       </menu>
       <menu action="filters-combine-menu" name="Combine" />
       <menu action="filters-artistic-menu" name="Artistic">


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]