[gimp] Bug 759316 - "Recently used" menu not updated with gegl filters



commit 3831f62495175d6aa728191429a602cc8d14ae11
Author: Michael Natterer <mitch gimp org>
Date:   Mon Jan 4 15:07:30 2016 +0100

    Bug 759316 - "Recently used" menu not updated with gegl filters
    
    Add GimpGeglProceure to keep track of recently used GEGL operations in
    the filter history. The new procedure also takes care of running the
    op in the GEGL tool, so filters-commands.c is almost empty now.
    
    Change gimp-filter-history.c to find procedures by name instead of
    comparing pointers.
    
    The only thing missing now is rerunning a GEGL op with the last
    settings (not just showing its UI).

 app/actions/Makefile.am          |    3 +
 app/actions/filters-actions.c    |   45 ++++--
 app/actions/filters-commands.c   |  109 +++-----------
 app/actions/gimpgeglprocedure.c  |  313 ++++++++++++++++++++++++++++++++++++++
 app/actions/gimpgeglprocedure.h  |   63 ++++++++
 app/actions/plug-in-commands.c   |   28 +---
 app/actions/plug-in-commands.h   |    7 -
 app/actions/procedure-commands.c |   37 +++++
 app/actions/procedure-commands.h |   25 ++-
 app/core/gimp-filter-history.c   |   29 ++--
 po/POTFILES.in                   |    1 -
 11 files changed, 502 insertions(+), 158 deletions(-)
---
diff --git a/app/actions/Makefile.am b/app/actions/Makefile.am
index 9194b89..b4c708d 100644
--- a/app/actions/Makefile.am
+++ b/app/actions/Makefile.am
@@ -17,6 +17,9 @@ libappactions_a_SOURCES = \
        actions.c                       \
        actions.h                       \
        \
+       gimpgeglprocedure.c             \
+       gimpgeglprocedure.h             \
+       \
        brush-editor-actions.c          \
        brush-editor-actions.h          \
        brushes-actions.c               \
