[gimp] app: enable copy and paste for curves
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: enable copy and paste for curves
- Date: Tue, 16 Feb 2010 19:00:01 +0000 (UTC)
commit fdde593fc51121e18a12ee65c703b90ca2b12f7e
Author: Michael Natterer <mitch gimp org>
Date: Tue Feb 16 19:58:51 2010 +0100
app: enable copy and paste for curves
Add GimpCurve support to the clipboard and handle ctrl-x, ctrl-c and
ctrl-v in GimpCurveView.
app/widgets/gimpclipboard.c | 210 +++++++++++++++++++++++++
app/widgets/gimpclipboard.h | 4 +
app/widgets/gimpcurveview.c | 298 ++++++++++++++++++++++++++----------
app/widgets/gimpcurveview.h | 6 +
app/widgets/gimpdeviceinfoeditor.c | 1 +
app/widgets/gimpselectiondata.c | 55 +++++++
app/widgets/gimpselectiondata.h | 7 +
7 files changed, 501 insertions(+), 80 deletions(-)
---
diff --git a/app/widgets/gimpclipboard.c b/app/widgets/gimpclipboard.c
index cd0653e..5da1959 100644
--- a/app/widgets/gimpclipboard.c
+++ b/app/widgets/gimpclipboard.c
@@ -25,6 +25,7 @@
#include "core/gimp.h"
#include "core/gimpbuffer.h"
+#include "core/gimpcurve.h"
#include "gimpclipboard.h"
#include "gimppixbuf.h"
@@ -48,8 +49,12 @@ struct _GimpClipboard
GtkTargetEntry *svg_target_entries;
gint n_svg_target_entries;
+ GtkTargetEntry *curve_target_entries;
+ gint n_curve_target_entries;
+
GimpBuffer *buffer;
gchar *svg;
+ GimpCurve *curve;
};
@@ -61,6 +66,7 @@ static GdkAtom * gimp_clipboard_wait_for_targets (Gimp *gimp,
gint *n_targets);
static GdkAtom gimp_clipboard_wait_for_buffer (Gimp *gimp);
static GdkAtom gimp_clipboard_wait_for_svg (Gimp *gimp);
+static GdkAtom gimp_clipboard_wait_for_curve (Gimp *gimp);
static void gimp_clipboard_send_buffer (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
@@ -70,6 +76,10 @@ static void gimp_clipboard_send_svg (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
guint info,
Gimp *gimp);
+static void gimp_clipboard_send_curve (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ Gimp *gimp);
/* public functions */
@@ -162,6 +172,13 @@ gimp_clipboard_init (Gimp *gimp)
gimp_clip->svg_target_entries[1].target = g_strdup ("image/svg+xml");
gimp_clip->svg_target_entries[1].flags = 0;
gimp_clip->svg_target_entries[1].info = 1;
+
+ gimp_clip->n_curve_target_entries = 1;
+ gimp_clip->curve_target_entries = g_new0 (GtkTargetEntry, 1);
+
+ gimp_clip->curve_target_entries[0].target = g_strdup ("application/x-gimp-curve");
+ gimp_clip->curve_target_entries[0].flags = 0;
+ gimp_clip->curve_target_entries[0].info = 0;
}
void
@@ -249,6 +266,39 @@ gimp_clipboard_has_svg (Gimp *gimp)
}
/**
+ * gimp_clipboard_has_curve:
+ * @gimp: pointer to #Gimp
+ *
+ * Tests if there's curve data in %GDK_SELECTION_CLIPBOARD.
+ * This is done in a main-loop similar to
+ * gtk_clipboard_wait_is_text_available(). The same caveats apply here.
+ *
+ * Return value: %TRUE if there's curve data in the clipboard, %FALSE otherwise
+ **/
+gboolean
+gimp_clipboard_has_curve (Gimp *gimp)
+{
+ GimpClipboard *gimp_clip;
+ GtkClipboard *clipboard;
+
+ g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
+
+ clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
+ GDK_SELECTION_CLIPBOARD);
+
+ if (clipboard &&
+ gtk_clipboard_get_owner (clipboard) != G_OBJECT (gimp) &&
+ gimp_clipboard_wait_for_curve (gimp) != GDK_NONE)
+ {
+ return TRUE;
+ }
+
+ gimp_clip = gimp_clipboard_get (gimp);
+
+ return (gimp_clip->curve != NULL);
+}
+
+/**
* gimp_clipboard_get_buffer:
* @gimp: pointer to #Gimp
*
@@ -373,6 +423,59 @@ gimp_clipboard_get_svg (Gimp *gimp,
}
/**
+ * gimp_clipboard_get_curve:
+ * @gimp: pointer to #Gimp
+ *
+ * Retrieves curve data from %GDK_SELECTION_CLIPBOARD or from the global
+ * curve buffer of @gimp.
+ *
+ * The returned curve needs to be unref'ed when it's no longer needed.
+ *
+ * Return value: a reference to a #GimpCurve or %NULL if there's no
+ * curve data
+ **/
+GimpCurve *
+gimp_clipboard_get_curve (Gimp *gimp)
+{
+ GimpClipboard *gimp_clip;
+ GtkClipboard *clipboard;
+ GdkAtom atom;
+ GimpCurve *curve = NULL;
+
+ g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+
+ clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
+ GDK_SELECTION_CLIPBOARD);
+
+ if (clipboard &&
+ gtk_clipboard_get_owner (clipboard) != G_OBJECT (gimp) &&
+ (atom = gimp_clipboard_wait_for_curve (gimp)) != GDK_NONE)
+ {
+ GtkSelectionData *data;
+
+ gimp_set_busy (gimp);
+
+ data = gtk_clipboard_wait_for_contents (clipboard, atom);
+
+ if (data)
+ {
+ curve = gimp_selection_data_get_curve (data);
+
+ gtk_selection_data_free (data);
+ }
+
+ gimp_unset_busy (gimp);
+ }
+
+ gimp_clip = gimp_clipboard_get (gimp);
+
+ if (! curve && gimp_clip->curve)
+ curve = g_object_ref (gimp_clip->curve);
+
+ return curve;
+}
+
+/**
* gimp_clipboard_set_buffer:
* @gimp: pointer to #Gimp
* @buffer: a #GimpBuffer, or %NULL.
@@ -492,6 +595,51 @@ gimp_clipboard_set_text (Gimp *gimp,
gtk_clipboard_set_text (clipboard, text, -1);
}
+/**
+ * gimp_clipboard_set_curve:
+ * @gimp: pointer to #Gimp
+ * @curve: a #GimpCurve, or %NULL
+ *
+ * Offers curve data in %GDK_SELECTION_CLIPBOARD.
+ **/
+void
+gimp_clipboard_set_curve (Gimp *gimp,
+ GimpCurve *curve)
+{
+ GimpClipboard *gimp_clip;
+ GtkClipboard *clipboard;
+
+ g_return_if_fail (GIMP_IS_GIMP (gimp));
+ g_return_if_fail (curve == NULL || GIMP_IS_CURVE (curve));
+
+ clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
+ GDK_SELECTION_CLIPBOARD);
+ if (! clipboard)
+ return;
+
+ gimp_clip = gimp_clipboard_get (gimp);
+
+ gimp_clipboard_clear (gimp_clip);
+
+ if (curve)
+ {
+ gimp_clip->curve = g_object_ref (curve);
+
+ gtk_clipboard_set_with_owner (clipboard,
+ gimp_clip->curve_target_entries,
+ gimp_clip->n_curve_target_entries,
+ (GtkClipboardGetFunc) gimp_clipboard_send_curve,
+ (GtkClipboardClearFunc) NULL,
+ G_OBJECT (gimp));
+
+ gtk_clipboard_set_can_store (clipboard, gimp_clip->curve_target_entries, 1);
+ }
+ else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
+ {
+ gtk_clipboard_clear (clipboard);
+ }
+}
+
/* private functions */
@@ -515,6 +663,12 @@ gimp_clipboard_clear (GimpClipboard *gimp_clip)
g_free (gimp_clip->svg);
gimp_clip->svg = NULL;
}
+
+ if (gimp_clip->curve)
+ {
+ g_object_unref (gimp_clip->curve);
+ gimp_clip->curve = NULL;
+ }
}
static void
@@ -536,6 +690,11 @@ gimp_clipboard_free (GimpClipboard *gimp_clip)
g_free (gimp_clip->svg_target_entries);
+ for (i = 0; i < gimp_clip->n_curve_target_entries; i++)
+ g_free (gimp_clip->curve_target_entries[i].target);
+
+ g_free (gimp_clip->curve_target_entries);
+
g_slice_free (GimpClipboard, gimp_clip);
}
@@ -680,6 +839,35 @@ gimp_clipboard_wait_for_svg (Gimp *gimp)
return result;
}
+static GdkAtom
+gimp_clipboard_wait_for_curve (Gimp *gimp)
+{
+ GdkAtom *targets;
+ gint n_targets;
+ GdkAtom result = GDK_NONE;
+
+ targets = gimp_clipboard_wait_for_targets (gimp, &n_targets);
+
+ if (targets)
+ {
+ GdkAtom curve_atom = gdk_atom_intern_static_string ("application/x-gimp-curve");
+ gint i;
+
+ for (i = 0; i < n_targets; i++)
+ {
+ if (targets[i] == curve_atom)
+ {
+ result = curve_atom;
+ break;
+ }
+ }
+
+ g_free (targets);
+ }
+
+ return result;
+}
+
static void
gimp_clipboard_send_buffer (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
@@ -735,3 +923,25 @@ gimp_clipboard_send_svg (GtkClipboard *clipboard,
gimp_unset_busy (gimp);
}
+
+static void
+gimp_clipboard_send_curve (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ Gimp *gimp)
+{
+ GimpClipboard *gimp_clip = gimp_clipboard_get (gimp);
+
+ gimp_set_busy (gimp);
+
+ if (gimp_clip->curve)
+ {
+ if (gimp->be_verbose)
+ g_printerr ("clipboard: sending curve data as '%s'\n",
+ gimp_clip->curve_target_entries[info].target);
+
+ gimp_selection_data_set_curve (selection_data, gimp_clip->curve);
+ }
+
+ gimp_unset_busy (gimp);
+}
diff --git a/app/widgets/gimpclipboard.h b/app/widgets/gimpclipboard.h
index 74674c4..eddd15e 100644
--- a/app/widgets/gimpclipboard.h
+++ b/app/widgets/gimpclipboard.h
@@ -24,10 +24,12 @@ void gimp_clipboard_exit (Gimp *gimp);
gboolean gimp_clipboard_has_buffer (Gimp *gimp);
gboolean gimp_clipboard_has_svg (Gimp *gimp);
+gboolean gimp_clipboard_has_curve (Gimp *gimp);
GimpBuffer * gimp_clipboard_get_buffer (Gimp *gimp);
gchar * gimp_clipboard_get_svg (Gimp *gimp,
gsize *svg_length);
+GimpCurve * gimp_clipboard_get_curve (Gimp *gimp);
void gimp_clipboard_set_buffer (Gimp *gimp,
GimpBuffer *buffer);
@@ -35,6 +37,8 @@ void gimp_clipboard_set_svg (Gimp *gimp,
const gchar *svg);
void gimp_clipboard_set_text (Gimp *gimp,
const gchar *text);
+void gimp_clipboard_set_curve (Gimp *gimp,
+ GimpCurve *curve);
#endif /* __GIMP_CLIPBOARD_H__ */
diff --git a/app/widgets/gimpcurveview.c b/app/widgets/gimpcurveview.c
index b794b85..c8511a9 100644
--- a/app/widgets/gimpcurveview.c
+++ b/app/widgets/gimpcurveview.c
@@ -22,56 +22,72 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include "libgimpconfig/gimpconfig.h"
#include "libgimpmath/gimpmath.h"
#include "widgets-types.h"
+#include "core/gimp.h"
#include "core/gimpcurve.h"
#include "core/gimpcurve-map.h"
#include "core/gimpmarshal.h"
+#include "gimpclipboard.h"
#include "gimpcurveview.h"
enum
{
PROP_0,
+ PROP_GIMP,
PROP_BASE_LINE,
PROP_GRID_ROWS,
PROP_GRID_COLUMNS
};
+enum
+{
+ CUT_CLIPBOARD,
+ COPY_CLIPBOARD,
+ PASTE_CLIPBOARD,
+ LAST_SIGNAL
+};
-static void gimp_curve_view_finalize (GObject *object);
-static void gimp_curve_view_dispose (GObject *object);
-static void gimp_curve_view_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_curve_view_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gimp_curve_view_style_set (GtkWidget *widget,
- GtkStyle *prev_style);
-static gboolean gimp_curve_view_expose (GtkWidget *widget,
- GdkEventExpose *event);
-static gboolean gimp_curve_view_button_press (GtkWidget *widget,
- GdkEventButton *bevent);
-static gboolean gimp_curve_view_button_release (GtkWidget *widget,
- GdkEventButton *bevent);
-static gboolean gimp_curve_view_motion_notify (GtkWidget *widget,
- GdkEventMotion *bevent);
-static gboolean gimp_curve_view_leave_notify (GtkWidget *widget,
- GdkEventCrossing *cevent);
-static gboolean gimp_curve_view_key_press (GtkWidget *widget,
- GdkEventKey *kevent);
-
-static void gimp_curve_view_set_cursor (GimpCurveView *view,
- gdouble x,
- gdouble y);
-static void gimp_curve_view_unset_cursor (GimpCurveView *view);
+
+static void gimp_curve_view_finalize (GObject *object);
+static void gimp_curve_view_dispose (GObject *object);
+static void gimp_curve_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_curve_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_curve_view_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static gboolean gimp_curve_view_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static gboolean gimp_curve_view_button_press (GtkWidget *widget,
+ GdkEventButton *bevent);
+static gboolean gimp_curve_view_button_release (GtkWidget *widget,
+ GdkEventButton *bevent);
+static gboolean gimp_curve_view_motion_notify (GtkWidget *widget,
+ GdkEventMotion *bevent);
+static gboolean gimp_curve_view_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *cevent);
+static gboolean gimp_curve_view_key_press (GtkWidget *widget,
+ GdkEventKey *kevent);
+
+static void gimp_curve_view_cut_clipboard (GimpCurveView *view);
+static void gimp_curve_view_copy_clipboard (GimpCurveView *view);
+static void gimp_curve_view_paste_clipboard (GimpCurveView *view);
+
+static void gimp_curve_view_set_cursor (GimpCurveView *view,
+ gdouble x,
+ gdouble y);
+static void gimp_curve_view_unset_cursor (GimpCurveView *view);
G_DEFINE_TYPE (GimpCurveView, gimp_curve_view,
@@ -79,12 +95,15 @@ G_DEFINE_TYPE (GimpCurveView, gimp_curve_view,
#define parent_class gimp_curve_view_parent_class
+static guint curve_view_signals[LAST_SIGNAL] = { 0 };
+
static void
gimp_curve_view_class_init (GimpCurveViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkBindingSet *binding_set;
object_class->finalize = gimp_curve_view_finalize;
object_class->dispose = gimp_curve_view_dispose;
@@ -99,22 +118,70 @@ gimp_curve_view_class_init (GimpCurveViewClass *klass)
widget_class->leave_notify_event = gimp_curve_view_leave_notify;
widget_class->key_press_event = gimp_curve_view_key_press;
+ klass->cut_clipboard = gimp_curve_view_cut_clipboard;
+ klass->copy_clipboard = gimp_curve_view_copy_clipboard;
+ klass->paste_clipboard = gimp_curve_view_paste_clipboard;
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp",
+ NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE));
+
g_object_class_install_property (object_class, PROP_BASE_LINE,
g_param_spec_boolean ("base-line",
NULL, NULL,
TRUE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+
g_object_class_install_property (object_class, PROP_GRID_ROWS,
g_param_spec_int ("grid-rows", NULL, NULL,
0, 100, 8,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+
g_object_class_install_property (object_class, PROP_GRID_COLUMNS,
g_param_spec_int ("grid-columns", NULL, NULL,
0, 100, 8,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+
+ curve_view_signals[CUT_CLIPBOARD] =
+ g_signal_new ("cut-clipboard",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GimpCurveViewClass, cut_clipboard),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ curve_view_signals[COPY_CLIPBOARD] =
+ g_signal_new ("copy-clipboard",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GimpCurveViewClass, copy_clipboard),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ curve_view_signals[PASTE_CLIPBOARD] =
+ g_signal_new ("paste-clipboard",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GimpCurveViewClass, paste_clipboard),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ binding_set = gtk_binding_set_by_class (klass);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_x, GDK_CONTROL_MASK,
+ "cut-clipboard", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_c, GDK_CONTROL_MASK,
+ "copy-clipboard", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_v, GDK_CONTROL_MASK,
+ "paste-clipboard", 0);
}
static void
@@ -179,6 +246,9 @@ gimp_curve_view_set_property (GObject *object,
switch (property_id)
{
+ case PROP_GIMP:
+ view->gimp = g_value_get_object (value); /* don't ref */
+ break;
case PROP_GRID_ROWS:
view->grid_rows = g_value_get_int (value);
break;
@@ -204,6 +274,9 @@ gimp_curve_view_get_property (GObject *object,
switch (property_id)
{
+ case PROP_GIMP:
+ g_value_set_object (value, view->gimp);
+ break;
case PROP_GRID_ROWS:
g_value_set_int (value, view->grid_rows);
break;
@@ -785,82 +858,147 @@ static gboolean
gimp_curve_view_key_press (GtkWidget *widget,
GdkEventKey *kevent)
{
- GimpCurveView *view = GIMP_CURVE_VIEW (widget);
- GimpCurve *curve = view->curve;
- gint i = view->selected;
- gdouble x, y;
- gboolean retval = FALSE;
+ GimpCurveView *view = GIMP_CURVE_VIEW (widget);
+ GimpCurve *curve = view->curve;
+ gboolean handled = FALSE;
- if (view->grabbed || ! curve ||
- gimp_curve_get_curve_type (curve) == GIMP_CURVE_FREE)
- return FALSE;
+ if (! view->grabbed && curve &&
+ gimp_curve_get_curve_type (curve) == GIMP_CURVE_SMOOTH)
+ {
+ gint i = view->selected;
+ gdouble x, y;
- gimp_curve_get_point (curve, i, NULL, &y);
+ gimp_curve_get_point (curve, i, NULL, &y);
- switch (kevent->keyval)
- {
- case GDK_Left:
- for (i = i - 1; i >= 0 && ! retval; i--)
+ switch (kevent->keyval)
{
- gimp_curve_get_point (curve, i, &x, NULL);
+ case GDK_Left:
+ for (i = i - 1; i >= 0 && ! handled; i--)
+ {
+ gimp_curve_get_point (curve, i, &x, NULL);
+
+ if (x >= 0.0)
+ {
+ gimp_curve_view_set_selected (view, i);
- if (x >= 0.0)
+ handled = TRUE;
+ }
+ }
+ break;
+
+ case GDK_Right:
+ for (i = i + 1; i < curve->n_points && ! handled; i++)
{
- gimp_curve_view_set_selected (view, i);
+ gimp_curve_get_point (curve, i, &x, NULL);
- retval = TRUE;
+ if (x >= 0.0)
+ {
+ gimp_curve_view_set_selected (view, i);
+
+ handled = TRUE;
+ }
}
- }
- break;
+ break;
- case GDK_Right:
- for (i = i + 1; i < curve->n_points && ! retval; i++)
- {
- gimp_curve_get_point (curve, i, &x, NULL);
+ case GDK_Up:
+ if (y < 1.0)
+ {
+ y = y + (kevent->state & GDK_SHIFT_MASK ?
+ (16.0 / 255.0) : (1.0 / 255.0));
+
+ gimp_curve_move_point (curve, i, CLAMP (y, 0.0, 1.0));
+
+ handled = TRUE;
+ }
+ break;
- if (x >= 0.0)
+ case GDK_Down:
+ if (y > 0)
{
- gimp_curve_view_set_selected (view, i);
+ y = y - (kevent->state & GDK_SHIFT_MASK ?
+ (16.0 / 255.0) : (1.0 / 255.0));
- retval = TRUE;
+ gimp_curve_move_point (curve, i, CLAMP (y, 0.0, 1.0));
+
+ handled = TRUE;
}
+ break;
+
+ default:
+ break;
}
- break;
+ }
- case GDK_Up:
- if (y < 1.0)
- {
- y = y + (kevent->state & GDK_SHIFT_MASK ?
- (16.0 / 255.0) : (1.0 / 255.0));
+ if (handled)
+ {
+ set_cursor (view, GDK_TCROSS);
- gimp_curve_move_point (curve, i, CLAMP (y, 0.0, 1.0));
+ return TRUE;
+ }
- retval = TRUE;
- }
- break;
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, kevent);
+}
- case GDK_Down:
- if (y > 0)
- {
- y = y - (kevent->state & GDK_SHIFT_MASK ?
- (16.0 / 255.0) : (1.0 / 255.0));
+static void
+gimp_curve_view_cut_clipboard (GimpCurveView *view)
+{
+ g_printerr ("%s\n", G_STRFUNC);
- gimp_curve_move_point (curve, i, CLAMP (y, 0.0, 1.0));
+ if (! view->curve || ! view->gimp)
+ {
+ gtk_widget_error_bell (GTK_WIDGET (view));
+ return;
+ }
- retval = TRUE;
- }
- break;
+ gimp_curve_view_copy_clipboard (view);
- default:
- break;
+ gimp_curve_reset (view->curve, FALSE);
+}
+
+static void
+gimp_curve_view_copy_clipboard (GimpCurveView *view)
+{
+ GimpCurve *copy;
+
+ g_printerr ("%s\n", G_STRFUNC);
+
+ if (! view->curve || ! view->gimp)
+ {
+ gtk_widget_error_bell (GTK_WIDGET (view));
+ return;
}
- if (retval)
- set_cursor (view, GDK_TCROSS);
+ copy = GIMP_CURVE (gimp_data_duplicate (GIMP_DATA (view->curve)));
+ gimp_clipboard_set_curve (view->gimp, copy);
+ g_object_unref (copy);
+}
+
+static void
+gimp_curve_view_paste_clipboard (GimpCurveView *view)
+{
+ GimpCurve *copy;
+
+ g_printerr ("%s\n", G_STRFUNC);
- return retval;
+ if (! view->curve || ! view->gimp)
+ {
+ gtk_widget_error_bell (GTK_WIDGET (view));
+ return;
+ }
+
+ copy = gimp_clipboard_get_curve (view->gimp);
+
+ if (copy)
+ {
+ gimp_config_copy (GIMP_CONFIG (copy),
+ GIMP_CONFIG (view->curve), 0);
+ g_object_unref (copy);
+ }
}
+
+/* public functions */
+
GtkWidget *
gimp_curve_view_new (void)
{
diff --git a/app/widgets/gimpcurveview.h b/app/widgets/gimpcurveview.h
index b3ad32b..98df87c 100644
--- a/app/widgets/gimpcurveview.h
+++ b/app/widgets/gimpcurveview.h
@@ -36,6 +36,8 @@ struct _GimpCurveView
{
GimpHistogramView parent_instance;
+ Gimp *gimp; /* only needed for copy & paste */
+
GimpCurve *curve;
gboolean draw_base_line;
@@ -63,6 +65,10 @@ struct _GimpCurveView
struct _GimpCurveViewClass
{
GimpHistogramViewClass parent_class;
+
+ void (* cut_clipboard) (GimpCurveView *view);
+ void (* copy_clipboard) (GimpCurveView *view);
+ void (* paste_clipboard) (GimpCurveView *view);
};
diff --git a/app/widgets/gimpdeviceinfoeditor.c b/app/widgets/gimpdeviceinfoeditor.c
index f1bd06a..89929bc 100644
--- a/app/widgets/gimpdeviceinfoeditor.c
+++ b/app/widgets/gimpdeviceinfoeditor.c
@@ -441,6 +441,7 @@ gimp_device_info_editor_constructor (GType type,
view = gimp_curve_view_new ();
g_object_set (view,
+ "gimp", GIMP_CONTEXT (private->info)->gimp,
"border-width", CURVE_BORDER,
NULL);
gtk_widget_set_size_request (view,
diff --git a/app/widgets/gimpselectiondata.c b/app/widgets/gimpselectiondata.c
index 69705c5..567d8cf 100644
--- a/app/widgets/gimpselectiondata.c
+++ b/app/widgets/gimpselectiondata.c
@@ -23,6 +23,7 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
#include "widgets-types.h"
@@ -31,6 +32,7 @@
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontainer.h"
+#include "core/gimpcurve.h"
#include "core/gimpdatafactory.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
@@ -362,6 +364,59 @@ gimp_selection_data_get_stream (GtkSelectionData *selection,
}
void
+gimp_selection_data_set_curve (GtkSelectionData *selection,
+ GimpCurve *curve)
+{
+ gchar *str;
+
+ g_return_if_fail (selection != NULL);
+ g_return_if_fail (GIMP_IS_CURVE (curve));
+
+ str = gimp_config_serialize_to_string (GIMP_CONFIG (curve), NULL);
+
+ gtk_selection_data_set (selection,
+ gtk_selection_data_get_target (selection),
+ 8, (guchar *) str, strlen (str));
+
+ g_free (str);
+}
+
+GimpCurve *
+gimp_selection_data_get_curve (GtkSelectionData *selection)
+{
+ GimpCurve *curve;
+ gint length;
+ GError *error = NULL;
+
+ g_return_val_if_fail (selection != NULL, NULL);
+
+ length = gtk_selection_data_get_length (selection);
+
+ if (gtk_selection_data_get_format (selection) != 8 || length < 1)
+ {
+ g_warning ("Received invalid curve data!");
+ return NULL;
+ }
+
+ curve = GIMP_CURVE (gimp_curve_new ("pasted curve"));
+
+ if (! gimp_config_deserialize_string (GIMP_CONFIG (curve),
+ (const gchar *)
+ gtk_selection_data_get_data (selection),
+ length,
+ NULL,
+ &error))
+ {
+ g_warning ("Received invalid curve data: %s", error->message);
+ g_clear_error (&error);
+ g_object_unref (curve);
+ return NULL;
+ }
+
+ return curve;
+}
+
+void
gimp_selection_data_set_image (GtkSelectionData *selection,
GimpImage *image)
{
diff --git a/app/widgets/gimpselectiondata.h b/app/widgets/gimpselectiondata.h
index 7cff6ea..bf52b97 100644
--- a/app/widgets/gimpselectiondata.h
+++ b/app/widgets/gimpselectiondata.h
@@ -43,6 +43,13 @@ const guchar * gimp_selection_data_get_stream (GtkSelectionData *selection,
gsize *stream_length);
+/* curve */
+
+void gimp_selection_data_set_curve (GtkSelectionData *selection,
+ GimpCurve *curve);
+GimpCurve * gimp_selection_data_get_curve (GtkSelectionData *selection);
+
+
/* image */
void gimp_selection_data_set_image (GtkSelectionData *selection,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]