[gimp] app: add untested infrastructure for tool-internal undo/redo



commit 8320381885e2d108105c79ac2668d1f470e4839b
Author: Michael Natterer <mitch gimp org>
Date:   Sun May 12 19:51:52 2013 +0200

    app: add untested infrastructure for tool-internal undo/redo
    
    Add virtual functions GimpTool::undo(), ::redo(), ::get_undo_desc()
    and ::get_redo_desc() and corresponding wrappers in tool_manager.
    
    Make the edit-undo and edit-redo actions check tool undo/redo first
    before invoking image undo/redo.

 app/actions/edit-actions.c  |   31 ++++--
 app/actions/edit-commands.c |   24 +++-
 app/tools/gimptool.c        |  246 +++++++++++++++++++++++++++++--------------
 app/tools/gimptool.h        |   18 +++
 app/tools/tool_manager.c    |   76 +++++++++++++
 app/tools/tool_manager.h    |    9 ++
 6 files changed, 311 insertions(+), 93 deletions(-)
---
diff --git a/app/actions/edit-actions.c b/app/actions/edit-actions.c
index 627282c..77ce434 100644
--- a/app/actions/edit-actions.c
+++ b/app/actions/edit-actions.c
@@ -38,6 +38,8 @@
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimphelp-ids.h"
 
+#include "tools/tool_manager.h"
+
 #include "actions.h"
 #include "edit-actions.h"
 #include "edit-commands.h"
@@ -268,6 +270,7 @@ edit_actions_update (GimpActionGroup *group,
                      gpointer         data)
 {
   GimpImage    *image        = action_data_get_image (data);
+  GimpDisplay  *display      = action_data_get_display (data);
   GimpDrawable *drawable     = NULL;
   gchar        *undo_name    = NULL;
   gchar        *redo_name    = NULL;
@@ -297,20 +300,28 @@ edit_actions_update (GimpActionGroup *group,
           GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image);
           GimpUndo      *undo       = gimp_undo_stack_peek (undo_stack);
           GimpUndo      *redo       = gimp_undo_stack_peek (redo_stack);
+          const gchar   *tool_undo  = NULL;
+          const gchar   *tool_redo  = NULL;
 
-          if (undo)
+          if (display)
             {
-              undo_name =
-                g_strdup_printf (_("_Undo %s"),
-                                 gimp_object_get_name (undo));
+              tool_undo = tool_manager_get_undo_desc_active (image->gimp,
+                                                             display);
+              tool_redo = tool_manager_get_redo_desc_active (image->gimp,
+                                                             display);
             }
 
-          if (redo)
-            {
-              redo_name =
-                g_strdup_printf (_("_Redo %s"),
-                                 gimp_object_get_name (redo));
-            }
+          if (tool_undo)
+            undo_name = g_strdup_printf (_("_Undo %s"), tool_undo);
+          else if (undo)
+            undo_name = g_strdup_printf (_("_Undo %s"),
+                                         gimp_object_get_name (undo));
+
+          if (tool_redo)
+            redo_name = g_strdup_printf (_("_Redo %s"), tool_redo);
+          else if (redo)
+            redo_name = g_strdup_printf (_("_Redo %s"),
+                                         gimp_object_get_name (redo));
 
           undo = gimp_image_undo_get_fadeable (image);
 
diff --git a/app/actions/edit-commands.c b/app/actions/edit-commands.c
index 04df3ee..c9d39f5 100644
--- a/app/actions/edit-commands.c
+++ b/app/actions/edit-commands.c
@@ -50,6 +50,8 @@
 #include "display/gimpdisplayshell.h"
 #include "display/gimpdisplayshell-transform.h"
 
+#include "tools/tool_manager.h"
+
 #include "dialogs/fade-dialog.h"
 
 #include "actions.h"
@@ -79,22 +81,32 @@ void
 edit_undo_cmd_callback (GtkAction *action,
                         gpointer   data)
 {
-  GimpImage *image;
+  GimpImage   *image;
+  GimpDisplay *display;
   return_if_no_image (image, data);
+  return_if_no_display (display, data);
 
-  if (gimp_image_undo (image))
-    gimp_image_flush (image);
+  if (tool_manager_undo_active (image->gimp, display) ||
+      gimp_image_undo (image))
+    {
+      gimp_image_flush (image);
+    }
 }
 
 void
 edit_redo_cmd_callback (GtkAction *action,
                         gpointer   data)
 {
-  GimpImage *image;
+  GimpImage   *image;
+  GimpDisplay *display;
   return_if_no_image (image, data);
+  return_if_no_display (display, data);
 
-  if (gimp_image_redo (image))
-    gimp_image_flush (image);
+  if (tool_manager_redo_active (image->gimp, display) ||
+      gimp_image_redo (image))
+    {
+      gimp_image_flush (image);
+    }
 }
 
 void
diff --git a/app/tools/gimptool.c b/app/tools/gimptool.c
index 065c843..dd83489 100644
--- a/app/tools/gimptool.c
+++ b/app/tools/gimptool.c
@@ -50,83 +50,91 @@ enum
 };
 
 
