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.
This commit is contained in:
Michael Natterer 2013-05-12 19:51:52 +02:00
parent 113f6c9fc3
commit 8320381885
6 changed files with 309 additions and 91 deletions

View File

@ -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);

View File

@ -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

View File

@ -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 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 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);
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,

View File

@ -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,

View File

@ -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,

View File

@ -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,