[gimp] Bug 789764 - Please add Paste In Place feature
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 789764 - Please add Paste In Place feature
- Date: Sun, 12 Nov 2017 17:44:32 +0000 (UTC)
commit f12d0d8c29fc73bb439d2a9f1aee9c45538a60d0
Author: Michael Natterer <mitch gimp org>
Date: Sun Nov 12 18:41:05 2017 +0100
Bug 789764 - Please add Paste In Place feature
Add "In Place" variants for all sorts of pasting:
- extend the GimpPasteType enum with IN_PLACE values
- add the needed actions and menu items
- merge the action callbacks into one, taking an enum value as parameter
- refactor the pasting code in gimp-edit.c into smaller functions
We probably have too menu items in the "Edit" menu now, needs to be
sorted out.
app/actions/buffers-actions.c | 69 ++++++---
app/actions/buffers-commands.c | 110 +++++---------
app/actions/buffers-commands.h | 5 +-
app/actions/edit-actions.c | 82 +++++++---
app/actions/edit-commands.c | 52 ++++----
app/actions/edit-commands.h | 5 +-
app/core/core-enums.c | 6 +
app/core/core-enums.h | 5 +-
app/core/gimp-edit.c | 321 +++++++++++++++++++++++++---------------
app/core/gimp-edit.h | 10 --
app/widgets/gimpbufferview.c | 16 ++-
app/widgets/gimphelp-ids.h | 6 +
menus/buffers-menu.xml | 3 +
menus/image-menu.xml.in | 3 +
14 files changed, 417 insertions(+), 276 deletions(-)
---
diff --git a/app/actions/buffers-actions.c b/app/actions/buffers-actions.c
index 1321d80..18d1f5f 100644
--- a/app/actions/buffers-actions.c
+++ b/app/actions/buffers-actions.c
@@ -42,35 +42,58 @@ static const GimpActionEntry buffers_actions[] =
NC_("buffers-action", "Buffers Menu"), NULL, NULL, NULL,
GIMP_HELP_BUFFER_DIALOG },
+ { "buffers-paste-as-new-image", GIMP_ICON_EDIT_PASTE_AS_NEW,
+ NC_("buffers-action", "Paste Buffer as _New Image"), NULL,
+ NC_("buffers-action", "Paste the selected buffer as a new image"),
+ G_CALLBACK (buffers_paste_as_new_image_cmd_callback),
+ GIMP_HELP_BUFFER_PASTE_AS_NEW_IMAGE },
+
+ { "buffers-delete", GIMP_ICON_EDIT_DELETE,
+ NC_("buffers-action", "_Delete Buffer"), NULL,
+ NC_("buffers-action", "Delete the selected buffer"),
+ G_CALLBACK (buffers_delete_cmd_callback),
+ GIMP_HELP_BUFFER_DELETE }
+};
+
+static const GimpEnumActionEntry buffers_paste_actions[] =
+{
{ "buffers-paste", GIMP_ICON_EDIT_PASTE,
NC_("buffers-action", "_Paste Buffer"), NULL,
NC_("buffers-action", "Paste the selected buffer"),
- G_CALLBACK (buffers_paste_cmd_callback),
+ GIMP_PASTE_TYPE_FLOATING, FALSE,
GIMP_HELP_BUFFER_PASTE },
+ { "buffers-paste-in-place", GIMP_ICON_EDIT_PASTE,
+ NC_("buffers-action", "Paste Buffer In Pl_ace"), NULL,
+ NC_("buffers-action", "Paste the selected buffer at its original position"),
+ GIMP_PASTE_TYPE_FLOATING_IN_PLACE, FALSE,
+ GIMP_HELP_BUFFER_PASTE_IN_PLACE },
+
{ "buffers-paste-into", GIMP_ICON_EDIT_PASTE_INTO,
NC_("buffers-action", "Paste Buffer _Into"), NULL,
NC_("buffers-action", "Paste the selected buffer into the selection"),
- G_CALLBACK (buffers_paste_into_cmd_callback),
+ GIMP_PASTE_TYPE_FLOATING_INTO, FALSE,
GIMP_HELP_BUFFER_PASTE_INTO },
+ { "buffers-paste-into-in-place", GIMP_ICON_EDIT_PASTE_INTO,
+ NC_("buffers-action", "Paste Buffer Into In Place"), NULL,
+ NC_("buffers-action",
+ "Paste the selected buffer into the selection at its original position"),
+ GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE, FALSE,
+ GIMP_HELP_BUFFER_PASTE_INTO_IN_PLACE },
+
{ "buffers-paste-as-new-layer", GIMP_ICON_EDIT_PASTE_AS_NEW,
NC_("buffers-action", "Paste Buffer as New _Layer"), NULL,
NC_("buffers-action", "Paste the selected buffer as a new layer"),
- G_CALLBACK (buffers_paste_as_new_layer_cmd_callback),
+ GIMP_PASTE_TYPE_NEW_LAYER, FALSE,
GIMP_HELP_BUFFER_PASTE_AS_NEW_LAYER },
- { "buffers-paste-as-new-image", GIMP_ICON_EDIT_PASTE_AS_NEW,
- NC_("buffers-action", "Paste Buffer as _New Image"), NULL,
- NC_("buffers-action", "Paste the selected buffer as a new image"),
- G_CALLBACK (buffers_paste_as_new_image_cmd_callback),
- GIMP_HELP_BUFFER_PASTE_AS_NEW_IMAGE },
-
- { "buffers-delete", GIMP_ICON_EDIT_DELETE,
- NC_("buffers-action", "_Delete Buffer"), NULL,
- NC_("buffers-action", "Delete the selected buffer"),
- G_CALLBACK (buffers_delete_cmd_callback),
- GIMP_HELP_BUFFER_DELETE }
+ { "buffers-paste-as-new-layer-in-place", GIMP_ICON_EDIT_PASTE_AS_NEW,
+ NC_("buffers-action", "Paste Buffer as New Layer in Place"), NULL,
+ NC_("buffers-action",
+ "Paste the selected buffer as a new layer at its original position"),
+ GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, FALSE,
+ GIMP_HELP_BUFFER_PASTE_AS_NEW_LAYER_IN_PLACE },
};
@@ -80,6 +103,11 @@ buffers_actions_setup (GimpActionGroup *group)
gimp_action_group_add_actions (group, "buffers-action",
buffers_actions,
G_N_ELEMENTS (buffers_actions));
+
+ gimp_action_group_add_enum_actions (group, "buffers-action",
+ buffers_paste_actions,
+ G_N_ELEMENTS (buffers_paste_actions),
+ G_CALLBACK (buffers_paste_cmd_callback));
}
void
@@ -95,11 +123,14 @@ buffers_actions_update (GimpActionGroup *group,
#define SET_SENSITIVE(action,condition) \
gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
- SET_SENSITIVE ("buffers-paste", buffer);
- SET_SENSITIVE ("buffers-paste-into", buffer);
- SET_SENSITIVE ("buffers-paste-as-new-layer", buffer);
- SET_SENSITIVE ("buffers-paste-as-new-image", buffer);
- SET_SENSITIVE ("buffers-delete", buffer);
+ SET_SENSITIVE ("buffers-paste", buffer);
+ SET_SENSITIVE ("buffers-paste-in-place", buffer);
+ SET_SENSITIVE ("buffers-paste-into", buffer);
+ SET_SENSITIVE ("buffers-paste-into-in-place", buffer);
+ SET_SENSITIVE ("buffers-paste-as-new-layer", buffer);
+ SET_SENSITIVE ("buffers-paste-as-new-layer-in-place", buffer);
+ SET_SENSITIVE ("buffers-paste-as-new-image", buffer);
+ SET_SENSITIVE ("buffers-delete", buffer);
#undef SET_SENSITIVE
}
diff --git a/app/actions/buffers-commands.c b/app/actions/buffers-commands.c
index a0fe7c8..454429e 100644
--- a/app/actions/buffers-commands.c
+++ b/app/actions/buffers-commands.c
@@ -30,7 +30,7 @@
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
-#include "widgets/gimpbufferview.h"
+#include "widgets/gimpcontainereditor.h"
#include "widgets/gimpcontainerview.h"
#include "widgets/gimpcontainerview-utils.h"
@@ -43,84 +43,18 @@
#include "gimp-intl.h"
-/* local function prototypes */
-
-static void buffers_paste (GimpBufferView *view,
- GimpPasteType paste_type);
-
-
/* public functionss */
void
buffers_paste_cmd_callback (GtkAction *action,
+ gint value,
gpointer data)
{
- buffers_paste (GIMP_BUFFER_VIEW (data), GIMP_PASTE_TYPE_FLOATING);
-}
-
-void
-buffers_paste_into_cmd_callback (GtkAction *action,
- gpointer data)
-{
- buffers_paste (GIMP_BUFFER_VIEW (data), GIMP_PASTE_TYPE_FLOATING_INTO);
-}
-
-void
-buffers_paste_as_new_layer_cmd_callback (GtkAction *action,
- gpointer data)
-{
- buffers_paste (GIMP_BUFFER_VIEW (data), GIMP_PASTE_TYPE_NEW_LAYER);
-}
-
-void
-buffers_paste_as_new_image_cmd_callback (GtkAction *action,
- gpointer data)
-{
- GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data);
- GimpContainer *container;
- GimpContext *context;
- GimpBuffer *buffer;
-
- container = gimp_container_view_get_container (editor->view);
- context = gimp_container_view_get_context (editor->view);
-
- buffer = gimp_context_get_buffer (context);
-
- if (buffer && gimp_container_have (container, GIMP_OBJECT (buffer)))
- {
- GtkWidget *widget = GTK_WIDGET (editor);
- GimpImage *new_image;
-
- new_image = gimp_edit_paste_as_new_image (context->gimp,
- GIMP_OBJECT (buffer));
- gimp_create_display (context->gimp, new_image,
- GIMP_UNIT_PIXEL, 1.0,
- G_OBJECT (gtk_widget_get_screen (widget)),
- gimp_widget_get_monitor (widget));
- g_object_unref (new_image);
- }
-}
-
-void
-buffers_delete_cmd_callback (GtkAction *action,
- gpointer data)
-{
GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data);
-
- gimp_container_view_remove_active (editor->view);
-}
-
-
-/* private functions */
-
-static void
-buffers_paste (GimpBufferView *view,
- GimpPasteType paste_type)
-{
- GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (view);
GimpContainer *container;
GimpContext *context;
GimpBuffer *buffer;
+ GimpPasteType paste_type = (GimpPasteType) value;
container = gimp_container_view_get_container (editor->view);
context = gimp_container_view_get_context (editor->view);
@@ -160,3 +94,41 @@ buffers_paste (GimpBufferView *view,
}
}
}
+
+void
+buffers_paste_as_new_image_cmd_callback (GtkAction *action,
+ gpointer data)
+{
+ GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data);
+ GimpContainer *container;
+ GimpContext *context;
+ GimpBuffer *buffer;
+
+ container = gimp_container_view_get_container (editor->view);
+ context = gimp_container_view_get_context (editor->view);
+
+ buffer = gimp_context_get_buffer (context);
+
+ if (buffer && gimp_container_have (container, GIMP_OBJECT (buffer)))
+ {
+ GtkWidget *widget = GTK_WIDGET (editor);
+ GimpImage *new_image;
+
+ new_image = gimp_edit_paste_as_new_image (context->gimp,
+ GIMP_OBJECT (buffer));
+ gimp_create_display (context->gimp, new_image,
+ GIMP_UNIT_PIXEL, 1.0,
+ G_OBJECT (gtk_widget_get_screen (widget)),
+ gimp_widget_get_monitor (widget));
+ g_object_unref (new_image);
+ }
+}
+
+void
+buffers_delete_cmd_callback (GtkAction *action,
+ gpointer data)
+{
+ GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (data);
+
+ gimp_container_view_remove_active (editor->view);
+}
diff --git a/app/actions/buffers-commands.h b/app/actions/buffers-commands.h
index 8c4dcf5..3af7413 100644
--- a/app/actions/buffers-commands.h
+++ b/app/actions/buffers-commands.h
@@ -20,10 +20,7 @@
void buffers_paste_cmd_callback (GtkAction *action,
- gpointer data);
-void buffers_paste_into_cmd_callback (GtkAction *action,
- gpointer data);
-void buffers_paste_as_new_layer_cmd_callback (GtkAction *action,
+ gint value,
gpointer data);
void buffers_paste_as_new_image_cmd_callback (GtkAction *action,
gpointer data);
diff --git a/app/actions/edit-actions.c b/app/actions/edit-actions.c
index fef6980..d2f6a46 100644
--- a/app/actions/edit-actions.c
+++ b/app/actions/edit-actions.c
@@ -126,25 +126,6 @@ static const GimpActionEntry edit_actions[] =
G_CALLBACK (edit_copy_visible_cmd_callback),
GIMP_HELP_EDIT_COPY_VISIBLE },
- { "edit-paste", GIMP_ICON_EDIT_PASTE,
- NC_("edit-action", "_Paste"), "<primary>V",
- NC_("edit-action", "Paste the content of the clipboard"),
- G_CALLBACK (edit_paste_cmd_callback),
- GIMP_HELP_EDIT_PASTE },
-
- { "edit-paste-into", GIMP_ICON_EDIT_PASTE_INTO,
- NC_("edit-action", "Paste _Into"), NULL,
- NC_("edit-action",
- "Paste the content of the clipboard into the current selection"),
- G_CALLBACK (edit_paste_into_cmd_callback),
- GIMP_HELP_EDIT_PASTE_INTO },
-
- { "edit-paste-as-new-layer", NULL,
- NC_("edit-action", "New _Layer"), NULL,
- NC_("edit-action", "Create a new layer from the content of the clipboard"),
- G_CALLBACK (edit_paste_as_new_layer_cmd_callback),
- GIMP_HELP_EDIT_PASTE_AS_NEW_LAYER },
-
{ "edit-paste-as-new-image", GIMP_ICON_EDIT_PASTE_AS_NEW,
NC_("edit-action", "From _Clipboard"), "<primary><shift>V",
NC_("edit-action", "Create a new image from the content of the clipboard"),
@@ -189,6 +170,51 @@ static const GimpActionEntry edit_actions[] =
GIMP_HELP_EDIT_CLEAR }
};
+static const GimpEnumActionEntry edit_paste_actions[] =
+{
+ { "edit-paste", GIMP_ICON_EDIT_PASTE,
+ NC_("edit-action", "_Paste"), "<primary>V",
+ NC_("edit-action", "Paste the content of the clipboard"),
+ GIMP_PASTE_TYPE_FLOATING, FALSE,
+ GIMP_HELP_EDIT_PASTE },
+
+ { "edit-paste-in-place", GIMP_ICON_EDIT_PASTE,
+ NC_("edit-action", "Paste In Place"), NULL,
+ NC_("edit-action",
+ "Paste the content of the clipboard at its original position"),
+ GIMP_PASTE_TYPE_FLOATING_IN_PLACE, FALSE,
+ GIMP_HELP_EDIT_PASTE_IN_PLACE },
+
+ { "edit-paste-into", GIMP_ICON_EDIT_PASTE_INTO,
+ NC_("edit-action", "Paste _Into Selection"), NULL,
+ NC_("edit-action",
+ "Paste the content of the clipboard into the current selection"),
+ GIMP_PASTE_TYPE_FLOATING_INTO, FALSE,
+ GIMP_HELP_EDIT_PASTE_INTO },
+
+ { "edit-paste-into-in-place", GIMP_ICON_EDIT_PASTE_INTO,
+ NC_("edit-action", "Paste Into Selection In Place"), NULL,
+ NC_("edit-action",
+ "Paste the content of the clipboard into the current selection "
+ "at its original position"),
+ GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE, FALSE,
+ GIMP_HELP_EDIT_PASTE_INTO_IN_PLACE },
+
+ { "edit-paste-as-new-layer", GIMP_ICON_EDIT_PASTE_AS_NEW,
+ NC_("edit-action", "New _Layer"), NULL,
+ NC_("edit-action", "Create a new layer from the content of the clipboard"),
+ GIMP_PASTE_TYPE_NEW_LAYER, FALSE,
+ GIMP_HELP_EDIT_PASTE_AS_NEW_LAYER },
+
+ { "edit-paste-as-new-layer-in-place", GIMP_ICON_EDIT_PASTE_AS_NEW,
+ NC_("edit-action", "New Layer In _Place"), NULL,
+ NC_("edit-action",
+ "Create a new layer from the content of the clipboard"
+ "and place it at its original position"),
+ GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, FALSE,
+ GIMP_HELP_EDIT_PASTE_AS_NEW_LAYER_IN_PLACE }
+};
+
static const GimpEnumActionEntry edit_fill_actions[] =
{
{ "edit-fill-fg", GIMP_ICON_TOOL_BUCKET_FILL,
@@ -224,6 +250,11 @@ edit_actions_setup (GimpActionGroup *group)
G_N_ELEMENTS (edit_actions));
gimp_action_group_add_enum_actions (group, "edit-action",
+ edit_paste_actions,
+ G_N_ELEMENTS (edit_paste_actions),
+ G_CALLBACK (edit_paste_cmd_callback));
+
+ gimp_action_group_add_enum_actions (group, "edit-action",
edit_fill_actions,
G_N_ELEMENTS (edit_fill_actions),
G_CALLBACK (edit_fill_cmd_callback));
@@ -359,12 +390,15 @@ edit_actions_update (GimpActionGroup *group,
g_free (redo_name);
g_free (fade_name);
- SET_SENSITIVE ("edit-cut", writable && !children);
- SET_SENSITIVE ("edit-copy", drawable);
- SET_SENSITIVE ("edit-copy-visible", image);
+ SET_SENSITIVE ("edit-cut", writable && !children);
+ SET_SENSITIVE ("edit-copy", drawable);
+ SET_SENSITIVE ("edit-copy-visible", image);
/* "edit-paste" is always active */
- SET_SENSITIVE ("edit-paste-into", image);
- SET_SENSITIVE ("edit-paste-as-new-layer", image);
+ SET_SENSITIVE ("edit-paste-in-place", image);
+ SET_SENSITIVE ("edit-paste-into", image);
+ SET_SENSITIVE ("edit-paste-into-in-place", image);
+ SET_SENSITIVE ("edit-paste-as-new-layer", image);
+ SET_SENSITIVE ("edit-paste-as-new-layer-in-place", image);
SET_SENSITIVE ("edit-named-cut", writable && !children);
SET_SENSITIVE ("edit-named-copy", drawable);
diff --git a/app/actions/edit-commands.c b/app/actions/edit-commands.c
index ef2a9a0..9959c63 100644
--- a/app/actions/edit-commands.c
+++ b/app/actions/edit-commands.c
@@ -65,7 +65,7 @@
/* local function prototypes */
static void edit_paste (GimpDisplay *display,
- GimpPasteType paste_into,
+ GimpPasteType paste_type,
gboolean try_svg);
static void cut_named_buffer_callback (GtkWidget *widget,
const gchar *name,
@@ -327,38 +327,38 @@ edit_copy_visible_cmd_callback (GtkAction *action,
void
edit_paste_cmd_callback (GtkAction *action,
+ gint value,
gpointer data)
{
- GimpDisplay *display = action_data_get_display (data);
+ GimpDisplay *display = action_data_get_display (data);
+ GimpPasteType paste_type = (GimpPasteType) value;
- if (display && gimp_display_get_image (display))
+ if (paste_type == GIMP_PASTE_TYPE_FLOATING)
{
- edit_paste (display, GIMP_PASTE_TYPE_FLOATING, TRUE);
- }
- else
- {
- edit_paste_as_new_image_cmd_callback (action, data);
+ if (! display || ! gimp_display_get_image (display))
+ {
+ edit_paste_as_new_image_cmd_callback (action, data);
+ return;
+ }
}
-}
-
-void
-edit_paste_into_cmd_callback (GtkAction *action,
- gpointer data)
-{
- GimpDisplay *display;
- return_if_no_display (display, data);
- edit_paste (display, GIMP_PASTE_TYPE_FLOATING_INTO, TRUE);
-}
+ if (! display)
+ return;
-void
-edit_paste_as_new_layer_cmd_callback (GtkAction *action,
- gpointer data)
-{
- GimpDisplay *display;
- return_if_no_display (display, data);
-
- edit_paste (display, GIMP_PASTE_TYPE_NEW_LAYER, FALSE);
+ switch (paste_type)
+ {
+ case GIMP_PASTE_TYPE_FLOATING:
+ case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
+ case GIMP_PASTE_TYPE_FLOATING_INTO:
+ case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
+ edit_paste (display, paste_type, TRUE);
+ break;
+
+ case GIMP_PASTE_TYPE_NEW_LAYER:
+ case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
+ edit_paste (display, paste_type, FALSE);
+ break;
+ }
}
void
diff --git a/app/actions/edit-commands.h b/app/actions/edit-commands.h
index 940dcc7..bb91675 100644
--- a/app/actions/edit-commands.h
+++ b/app/actions/edit-commands.h
@@ -41,10 +41,7 @@ void edit_copy_visible_cmd_callback (GtkAction *action,
gpointer data);
void edit_paste_cmd_callback (GtkAction *action,
- gpointer data);
-void edit_paste_into_cmd_callback (GtkAction *action,
- gpointer data);
-void edit_paste_as_new_layer_cmd_callback (GtkAction *action,
+ gint value,
gpointer data);
void edit_paste_as_new_image_cmd_callback (GtkAction *action,
gpointer data);
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 1e1570e..645c022 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -319,16 +319,22 @@ gimp_paste_type_get_type (void)
static const GEnumValue values[] =
{
{ GIMP_PASTE_TYPE_FLOATING, "GIMP_PASTE_TYPE_FLOATING", "floating" },
+ { GIMP_PASTE_TYPE_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_FLOATING_IN_PLACE", "floating-in-place" },
{ GIMP_PASTE_TYPE_FLOATING_INTO, "GIMP_PASTE_TYPE_FLOATING_INTO", "floating-into" },
+ { GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE, "GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE",
"floating-into-in-place" },
{ GIMP_PASTE_TYPE_NEW_LAYER, "GIMP_PASTE_TYPE_NEW_LAYER", "new-layer" },
+ { GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE", "new-layer-in-place" },
{ 0, NULL, NULL }
};
static const GimpEnumDesc descs[] =
{
{ GIMP_PASTE_TYPE_FLOATING, "GIMP_PASTE_TYPE_FLOATING", NULL },
+ { GIMP_PASTE_TYPE_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_FLOATING_IN_PLACE", NULL },
{ GIMP_PASTE_TYPE_FLOATING_INTO, "GIMP_PASTE_TYPE_FLOATING_INTO", NULL },
+ { GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE, "GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE", NULL },
{ GIMP_PASTE_TYPE_NEW_LAYER, "GIMP_PASTE_TYPE_NEW_LAYER", NULL },
+ { GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE", NULL },
{ 0, NULL, NULL }
};
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 429de3a..eb7a2ad 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -169,8 +169,11 @@ GType gimp_paste_type_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_PASTE_TYPE_FLOATING,
+ GIMP_PASTE_TYPE_FLOATING_IN_PLACE,
GIMP_PASTE_TYPE_FLOATING_INTO,
- GIMP_PASTE_TYPE_NEW_LAYER
+ GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE,
+ GIMP_PASTE_TYPE_NEW_LAYER,
+ GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE
} GimpPasteType;
diff --git a/app/core/gimp-edit.c b/app/core/gimp-edit.c
index 4ecbe13..5d2fa96 100644
--- a/app/core/gimp-edit.c
+++ b/app/core/gimp-edit.c
@@ -80,8 +80,15 @@ gimp_edit_cut (GimpImage *image,
gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpImage *clip_image;
+ gint off_x, off_y;
+
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
clip_image = gimp_image_new_from_drawable (image->gimp, drawable);
+ g_object_set_data (G_OBJECT (clip_image), "offset-x",
+ GINT_TO_POINTER (off_x));
+ g_object_set_data (G_OBJECT (clip_image), "offset-y",
+ GINT_TO_POINTER (off_y));
gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
gimp_set_clipboard_image (image->gimp, clip_image);
g_object_unref (clip_image);
@@ -131,8 +138,15 @@ gimp_edit_copy (GimpImage *image,
gimp_channel_is_empty (gimp_image_get_mask (image)))
{
GimpImage *clip_image;
+ gint off_x, off_y;
+
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
clip_image = gimp_image_new_from_drawable (image->gimp, drawable);
+ g_object_set_data (G_OBJECT (clip_image), "offset-x",
+ GINT_TO_POINTER (off_x));
+ g_object_set_data (G_OBJECT (clip_image), "offset-y",
+ GINT_TO_POINTER (off_y));
gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
gimp_set_clipboard_image (image->gimp, clip_image);
g_object_unref (clip_image);
@@ -183,16 +197,110 @@ gimp_edit_copy_visible (GimpImage *image,
return NULL;
}
-void
-gimp_edit_get_paste_offset (GimpImage *image,
- GimpDrawable *drawable,
- GimpObject *paste,
- gint viewport_x,
- gint viewport_y,
- gint viewport_width,
- gint viewport_height,
- gint *offset_x,
- gint *offset_y)
+static GimpLayer *
+gimp_edit_paste_get_layer (GimpImage *image,
+ GimpDrawable *drawable,
+ GimpObject *paste,
+ GimpPasteType *paste_type)
+{
+ GimpLayer *layer = NULL;
+ const Babl *floating_format;
+
+ /* change paste type to NEW_LAYER for cases where we can't attach a
+ * floating selection
+ */
+ if (! drawable ||
+ gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
+ gimp_item_is_content_locked (GIMP_ITEM (drawable)))
+ {
+ *paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
+ }
+
+ /* floating pastes always have the pasted-to drawable's format with
+ * alpha; if drawable == NULL, user is pasting into an empty image
+ */
+ if (drawable)
+ floating_format = gimp_drawable_get_format_with_alpha (drawable);
+ else
+ floating_format = gimp_image_get_layer_format (image, TRUE);
+
+ if (GIMP_IS_IMAGE (paste))
+ {
+ GType layer_type;
+
+ layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data;
+
+ switch (*paste_type)
+ {
+ case GIMP_PASTE_TYPE_FLOATING:
+ case GIMP_PASTE_TYPE_FLOATING_INTO:
+ /* when pasting as floating selection, force creation of a
+ * plain layer, so gimp_item_convert() will collapse a
+ * group layer
+ */
+ layer_type = GIMP_TYPE_LAYER;
+ break;
+
+ case GIMP_PASTE_TYPE_NEW_LAYER:
+ layer_type = G_TYPE_FROM_INSTANCE (layer);
+ break;
+
+ default:
+ g_return_val_if_reached (NULL);
+ }
+
+ layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
+ image, layer_type));
+
+ switch (*paste_type)
+ {
+ case GIMP_PASTE_TYPE_FLOATING:
+ case GIMP_PASTE_TYPE_FLOATING_INTO:
+ /* when pasting as floating selection, get rid of the layer mask,
+ * and make sure the layer has the right format
+ */
+ if (gimp_layer_get_mask (layer))
+ gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
+
+ if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) !=
+ floating_format)
+ {
+ gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
+ gimp_drawable_get_base_type (drawable),
+ gimp_drawable_get_precision (drawable),
+ TRUE,
+ NULL,
+ GEGL_DITHER_NONE, GEGL_DITHER_NONE,
+ FALSE, NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (GIMP_IS_BUFFER (paste))
+ {
+ layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
+ floating_format,
+ _("Pasted Layer"),
+ GIMP_OPACITY_OPAQUE,
+ gimp_image_get_default_new_layer_mode (image));
+ }
+
+ return layer;
+}
+
+static void
+gimp_edit_paste_get_viewport_offset (GimpImage *image,
+ GimpDrawable *drawable,
+ GimpObject *paste,
+ gint viewport_x,
+ gint viewport_y,
+ gint viewport_width,
+ gint viewport_height,
+ gint *offset_x,
+ gint *offset_y)
{
gint image_width;
gint image_height;
@@ -321,119 +429,45 @@ gimp_edit_get_paste_offset (GimpImage *image,
}
}
-GimpLayer *
-gimp_edit_paste (GimpImage *image,
- GimpDrawable *drawable,
- GimpObject *paste,
- GimpPasteType paste_type,
- gint viewport_x,
- gint viewport_y,
- gint viewport_width,
- gint viewport_height)
+static void
+gimp_edit_paste_get_paste_offset (GimpImage *image,
+ GimpDrawable *drawable,
+ GimpObject *paste,
+ gint *offset_x,
+ gint *offset_y)
{
- GimpLayer *layer = NULL;
- const Babl *floating_format;
- gint offset_x;
- gint offset_y;
-
- g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
- g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
- g_return_val_if_fail (drawable == NULL ||
- gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
- g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
-
- /* change paste type to NEW_LAYER for cases where we can't attach a
- * floating selection
- */
- if (! drawable ||
- gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
- gimp_item_is_content_locked (GIMP_ITEM (drawable)))
- {
- paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
- }
-
- /* floating pastes always have the pasted-to drawable's format with
- * alpha; if drawable == NULL, user is pasting into an empty image
- */
- if (drawable)
- floating_format = gimp_drawable_get_format_with_alpha (drawable);
- else
- floating_format = gimp_image_get_layer_format (image, TRUE);
+ g_return_if_fail (GIMP_IS_IMAGE (image));
+ g_return_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable));
+ g_return_if_fail (drawable == NULL ||
+ gimp_item_is_attached (GIMP_ITEM (drawable)));
+ g_return_if_fail (GIMP_IS_VIEWABLE (paste));
+ g_return_if_fail (offset_x != NULL);
+ g_return_if_fail (offset_y != NULL);
if (GIMP_IS_IMAGE (paste))
{
- GType layer_type;
-
- layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data;
-
- switch (paste_type)
- {
- case GIMP_PASTE_TYPE_FLOATING:
- case GIMP_PASTE_TYPE_FLOATING_INTO:
- /* when pasting as floating selection, force creation of a
- * plain layer, so gimp_item_convert() will collapse a
- * group layer
- */
- layer_type = GIMP_TYPE_LAYER;
- break;
-
- case GIMP_PASTE_TYPE_NEW_LAYER:
- layer_type = G_TYPE_FROM_INSTANCE (layer);
- break;
-
- default:
- g_return_val_if_reached (NULL);
- }
-
- layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
- image, layer_type));
-
- switch (paste_type)
- {
- case GIMP_PASTE_TYPE_FLOATING:
- case GIMP_PASTE_TYPE_FLOATING_INTO:
- /* when pasting as floating selection, get rid of the layer mask,
- * and make sure the layer has the right format
- */
- if (gimp_layer_get_mask (layer))
- gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
-
- if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) !=
- floating_format)
- {
- gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
- gimp_drawable_get_base_type (drawable),
- gimp_drawable_get_precision (drawable),
- TRUE,
- NULL,
- GEGL_DITHER_NONE, GEGL_DITHER_NONE,
- FALSE, NULL);
- }
- break;
-
- default:
- break;
- }
+ *offset_x = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (paste),
+ "offset-x"));
+ *offset_y = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (paste),
+ "offset-y"));
}
else if (GIMP_IS_BUFFER (paste))
{
- layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
- floating_format,
- _("Pasted Layer"),
- GIMP_OPACITY_OPAQUE,
- gimp_image_get_default_new_layer_mode (image));
- }
+ GimpBuffer *buffer = GIMP_BUFFER (paste);
- if (! layer)
- return NULL;
+ *offset_x = buffer->offset_x;
+ *offset_y = buffer->offset_y;
+ }
+}
- gimp_edit_get_paste_offset (image, drawable, GIMP_OBJECT (layer),
- viewport_x,
- viewport_y,
- viewport_width,
- viewport_height,
- &offset_x,
- &offset_y);
+static GimpLayer *
+gimp_edit_paste_paste (GimpImage *image,
+ GimpDrawable *drawable,
+ GimpLayer *layer,
+ GimpPasteType paste_type,
+ gint offset_x,
+ gint offset_y)
+{
gimp_item_translate (GIMP_ITEM (layer), offset_x, offset_y, FALSE);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
@@ -442,6 +476,7 @@ gimp_edit_paste (GimpImage *image,
switch (paste_type)
{
case GIMP_PASTE_TYPE_FLOATING:
+ case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
/* if there is a selection mask clear it - this might not
* always be desired, but in general, it seems like the correct
* behavior
@@ -452,16 +487,18 @@ gimp_edit_paste (GimpImage *image,
/* fall thru */
case GIMP_PASTE_TYPE_FLOATING_INTO:
+ case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
floating_sel_attach (layer, drawable);
break;
case GIMP_PASTE_TYPE_NEW_LAYER:
+ case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
{
GimpLayer *parent = NULL;
gint position = 0;
- /* always add on top of the passed layer, where we would
- * attach a floating selection
+ /* always add on top of a passed layer, where we would attach
+ * a floating selection
*/
if (GIMP_IS_LAYER (drawable))
{
@@ -479,6 +516,58 @@ gimp_edit_paste (GimpImage *image,
return layer;
}
+GimpLayer *
+gimp_edit_paste (GimpImage *image,
+ GimpDrawable *drawable,
+ GimpObject *paste,
+ GimpPasteType paste_type,
+ gint viewport_x,
+ gint viewport_y,
+ gint viewport_width,
+ gint viewport_height)
+{
+ GimpLayer *layer;
+ gint offset_x = 0;
+ gint offset_y = 0;
+
+ g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
+ g_return_val_if_fail (drawable == NULL ||
+ gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
+ g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
+
+ layer = gimp_edit_paste_get_layer (image, drawable, paste, &paste_type);
+
+ if (! layer)
+ return NULL;
+
+ switch (paste_type)
+ {
+ case GIMP_PASTE_TYPE_FLOATING:
+ case GIMP_PASTE_TYPE_FLOATING_INTO:
+ case GIMP_PASTE_TYPE_NEW_LAYER:
+ gimp_edit_paste_get_viewport_offset (image, drawable, GIMP_OBJECT (layer),
+ viewport_x,
+ viewport_y,
+ viewport_width,
+ viewport_height,
+ &offset_x,
+ &offset_y);
+ break;
+
+ case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
+ case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
+ case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
+ gimp_edit_paste_get_paste_offset (image, drawable, paste,
+ &offset_x,
+ &offset_y);
+ break;
+ }
+
+ return gimp_edit_paste_paste (image, drawable, layer, paste_type,
+ offset_x, offset_y);
+}
+
GimpImage *
gimp_edit_paste_as_new_image (Gimp *gimp,
GimpObject *paste)
diff --git a/app/core/gimp-edit.h b/app/core/gimp-edit.h
index 1103841..dc8b6ac 100644
--- a/app/core/gimp-edit.h
+++ b/app/core/gimp-edit.h
@@ -31,16 +31,6 @@ GimpBuffer * gimp_edit_copy_visible (GimpImage *image,
GimpContext *context,
GError **error);
-void gimp_edit_get_paste_offset (GimpImage *image,
- GimpDrawable *drawable,
- GimpObject *paste,
- gint viewport_x,
- gint viewport_y,
- gint viewport_width,
- gint viewport_height,
- gint *offset_x,
- gint *offset_y);
-
GimpLayer * gimp_edit_paste (GimpImage *image,
GimpDrawable *drawable,
GimpObject *paste,
diff --git a/app/widgets/gimpbufferview.c b/app/widgets/gimpbufferview.c
index 73bf322..3eefb7c 100644
--- a/app/widgets/gimpbufferview.c
+++ b/app/widgets/gimpbufferview.c
@@ -42,6 +42,7 @@
#include "gimpview.h"
#include "gimpviewrendererbuffer.h"
#include "gimpuimanager.h"
+#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
@@ -186,15 +187,24 @@ gimp_buffer_view_new (GimpViewType view_type,
buffer_view->paste_button =
gimp_editor_add_action_button (GIMP_EDITOR (editor->view), "buffers",
- "buffers-paste", NULL);
+ "buffers-paste",
+ "buffers-paste-in-place",
+ gimp_get_extend_selection_mask (),
+ NULL);
buffer_view->paste_into_button =
gimp_editor_add_action_button (GIMP_EDITOR (editor->view), "buffers",
- "buffers-paste-into", NULL);
+ "buffers-paste-into",
+ "buffers-paste-into-in-place",
+ gimp_get_extend_selection_mask (),
+ NULL);
buffer_view->paste_as_new_layer_button =
gimp_editor_add_action_button (GIMP_EDITOR (editor->view), "buffers",
- "buffers-paste-as-new-layer", NULL);
+ "buffers-paste-as-new-layer",
+ "buffers-paste-as-new-layer-in-place",
+ gimp_get_extend_selection_mask (),
+ NULL);
buffer_view->paste_as_new_image_button =
gimp_editor_add_action_button (GIMP_EDITOR (editor->view), "buffers",
diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h
index b9d35a4..174546b 100644
--- a/app/widgets/gimphelp-ids.h
+++ b/app/widgets/gimphelp-ids.h
@@ -56,8 +56,11 @@
#define GIMP_HELP_EDIT_COPY "gimp-edit-copy"
#define GIMP_HELP_EDIT_COPY_VISIBLE "gimp-edit-copy-visible"
#define GIMP_HELP_EDIT_PASTE "gimp-edit-paste"
+#define GIMP_HELP_EDIT_PASTE_IN_PLACE "gimp-edit-paste-in-place"
#define GIMP_HELP_EDIT_PASTE_INTO "gimp-edit-paste-into"
+#define GIMP_HELP_EDIT_PASTE_INTO_IN_PLACE "gimp-edit-paste-into-in-place"
#define GIMP_HELP_EDIT_PASTE_AS_NEW_LAYER "gimp-edit-paste-as-new-layer"
+#define GIMP_HELP_EDIT_PASTE_AS_NEW_LAYER_IN_PLACE "gimp-edit-paste-as-new-layer-in-place"
#define GIMP_HELP_EDIT_PASTE_AS_NEW_IMAGE "gimp-edit-paste-as-new-image"
#define GIMP_HELP_EDIT_CLEAR "gimp-edit-clear"
#define GIMP_HELP_EDIT_FILL_FG "gimp-edit-fill-fg"
@@ -552,8 +555,11 @@
#define GIMP_HELP_BUFFER_CUT "gimp-buffer-cut"
#define GIMP_HELP_BUFFER_COPY "gimp-buffer-copy"
#define GIMP_HELP_BUFFER_PASTE "gimp-buffer-paste"
+#define GIMP_HELP_BUFFER_PASTE_IN_PLACE "gimp-buffer-paste-in-place"
#define GIMP_HELP_BUFFER_PASTE_INTO "gimp-buffer-paste-into"
+#define GIMP_HELP_BUFFER_PASTE_INTO_IN_PLACE "gimp-buffer-paste-into-in-place"
#define GIMP_HELP_BUFFER_PASTE_AS_NEW_LAYER "gimp-buffer-paste-as-new-layer"
+#define GIMP_HELP_BUFFER_PASTE_AS_NEW_LAYER_IN_PLACE "gimp-buffer-paste-as-new-layer-in-place"
#define GIMP_HELP_BUFFER_PASTE_AS_NEW_IMAGE "gimp-buffer-paste-as-new-image"
#define GIMP_HELP_BUFFER_DELETE "gimp-buffer-delete"
diff --git a/menus/buffers-menu.xml b/menus/buffers-menu.xml
index 840ef61..05b7745 100644
--- a/menus/buffers-menu.xml
+++ b/menus/buffers-menu.xml
@@ -4,8 +4,11 @@
<ui>
<popup action="buffers-popup">
<menuitem action="buffers-paste" />
+ <menuitem action="buffers-paste-in-place" />
<menuitem action="buffers-paste-into" />
+ <menuitem action="buffers-paste-into-in-place" />
<menuitem action="buffers-paste-as-new-layer" />
+ <menuitem action="buffers-paste-as-new-layer-in-place" />
<menuitem action="buffers-paste-as-new-image" />
<menuitem action="buffers-delete" />
<separator />
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index e44e073..5a8e856 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -193,10 +193,13 @@
</placeholder>
<placeholder name="Paste">
<menuitem action="edit-paste" />
+ <menuitem action="edit-paste-in-place" />
<menuitem action="edit-paste-into" />
+ <menuitem action="edit-paste-into-in-place" />
</placeholder>
<menu action="edit-paste-as-menu" name="Paste as">
<menuitem action="edit-paste-as-new-layer" />
+ <menuitem action="edit-paste-as-new-layer-in-place" />
<menuitem action="edit-paste-as-new-image-short" />
</menu>
<menu action="edit-buffer-menu" name="Buffer">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]