-static void       gimp_tool_constructed         (GObject               *object);
-static void       gimp_tool_dispose             (GObject               *object);
-static void       gimp_tool_finalize            (GObject               *object);
-static void       gimp_tool_set_property        (GObject               *object,
-                                                 guint                  property_id,
-                                                 const GValue          *value,
-                                                 GParamSpec            *pspec);
-static void       gimp_tool_get_property        (GObject               *object,
-                                                 guint                  property_id,
-                                                 GValue                *value,
-                                                 GParamSpec            *pspec);
-
-static gboolean   gimp_tool_real_has_display    (GimpTool              *tool,
-                                                 GimpDisplay           *display);
-static GimpDisplay * gimp_tool_real_has_image   (GimpTool              *tool,
-                                                 GimpImage             *image);
-static gboolean   gimp_tool_real_initialize     (GimpTool              *tool,
-                                                 GimpDisplay           *display,
-                                                 GError               **error);
-static void       gimp_tool_real_control        (GimpTool              *tool,
-                                                 GimpToolAction         action,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_button_press   (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 guint32                time,
-                                                 GdkModifierType        state,
-                                                 GimpButtonPressType    press_type,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_button_release (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 guint32                time,
-                                                 GdkModifierType        state,
-                                                 GimpButtonReleaseType  release_type,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_motion         (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 guint32                time,
-                                                 GdkModifierType        state,
-                                                 GimpDisplay           *display);
-static gboolean   gimp_tool_real_key_press      (GimpTool              *tool,
-                                                 GdkEventKey           *kevent,
-                                                 GimpDisplay           *display);
-static gboolean   gimp_tool_real_key_release    (GimpTool              *tool,
-                                                 GdkEventKey           *kevent,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_modifier_key   (GimpTool              *tool,
-                                                 GdkModifierType        key,
-                                                 gboolean               press,
-                                                 GdkModifierType        state,
-                                                 GimpDisplay           *display);
-static void  gimp_tool_real_active_modifier_key (GimpTool              *tool,
-                                                 GdkModifierType        key,
-                                                 gboolean               press,
-                                                 GdkModifierType        state,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_oper_update    (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 GdkModifierType        state,
-                                                 gboolean               proximity,
-                                                 GimpDisplay           *display);
-static void       gimp_tool_real_cursor_update  (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 GdkModifierType        state,
-                                                 GimpDisplay           *display);
-static GimpUIManager * gimp_tool_real_get_popup (GimpTool              *tool,
-                                                 const GimpCoords      *coords,
-                                                 GdkModifierType        state,
-                                                 GimpDisplay           *display,
-                                                 const gchar          **ui_path);
-static void       gimp_tool_real_options_notify (GimpTool              *tool,
-                                                 GimpToolOptions       *options,
-                                                 const GParamSpec      *pspec);
-
-static void       gimp_tool_options_notify      (GimpToolOptions       *options,
-                                                 const GParamSpec      *pspec,
-                                                 GimpTool              *tool);
-static void       gimp_tool_clear_status        (GimpTool              *tool);
+static void            gimp_tool_constructed         (GObject          *object);
+static void            gimp_tool_dispose             (GObject          *object);
+static void            gimp_tool_finalize            (GObject          *object);
+static void            gimp_tool_set_property        (GObject          *object,
+                                                      guint             property_id,
+                                                      const GValue     *value,
+                                                      GParamSpec       *pspec);
+static void            gimp_tool_get_property        (GObject          *object,
+                                                      guint             property_id,
+                                                      GValue           *value,
+                                                      GParamSpec       *pspec);
+
+static gboolean        gimp_tool_real_has_display    (GimpTool         *tool,
+                                                      GimpDisplay      *display);
+static GimpDisplay   * gimp_tool_real_has_image      (GimpTool         *tool,
+                                                      GimpImage        *image);
+static gboolean        gimp_tool_real_initialize     (GimpTool         *tool,
+                                                      GimpDisplay      *display,
+                                                      GError          **error);
+static void            gimp_tool_real_control        (GimpTool         *tool,
+                                                      GimpToolAction    action,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_button_press   (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      guint32           time,
+                                                      GdkModifierType   state,
+                                                      GimpButtonPressType press_type,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_button_release (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      guint32           time,
+                                                      GdkModifierType   state,
+                                                      GimpButtonReleaseType release_type,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_motion         (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      guint32           time,
+                                                      GdkModifierType   state,
+                                                      GimpDisplay      *display);
+static gboolean        gimp_tool_real_key_press      (GimpTool         *tool,
+                                                      GdkEventKey      *kevent,
+                                                      GimpDisplay      *display);
+static gboolean        gimp_tool_real_key_release    (GimpTool         *tool,
+                                                      GdkEventKey      *kevent,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_modifier_key   (GimpTool         *tool,
+                                                      GdkModifierType   key,
+                                                      gboolean          press,
+                                                      GdkModifierType   state,
+                                                      GimpDisplay      *display);
+static void       gimp_tool_real_active_modifier_key (GimpTool         *tool,
+                                                      GdkModifierType   key,
+                                                      gboolean          press,
+                                                      GdkModifierType   state,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_oper_update    (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      GdkModifierType   state,
+                                                      gboolean          proximity,
+                                                      GimpDisplay      *display);
+static void            gimp_tool_real_cursor_update  (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      GdkModifierType   state,
+                                                      GimpDisplay      *display);
+static const gchar   * gimp_tool_real_get_undo_desc  (GimpTool         *tool,
+                                                      GimpDisplay      *display);
+static const gchar   * gimp_tool_real_get_redo_desc  (GimpTool         *tool,
+                                                      GimpDisplay      *display);
+static gboolean        gimp_tool_real_undo           (GimpTool         *tool,
+                                                      GimpDisplay      *display);
+static gboolean        gimp_tool_real_redo           (GimpTool         *tool,
+                                                      GimpDisplay      *display);
+static GimpUIManager * gimp_tool_real_get_popup      (GimpTool         *tool,
+                                                      const GimpCoords *coords,
+                                                      GdkModifierType   state,
+                                                      GimpDisplay      *display,
+                                                      const gchar     **ui_path);
+static void            gimp_tool_real_options_notify (GimpTool         *tool,
+                                                      GimpToolOptions  *options,
+                                                      const GParamSpec *pspec);
+
+static void            gimp_tool_options_notify      (GimpToolOptions  *options,
+                                                      const GParamSpec *pspec,
+                                                      GimpTool         *tool);
+static void            gimp_tool_clear_status        (GimpTool         *tool);
 
 
 G_DEFINE_TYPE_WITH_CODE (GimpTool, gimp_tool, GIMP_TYPE_OBJECT,
@@ -162,6 +170,10 @@ gimp_tool_class_init (GimpToolClass *klass)
   klass->active_modifier_key = gimp_tool_real_active_modifier_key;
   klass->oper_update         = gimp_tool_real_oper_update;
   klass->cursor_update       = gimp_tool_real_cursor_update;
+  klass->get_undo_desc       = gimp_tool_real_get_undo_desc;
+  klass->get_redo_desc       = gimp_tool_real_get_redo_desc;
+  klass->undo                = gimp_tool_real_undo;
+  klass->redo                = gimp_tool_real_redo;
   klass->get_popup           = gimp_tool_real_get_popup;
   klass->options_notify      = gimp_tool_real_options_notify;
 
@@ -418,6 +430,34 @@ gimp_tool_real_cursor_update (GimpTool         *tool,
                         gimp_tool_control_get_cursor_modifier (tool->control));
 }
 
+static const gchar *
+gimp_tool_real_get_undo_desc (GimpTool    *tool,
+                              GimpDisplay *display)
+{
+  return NULL;
+}
+
+static const gchar *
+gimp_tool_real_get_redo_desc (GimpTool    *tool,
+                              GimpDisplay *display)
+{
+  return NULL;
+}
+
+static gboolean
+gimp_tool_real_undo (GimpTool    *tool,
+                     GimpDisplay *display)
+{
+  return FALSE;
+}
+
+static gboolean
+gimp_tool_real_redo (GimpTool    *tool,
+                     GimpDisplay *display)
+{
+  return FALSE;
+}
+
 static GimpUIManager *
 gimp_tool_real_get_popup (GimpTool         *tool,
                           const GimpCoords *coords,
@@ -992,6 +1032,58 @@ gimp_tool_cursor_update (GimpTool         *tool,
   GIMP_TOOL_GET_CLASS (tool)->cursor_update (tool, coords, state, display);
 }
 
+const gchar *
+gimp_tool_get_undo_desc (GimpTool    *tool,
+                         GimpDisplay *display)
+{
+  g_return_val_if_fail (GIMP_IS_TOOL (tool), NULL);
+  g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL);
+
+  if (display == tool->display)
+    return GIMP_TOOL_GET_CLASS (tool)->get_undo_desc (tool, display);
+
+  return NULL;
+}
+
+const gchar *
+gimp_tool_get_redo_desc (GimpTool    *tool,
+                         GimpDisplay *display)
+{
+  g_return_val_if_fail (GIMP_IS_TOOL (tool), NULL);
+  g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL);
+
+  if (display == tool->display)
+    return GIMP_TOOL_GET_CLASS (tool)->get_redo_desc (tool, display);
+
+  return NULL;
+}
+
+gboolean
+gimp_tool_undo (GimpTool    *tool,
+                GimpDisplay *display)
+{
+  g_return_val_if_fail (GIMP_IS_TOOL (tool), FALSE);
+  g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE);
+
+  if (display == tool->display)
+    return GIMP_TOOL_GET_CLASS (tool)->undo (tool, display);
+
+  return FALSE;
+}
+
+gboolean
+gimp_tool_redo (GimpTool    *tool,
+                GimpDisplay *display)
+{
+  g_return_val_if_fail (GIMP_IS_TOOL (tool), FALSE);
+  g_return_val_if_fail (GIMP_IS_DISPLAY (display), FALSE);
+
+  if (display == tool->display)
+    return GIMP_TOOL_GET_CLASS (tool)->redo (tool, display);
+
+  return FALSE;
+}
+
 GimpUIManager *
 gimp_tool_get_popup (GimpTool         *tool,
                      const GimpCoords *coords,
diff --git a/app/tools/gimptool.h b/app/tools/gimptool.h
index 24f5f8b..fbaebae 100644
--- a/app/tools/gimptool.h
+++ b/app/tools/gimptool.h
@@ -134,6 +134,15 @@ struct _GimpToolClass
                                            GdkModifierType        state,
                                            GimpDisplay           *display);
 
+  const gchar   * (* get_undo_desc)       (GimpTool              *tool,
+                                           GimpDisplay           *display);
+  const gchar   * (* get_redo_desc)       (GimpTool              *tool,
+                                           GimpDisplay           *display);
+  gboolean        (* undo)                (GimpTool              *tool,
+                                           GimpDisplay           *display);
+  gboolean        (* redo)                (GimpTool              *tool,
+                                           GimpDisplay           *display);
+
   GimpUIManager * (* get_popup)           (GimpTool              *tool,
                                            const GimpCoords      *coords,
                                            GdkModifierType        state,
@@ -204,6 +213,15 @@ void              gimp_tool_cursor_update       (GimpTool            *tool,
                                                  GdkModifierType      state,
                                                  GimpDisplay         *display);
 
+const gchar     * gimp_tool_get_undo_desc       (GimpTool            *tool,
+                                                 GimpDisplay         *display);
+const gchar     * gimp_tool_get_redo_desc       (GimpTool            *tool,
+                                                 GimpDisplay         *display);
+gboolean          gimp_tool_undo                (GimpTool            *tool,
+                                                 GimpDisplay         *display);
+gboolean          gimp_tool_redo                (GimpTool            *tool,
+                                                 GimpDisplay         *display);
+
 GimpUIManager   * gimp_tool_get_popup           (GimpTool            *tool,
                                                  const GimpCoords    *coords,
                                                  GdkModifierType      state,
diff --git a/app/tools/tool_manager.c b/app/tools/tool_manager.c
index 920c4fd..15b72a2 100644
--- a/app/tools/tool_manager.c
+++ b/app/tools/tool_manager.c
@@ -510,6 +510,82 @@ tool_manager_cursor_update_active (Gimp             *gimp,
     }
 }
 
+const gchar *
+tool_manager_get_undo_desc_active (Gimp        *gimp,
+                                   GimpDisplay *display)
+{
+  GimpToolManager *tool_manager;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+  tool_manager = tool_manager_get (gimp);
+
+  if (tool_manager->active_tool)
+    {
+      return gimp_tool_get_undo_desc (tool_manager->active_tool,
+                                      display);
+    }
+
+  return NULL;
+}
+
+const gchar *
+tool_manager_get_redo_desc_active (Gimp        *gimp,
+                                   GimpDisplay *display)
+{
+  GimpToolManager *tool_manager;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+  tool_manager = tool_manager_get (gimp);
+
+  if (tool_manager->active_tool)
+    {
+      return gimp_tool_get_redo_desc (tool_manager->active_tool,
+                                      display);
+    }
+
+  return NULL;
+}
+
+gboolean
+tool_manager_undo_active (Gimp        *gimp,
+                          GimpDisplay *display)
+{
+  GimpToolManager *tool_manager;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
+
+  tool_manager = tool_manager_get (gimp);
+
+  if (tool_manager->active_tool)
+    {
+      return gimp_tool_undo (tool_manager->active_tool,
+                             display);
+    }
+
+  return FALSE;
+}
+
+gboolean
+tool_manager_redo_active (Gimp        *gimp,
+                          GimpDisplay *display)
+{
+  GimpToolManager *tool_manager;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
+
+  tool_manager = tool_manager_get (gimp);
+
+  if (tool_manager->active_tool)
+    {
+      return gimp_tool_redo (tool_manager->active_tool,
+                             display);
+    }
+
+  return FALSE;
+}
+
 GimpUIManager *
 tool_manager_get_popup_active (Gimp             *gimp,
                                const GimpCoords *coords,
diff --git a/app/tools/tool_manager.h b/app/tools/tool_manager.h
index 54fad22..a1b278f 100644
--- a/app/tools/tool_manager.h
+++ b/app/tools/tool_manager.h
@@ -80,6 +80,15 @@ void       tool_manager_cursor_update_active       (Gimp             *gimp,
                                                     GdkModifierType   state,
                                                     GimpDisplay      *display);
 
+const gchar   * tool_manager_get_undo_desc_active  (Gimp             *gimp,
+                                                    GimpDisplay      *display);
+const gchar   * tool_manager_get_redo_desc_active  (Gimp             *gimp,
+                                                    GimpDisplay      *display);
+gboolean        tool_manager_undo_active           (Gimp             *gimp,
+                                                    GimpDisplay      *display);
+gboolean        tool_manager_redo_active           (Gimp             *gimp,
+                                                    GimpDisplay      *display);
+
 GimpUIManager * tool_manager_get_popup_active      (Gimp             *gimp,
                                                     const GimpCoords *coords,
                                                     GdkModifierType   state,


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