diff --git a/app/actions/filters-actions.c b/app/actions/filters-actions.c
index 97a0588..8c8de44 100644
--- a/app/actions/filters-actions.c
+++ b/app/actions/filters-actions.c
@@ -778,6 +778,7 @@ filters_actions_history_changed (Gimp            *gimp,
 
   if (proc)
     {
+      GtkAction   *actual_action = NULL;
       const gchar *label;
       gchar       *repeat;
       gchar       *reshow;
@@ -794,20 +795,28 @@ filters_actions_history_changed (Gimp            *gimp,
       g_free (repeat);
       g_free (reshow);
 
-      /*  copy the sensitivity of the plug-in procedure's actual action
-       *  instead of calling filters_actions_update() because doing the
-       *  latter would set the sensitivity of this image's action on
-       *  all images' actions. See bug #517683.
-       */
-      if (plug_in_group)
+      if (g_str_has_prefix (gimp_object_get_name (proc), "filters-"))
         {
-          GtkAction *actual_action =
+          actual_action =
+            gtk_action_group_get_action (GTK_ACTION_GROUP (group),
+                                         gimp_object_get_name (proc));
+        }
+      else if (plug_in_group)
+        {
+          /*  copy the sensitivity of the plug-in procedure's actual
+           *  action instead of calling filters_actions_update()
+           *  because doing the latter would set the sensitivity of
+           *  this image's action on all images' actions. See bug
+           *  #517683.
+           */
+          actual_action =
             gtk_action_group_get_action (GTK_ACTION_GROUP (plug_in_group),
                                          gimp_object_get_name (proc));
-          if (actual_action)
-            sensitive = gtk_action_get_sensitive (actual_action);
         }
 
+      if (actual_action)
+        sensitive = gtk_action_get_sensitive (actual_action);
+
       gimp_action_group_set_action_sensitive (group, "filters-repeat",
                                               sensitive);
       gimp_action_group_set_action_sensitive (group, "filters-reshow",
@@ -827,6 +836,7 @@ filters_actions_history_changed (Gimp            *gimp,
   for (i = 0; i < gimp_filter_history_length (gimp); i++)
     {
       GtkAction   *action;
+      GtkAction   *actual_action = NULL;
       const gchar *label;
       gchar       *name;
       gboolean     sensitive = FALSE;
@@ -839,16 +849,23 @@ filters_actions_history_changed (Gimp            *gimp,
 
       label = gimp_procedure_get_menu_label (proc);
 
-      /*  see comment above  */
-      if (plug_in_group)
+      if (g_str_has_prefix (gimp_object_get_name (proc), "filters-"))
         {
-          GtkAction *actual_action =
+          actual_action =
+            gtk_action_group_get_action (GTK_ACTION_GROUP (group),
+                                         gimp_object_get_name (proc));
+        }
+      else if (plug_in_group)
+        {
+          /*  see comment above  */
+          actual_action =
             gtk_action_group_get_action (GTK_ACTION_GROUP (plug_in_group),
                                          gimp_object_get_name (proc));
-          if (actual_action)
-            sensitive = gtk_action_get_sensitive (actual_action);
         }
 
+      if (actual_action)
+        sensitive = gtk_action_get_sensitive (actual_action);
+
       g_object_set (action,
                     "visible",   TRUE,
                     "sensitive", sensitive,
diff --git a/app/actions/filters-commands.c b/app/actions/filters-commands.c
index 434b844..25f6ef5 100644
--- a/app/actions/filters-commands.c
+++ b/app/actions/filters-commands.c
@@ -26,22 +26,13 @@
 
 #include "core/gimp.h"
 #include "core/gimp-filter-history.h"
-#include "core/gimpcontext.h"
-#include "core/gimpimage.h"
 #include "core/gimpprogress.h"
-#include "core/gimptoolinfo.h"
-
-#include "pdb/gimpprocedure.h"
-
-#include "tools/gimpoperationtool.h"
-#include "tools/tool_manager.h"
 
 #include "actions.h"
 #include "filters-commands.h"
+#include "gimpgeglprocedure.h"
 #include "procedure-commands.h"
 
-#include "gimp-intl.h"
-
 
 /*  public functions  */
 
@@ -50,53 +41,21 @@ filters_filter_cmd_callback (GtkAction   *action,
                              const gchar *operation,
                              gpointer     data)
 {
-  GimpImage    *image;
-  GimpDrawable *drawable;
-  GimpDisplay  *display;
-  GimpTool     *active_tool;
-  return_if_no_drawable (image, drawable, data);
+  GimpDisplay   *display;
+  GimpProcedure *procedure;
   return_if_no_display (display, data);
 
-  active_tool = tool_manager_get_active (image->gimp);
-
-  if (G_TYPE_FROM_INSTANCE (active_tool) != GIMP_TYPE_OPERATION_TOOL)
-    {
-      GimpToolInfo *tool_info = gimp_get_tool_info (image->gimp,
-                                                    "gimp-operation-tool");
-
-      if (GIMP_IS_TOOL_INFO (tool_info))
-        gimp_context_set_tool (action_data_get_context (data), tool_info);
-    }
-  else
-    {
-      gimp_context_tool_changed (action_data_get_context (data));
-    }
-
-  active_tool = tool_manager_get_active (image->gimp);
+  procedure = gimp_gegl_procedure_new (action_data_get_gimp (data),
+                                       operation,
+                                       gtk_action_get_name (action),
+                                       gtk_action_get_label (action),
+                                       gtk_action_get_icon_name (action),
+                                       gtk_action_get_tooltip (action));
 
-  if (GIMP_IS_OPERATION_TOOL (active_tool))
-    {
-      gchar       *label    = gimp_strip_uline (gtk_action_get_label (action));
-      const gchar *ellipsis = _("...");
-      gint         label_len;
-      gint         ellipsis_len;
-
-      label_len    = strlen (label);
-      ellipsis_len = strlen (ellipsis);
+  gimp_filter_history_add (action_data_get_gimp (data), procedure);
+  filters_history_cmd_callback (NULL, procedure, data);
 
-      if (label_len > ellipsis_len &&
-          strcmp (label + label_len - ellipsis_len, ellipsis) == 0)
-        {
-          label[label_len - ellipsis_len] = '\0';
-        }
-
-      gimp_operation_tool_set_operation (GIMP_OPERATION_TOOL (active_tool),
-                                         operation, label,
-                                         gtk_action_get_icon_name (action));
-      tool_manager_initialize_active (image->gimp, display);
-
-      g_free (label);
-    }
+  g_object_unref (procedure);
 }
 
 void
@@ -104,10 +63,10 @@ filters_repeat_cmd_callback (GtkAction *action,
                              gint       value,
                              gpointer   data)
 {
-  GimpProcedure *procedure;
   Gimp          *gimp;
   GimpDisplay   *display;
   GimpRunMode    run_mode;
+  GimpProcedure *procedure;
   return_if_no_gimp (gimp, data);
   return_if_no_display (display, data);
 
@@ -123,23 +82,10 @@ filters_repeat_cmd_callback (GtkAction *action,
 
       if (args)
         {
-          GError *error = NULL;
-
-          g_value_set_int (gimp_value_array_index (args, 0), run_mode);
-
-          gimp_procedure_execute_async (procedure, gimp,
-                                        gimp_get_user_context (gimp),
-                                        GIMP_PROGRESS (display), args,
-                                        GIMP_OBJECT (display), &error);
-
-          if (error)
-            {
-              gimp_message_literal (gimp,
-                                    G_OBJECT (display), GIMP_MESSAGE_ERROR,
-                                    error->message);
-              g_clear_error (&error);
-            }
-          else
+          if (procedure_commands_run_procedure (procedure, gimp,
+                                                GIMP_PROGRESS (display),
+                                                run_mode, args,
+                                                display))
             {
               gimp_filter_history_add (gimp, procedure);
             }
@@ -164,23 +110,10 @@ filters_history_cmd_callback (GtkAction     *action,
 
   if (args)
     {
-      GError *error = NULL;
-
-      g_value_set_int (gimp_value_array_index (args, 0), GIMP_RUN_INTERACTIVE);
-
-      gimp_procedure_execute_async (procedure, gimp,
-                                    gimp_get_user_context (gimp),
-                                    GIMP_PROGRESS (display), args,
-                                    GIMP_OBJECT (display), &error);
-
-      if (error)
-        {
-          gimp_message_literal (gimp,
-                                G_OBJECT (display), GIMP_MESSAGE_ERROR,
-                                error->message);
-          g_clear_error (&error);
-        }
-      else
+      if (procedure_commands_run_procedure (procedure, gimp,
+                                            GIMP_PROGRESS (display),
+                                            GIMP_RUN_INTERACTIVE, args,
+                                            display))
         {
           gimp_filter_history_add (gimp, procedure);
         }
diff --git a/app/actions/gimpgeglprocedure.c b/app/actions/gimpgeglprocedure.c
new file mode 100644
index 0000000..adf5b5c
--- /dev/null
+++ b/app/actions/gimpgeglprocedure.c
@@ -0,0 +1,313 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpgeglprocedure.c
+ * Copyright (C) 2016 Michael Natterer <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "actions-types.h"
+
+#include "core/gimp.h"
+#include "core/gimp-memsize.h"
+#include "core/gimpcontext.h"
+#include "core/gimplayermask.h"
+#include "core/gimpparamspecs.h"
+#include "core/gimptoolinfo.h"
+
+#include "display/gimpdisplay.h"
+
+#include "tools/gimpoperationtool.h"
+#include "tools/tool_manager.h"
+
+#include "gimpgeglprocedure.h"
+
+
+static void     gimp_gegl_procedure_finalize            (GObject        *object);
+
+static gint64   gimp_gegl_procedure_get_memsize         (GimpObject     *object,
+                                                         gint64         *gui_size);
+
+static gchar  * gimp_gegl_procedure_get_description     (GimpViewable   *viewable,
+                                                         gchar         **tooltip);
+
+static const gchar * gimp_gegl_procedure_get_label      (GimpProcedure  *procedure);
+static const gchar * gimp_gegl_procedure_get_menu_label (GimpProcedure  *procedure);
+static gboolean      gimp_gegl_procedure_get_sensitive  (GimpProcedure  *procedure,
+                                                         GimpObject     *object);
+static GimpValueArray * gimp_gegl_procedure_execute     (GimpProcedure  *procedure,
+                                                         Gimp           *gimp,
+                                                         GimpContext    *context,
+                                                         GimpProgress   *progress,
+                                                         GimpValueArray *args,
+                                                         GError        **error);
+static void     gimp_gegl_procedure_execute_async       (GimpProcedure  *procedure,
+                                                         Gimp           *gimp,
+                                                         GimpContext    *context,
+                                                         GimpProgress   *progress,
+                                                         GimpValueArray *args,
+                                                         GimpObject     *display);
+
+
+G_DEFINE_TYPE (GimpGeglProcedure, gimp_gegl_procedure,
+               GIMP_TYPE_PROCEDURE)
+
+#define parent_class gimp_gegl_procedure_parent_class
+
+
+static void
+gimp_gegl_procedure_class_init (GimpGeglProcedureClass *klass)
+{
+  GObjectClass       *object_class      = G_OBJECT_CLASS (klass);
+  GimpObjectClass    *gimp_object_class = GIMP_OBJECT_CLASS (klass);
+  GimpViewableClass  *viewable_class    = GIMP_VIEWABLE_CLASS (klass);
+  GimpProcedureClass *proc_class        = GIMP_PROCEDURE_CLASS (klass);
+
+  object_class->finalize            = gimp_gegl_procedure_finalize;
+
+  gimp_object_class->get_memsize    = gimp_gegl_procedure_get_memsize;
+
+  viewable_class->default_icon_name = "gimp-gegl";
+  viewable_class->get_description   = gimp_gegl_procedure_get_description;
+
+  proc_class->get_label             = gimp_gegl_procedure_get_label;
+  proc_class->get_menu_label        = gimp_gegl_procedure_get_menu_label;
+  proc_class->get_sensitive         = gimp_gegl_procedure_get_sensitive;
+  proc_class->execute               = gimp_gegl_procedure_execute;
+  proc_class->execute_async         = gimp_gegl_procedure_execute_async;
+}
+
+static void
+gimp_gegl_procedure_init (GimpGeglProcedure *proc)
+{
+}
+
+static void
+gimp_gegl_procedure_finalize (GObject *object)
+{
+  GimpGeglProcedure *proc = GIMP_GEGL_PROCEDURE (object);
+
+  g_free (proc->menu_label);
+  g_free (proc->label);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint64
+gimp_gegl_procedure_get_memsize (GimpObject *object,
+                                    gint64     *gui_size)
+{
+  GimpGeglProcedure *proc    = GIMP_GEGL_PROCEDURE (object);
+  gint64             memsize = 0;
+
+  memsize += gimp_string_get_memsize (proc->menu_label);
+  memsize += gimp_string_get_memsize (proc->label);
+
+  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
+                                                                  gui_size);
+}
+
+static gchar *
+gimp_gegl_procedure_get_description (GimpViewable  *viewable,
+                                        gchar        **tooltip)
+{
+  GimpProcedure *procedure = GIMP_PROCEDURE (viewable);
+
+  if (tooltip)
+    *tooltip = g_strdup (gimp_procedure_get_blurb (procedure));
+
+  return g_strdup (gimp_procedure_get_label (procedure));
+}
+
+static const gchar *
+gimp_gegl_procedure_get_label (GimpProcedure *procedure)
+{
+  GimpGeglProcedure *proc = GIMP_GEGL_PROCEDURE (procedure);
+  gchar             *ellipsis;
+  gchar             *label;
+
+  if (proc->label)
+    return proc->label;
+
+  label = gimp_strip_uline (gimp_procedure_get_menu_label (procedure));
+
+  ellipsis = strstr (label, "...");
+
+  if (! ellipsis)
+    ellipsis = strstr (label, "\342\200\246" /* U+2026 HORIZONTAL ELLIPSIS */);
+
+  if (ellipsis && ellipsis == (label + strlen (label) - 3))
+    *ellipsis = '\0';
+
+  proc->label = label;
+
+  return proc->label;
+}
+
+static const gchar *
+gimp_gegl_procedure_get_menu_label (GimpProcedure *procedure)
+{
+  GimpGeglProcedure *proc = GIMP_GEGL_PROCEDURE (procedure);
+
+  if (proc->menu_label)
+    return proc->menu_label;
+
+  return GIMP_PROCEDURE_CLASS (parent_class)->get_menu_label (procedure);
+}
+
+static gboolean
+gimp_gegl_procedure_get_sensitive (GimpProcedure *procedure,
+                                   GimpObject    *object)
+{
+  GimpDrawable *drawable;
+  gboolean      sensitive = FALSE;
+
+  g_return_val_if_fail (object == NULL || GIMP_IS_DRAWABLE (object), FALSE);
+
+  drawable = GIMP_DRAWABLE (object);
+
+  if (drawable)
+    {
+      GimpItem *item;
+
+      if (GIMP_IS_LAYER_MASK (drawable))
+        item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable)));
+      else
+        item = GIMP_ITEM (drawable);
+
+      sensitive = ! gimp_item_is_content_locked (item);
+
+      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
+        sensitive = FALSE;
+    }
+
+  return sensitive;
+}
+
+static GimpValueArray *
+gimp_gegl_procedure_execute (GimpProcedure  *procedure,
+                             Gimp           *gimp,
+                             GimpContext    *context,
+                             GimpProgress   *progress,
+                             GimpValueArray *args,
+                             GError        **error)
+{
+  return GIMP_PROCEDURE_CLASS (parent_class)->execute (procedure, gimp,
+                                                       context, progress,
+                                                       args, error);
+}
+
+static void
+gimp_gegl_procedure_execute_async (GimpProcedure  *procedure,
+                                   Gimp           *gimp,
+                                   GimpContext    *context,
+                                   GimpProgress   *progress,
+                                   GimpValueArray *args,
+                                   GimpObject     *display)
+{
+  GimpTool *active_tool = tool_manager_get_active (gimp);
+
+  /*  do not use the passed context because we need to set the active
+   *  tool on the global user context
+   */
+  context = gimp_get_user_context (gimp);
+
+  if (G_TYPE_FROM_INSTANCE (active_tool) != GIMP_TYPE_OPERATION_TOOL)
+    {
+      GimpToolInfo *tool_info = gimp_get_tool_info (gimp,
+                                                    "gimp-operation-tool");
+
+      if (GIMP_IS_TOOL_INFO (tool_info))
+        gimp_context_set_tool (context, tool_info);
+    }
+  else
+    {
+      gimp_context_tool_changed (context);
+    }
+
+  active_tool = tool_manager_get_active (gimp);
+
+  if (GIMP_IS_OPERATION_TOOL (active_tool))
+    {
+      gimp_operation_tool_set_operation (GIMP_OPERATION_TOOL (active_tool),
+                                         procedure->original_name,
+                                         gimp_procedure_get_label (procedure),
+                                         gimp_viewable_get_icon_name (GIMP_VIEWABLE (procedure)));
+
+      tool_manager_initialize_active (gimp, GIMP_DISPLAY (display));
+    }
+}
+
+
+/*  public functions  */
+
+GimpProcedure *
+gimp_gegl_procedure_new (Gimp        *gimp,
+                         const gchar *operation,
+                         const gchar *name,
+                         const gchar *menu_label,
+                         const gchar *icon_name,
+                         const gchar *tooltip)
+{
+  GimpProcedure *procedure;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+  g_return_val_if_fail (operation != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (menu_label != NULL, NULL);
+
+  procedure = g_object_new (GIMP_TYPE_GEGL_PROCEDURE, NULL);
+
+  GIMP_GEGL_PROCEDURE (procedure)->menu_label = g_strdup (menu_label);
+
+  gimp_object_set_name (GIMP_OBJECT (procedure), name);
+  gimp_viewable_set_icon_name (GIMP_VIEWABLE (procedure), icon_name);
+  gimp_procedure_set_strings (procedure,
+                              operation,
+                              tooltip,
+                              "help",
+                              "author", "copyright", "date",
+                              NULL);
+
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_int32 ("dummy-param",
+                                                      "Dummy Param",
+                                                      "Dummy parameter",
+                                                      G_MININT32, G_MAXINT32, 0,
+                                                      GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_image_id ("image",
+                                                         "Image",
+                                                         "Input image",
+                                                         gimp, FALSE,
+                                                         GIMP_PARAM_READWRITE));
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_drawable_id ("drawable",
+                                                            "Drawable",
+                                                            "Input drawable",
+                                                            gimp, TRUE,
+                                                            GIMP_PARAM_READWRITE));
+
+  return procedure;
+}
diff --git a/app/actions/gimpgeglprocedure.h b/app/actions/gimpgeglprocedure.h
new file mode 100644
index 0000000..36a128e
--- /dev/null
+++ b/app/actions/gimpgeglprocedure.h
@@ -0,0 +1,63 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpgeglprocedure.h
+ * Copyright (C) 2016 Michael Natterer <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_GEGL_PROCEDURE_H__
+#define __GIMP_GEGL_PROCEDURE_H__
+
+
+#include "pdb/gimpprocedure.h"
+
+
+#define GIMP_TYPE_GEGL_PROCEDURE            (gimp_gegl_procedure_get_type ())
+#define GIMP_GEGL_PROCEDURE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_GEGL_PROCEDURE, 
GimpGeglProcedure))
+#define GIMP_GEGL_PROCEDURE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_GEGL_PROCEDURE, 
GimpGeglProcedureClass))
+#define GIMP_IS_GEGL_PROCEDURE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_GEGL_PROCEDURE))
+#define GIMP_IS_GEGL_PROCEDURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_GEGL_PROCEDURE))
+#define GIMP_GEGL_PROCEDURE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_GEGL_PROCEDURE, 
GimpGeglProcedureClass))
+
+
+typedef struct _GimpGeglProcedure      GimpGeglProcedure;
+typedef struct _GimpGeglProcedureClass GimpGeglProcedureClass;
+
+struct _GimpGeglProcedure
+{
+  GimpProcedure  parent_instance;
+
+  gchar         *menu_label;
+  gchar         *label;
+};
+
+struct _GimpGeglProcedureClass
+{
+  GimpProcedureClass parent_class;
+};
+
+
+GType           gimp_gegl_procedure_get_type (void) G_GNUC_CONST;
+
+GimpProcedure * gimp_gegl_procedure_new      (Gimp        *gimp,
+                                              const gchar *operation,
+                                              const gchar *name,
+                                              const gchar *menu_label,
+                                              const gchar *icon_name,
+                                              const gchar *tooltip);
+
+
+#endif /* __GIMP_GEGL_PROCEDURE_H__ */
diff --git a/app/actions/plug-in-commands.c b/app/actions/plug-in-commands.c
index 4acd33e..6b29881 100644
--- a/app/actions/plug-in-commands.c
+++ b/app/actions/plug-in-commands.c
@@ -17,8 +17,6 @@
 
 #include "config.h"
 
-#include <string.h>
-
 #include <gegl.h>
 #include <gtk/gtk.h>
 
@@ -29,10 +27,8 @@
 
 #include "core/gimp.h"
 #include "core/gimp-filter-history.h"
-#include "core/gimp-utils.h"
 #include "core/gimpcontainer.h"
 #include "core/gimpcontext.h"
-#include "core/gimpdrawable.h"
 #include "core/gimpimage.h"
 #include "core/gimpitem.h"
 #include "core/gimpparamspecs.h"
@@ -53,8 +49,6 @@
 #include "widgets/gimpmessagebox.h"
 #include "widgets/gimpmessagedialog.h"
 
-#include "display/gimpdisplay.h"
-
 #include "actions.h"
 #include "plug-in-commands.h"
 #include "procedure-commands.h"
@@ -144,24 +138,10 @@ plug_in_run_cmd_callback (GtkAction     *action,
 
   if (args)
     {
-      GError *error = NULL;
-
-      g_value_set_int (gimp_value_array_index (args, 0),
-                       GIMP_RUN_INTERACTIVE);
-
-      gimp_procedure_execute_async (procedure, gimp,
-                                    gimp_get_user_context (gimp),
-                                    GIMP_PROGRESS (display), args,
-                                    GIMP_OBJECT (display), &error);
-
-      if (error)
-        {
-          gimp_message_literal (gimp,
-                                G_OBJECT (display), GIMP_MESSAGE_ERROR,
-                                error->message);
-          g_error_free (error);
-        }
-      else
+      if (procedure_commands_run_procedure (procedure, gimp,
+                                            GIMP_PROGRESS (display),
+                                            GIMP_RUN_INTERACTIVE, args,
+                                            display))
         {
           /* remember only image plug-ins */
           if (procedure->num_args >= 2 &&
diff --git a/app/actions/plug-in-commands.h b/app/actions/plug-in-commands.h
index e16aaca..728f4c4 100644
--- a/app/actions/plug-in-commands.h
+++ b/app/actions/plug-in-commands.h
@@ -27,11 +27,4 @@ void   plug_in_reset_all_cmd_callback (GtkAction     *action,
                                        gpointer       data);
 
 
-/* FIXME history */
-gint  plug_in_collect_display_args  (GtkAction       *action,
-                                     GimpDisplay     *display,
-                                     GParamSpec     **pspecs,
-                                     GimpValueArray  *args,
-                                     gint             n_args);
-
 #endif /* __PLUG_IN_COMMANDS_H__ */
diff --git a/app/actions/procedure-commands.c b/app/actions/procedure-commands.c
index c45daf8..246853d 100644
--- a/app/actions/procedure-commands.c
+++ b/app/actions/procedure-commands.c
@@ -24,8 +24,10 @@
 
 #include "actions-types.h"
 
+#include "core/gimp.h"
 #include "core/gimpimage.h"
 #include "core/gimpparamspecs.h"
+#include "core/gimpprogress.h"
 
 #include "pdb/gimpprocedure.h"
 
@@ -222,3 +224,38 @@ procedure_commands_get_display_args (GimpProcedure *procedure,
   return args;
 }
 
+gboolean
+procedure_commands_run_procedure (GimpProcedure  *procedure,
+                                  Gimp           *gimp,
+                                  GimpProgress   *progress,
+                                  GimpRunMode     run_mode,
+                                  GimpValueArray *args,
+                                  GimpDisplay    *display)
+{
+  GError *error = NULL;
+
+  g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), FALSE);
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
+  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
+  g_return_val_if_fail (display == NULL || GIMP_IS_DISPLAY (display), FALSE);
+  g_return_val_if_fail (args != NULL, FALSE);
+
+  g_value_set_int (gimp_value_array_index (args, 0), run_mode);
+
+  gimp_procedure_execute_async (procedure, gimp,
+                                gimp_get_user_context (gimp),
+                                progress, args,
+                                GIMP_OBJECT (display), &error);
+
+  if (error)
+    {
+      gimp_message_literal (gimp,
+                            G_OBJECT (progress), GIMP_MESSAGE_ERROR,
+                            error->message);
+      g_clear_error (&error);
+
+      return FALSE;
+    }
+
+  return TRUE;
+}
diff --git a/app/actions/procedure-commands.h b/app/actions/procedure-commands.h
index 9c0743f..16e26d7 100644
--- a/app/actions/procedure-commands.h
+++ b/app/actions/procedure-commands.h
@@ -19,15 +19,22 @@
 #define __PROCEDURE_COMMANDS_H__
 
 
-GimpValueArray * procedure_commands_get_data_args    (GimpProcedure   *procedure,
-                                                      GimpObject      *object);
-GimpValueArray * procedure_commands_get_image_args   (GimpProcedure   *procedure,
-                                                      GimpImage       *image);
-GimpValueArray * procedure_commands_get_item_args    (GimpProcedure   *procedure,
-                                                      GimpImage       *image,
-                                                      GimpItem        *item);
-GimpValueArray * procedure_commands_get_display_args (GimpProcedure   *procedure,
-                                                      GimpDisplay     *display);
+GimpValueArray * procedure_commands_get_data_args    (GimpProcedure  *procedure,
+                                                      GimpObject     *object);
+GimpValueArray * procedure_commands_get_image_args   (GimpProcedure  *procedure,
+                                                      GimpImage      *image);
+GimpValueArray * procedure_commands_get_item_args    (GimpProcedure  *procedure,
+                                                      GimpImage      *image,
+                                                      GimpItem       *item);
+GimpValueArray * procedure_commands_get_display_args (GimpProcedure  *procedure,
+                                                      GimpDisplay    *display);
+
+gboolean         procedure_commands_run_procedure    (GimpProcedure  *procedure,
+                                                      Gimp           *gimp,
+                                                      GimpProgress   *progress,
+                                                      GimpRunMode     run_mode,
+                                                      GimpValueArray *args,
+                                                      GimpDisplay    *display);
 
 
 #endif /* __PROCEDURE_COMMANDS_H__ */
diff --git a/app/core/gimp-filter-history.c b/app/core/gimp-filter-history.c
index 56a69c3..140b49d 100644
--- a/app/core/gimp-filter-history.c
+++ b/app/core/gimp-filter-history.c
@@ -64,37 +64,35 @@ gimp_filter_history_add (Gimp          *gimp,
                          GimpProcedure *procedure)
 {
   GList *link;
-  gint   history_size;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
   g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
 
   /* return early if the procedure is already at the top */
-  if (gimp->filter_history && gimp->filter_history->data == procedure)
+  if (gimp->filter_history &&
+      gimp_procedure_name_compare (gimp->filter_history->data, procedure) == 0)
     return;
 
-  history_size = gimp_filter_history_size (gimp);
+  /* ref new first then unref old, they might be the same */
+  g_object_ref (procedure);
 
-  link = g_list_find (gimp->filter_history, procedure);
+  link = g_list_find_custom (gimp->filter_history, procedure,
+                             (GCompareFunc) gimp_procedure_name_compare);
 
   if (link)
     {
+      g_object_unref (link->data);
       gimp->filter_history = g_list_delete_link (gimp->filter_history, link);
-      gimp->filter_history = g_list_prepend (gimp->filter_history, procedure);
-    }
-  else
-    {
-      gimp->filter_history = g_list_prepend (gimp->filter_history,
-                                             g_object_ref (procedure));
     }
 
-  link = g_list_nth (gimp->filter_history, history_size);
+  gimp->filter_history = g_list_prepend (gimp->filter_history, procedure);
+
+  link = g_list_nth (gimp->filter_history, gimp_filter_history_size (gimp));
 
   if (link)
     {
-      gimp->filter_history = g_list_remove_link (gimp->filter_history, link);
       g_object_unref (link->data);
-      g_list_free (link);
+      gimp->filter_history = g_list_delete_link (gimp->filter_history, link);
     }
 
   gimp_filter_history_changed (gimp);
@@ -109,12 +107,13 @@ gimp_filter_history_remove (Gimp          *gimp,
   g_return_if_fail (GIMP_IS_GIMP (gimp));
   g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
 
-  link = g_list_find (gimp->filter_history, procedure);
+  link = g_list_find_custom (gimp->filter_history, procedure,
+                             (GCompareFunc) gimp_procedure_name_compare);
 
   if (link)
     {
+      g_object_unref (link->data);
       gimp->filter_history = g_list_delete_link (gimp->filter_history, link);
-      g_object_unref (procedure);
 
       gimp_filter_history_changed (gimp);
     }
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9979dfd..a4fa4f8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -42,7 +42,6 @@ app/actions/error-console-commands.c
 app/actions/file-actions.c
 app/actions/file-commands.c
 app/actions/filters-actions.c
-app/actions/filters-commands.c
 app/actions/fonts-actions.c
 app/actions/gradient-editor-actions.c
 app/actions/gradient-editor-commands.c


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