2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1999-08-21 03:59:06 +08:00
|
|
|
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
1999-08-21 03:59:06 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
1999-08-21 03:59:06 +08:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1999-08-21 03:59:06 +08:00
|
|
|
*/
|
2000-12-29 23:22:01 +08:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2008-10-10 04:24:04 +08:00
|
|
|
#include <gegl.h>
|
2000-12-29 23:22:01 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
2001-01-25 06:36:18 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
2001-01-24 02:49:44 +08:00
|
|
|
|
2001-05-10 06:34:59 +08:00
|
|
|
#include "widgets-types.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
|
2016-05-30 03:32:05 +08:00
|
|
|
#include "config/gimpcoreconfig.h"
|
|
|
|
|
2001-07-05 03:31:35 +08:00
|
|
|
#include "core/gimp.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpbrush.h"
|
2001-06-26 20:09:43 +08:00
|
|
|
#include "core/gimpbuffer.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpchannel.h"
|
|
|
|
#include "core/gimpcontainer.h"
|
|
|
|
#include "core/gimpdatafactory.h"
|
|
|
|
#include "core/gimpdrawable.h"
|
|
|
|
#include "core/gimpgradient.h"
|
2001-06-26 20:09:43 +08:00
|
|
|
#include "core/gimpimage.h"
|
2001-08-11 15:47:35 +08:00
|
|
|
#include "core/gimpimagefile.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimplayer.h"
|
|
|
|
#include "core/gimplayermask.h"
|
|
|
|
#include "core/gimppalette.h"
|
|
|
|
#include "core/gimppattern.h"
|
2003-04-06 03:56:38 +08:00
|
|
|
#include "core/gimptemplate.h"
|
2001-05-10 06:34:59 +08:00
|
|
|
#include "core/gimptoolinfo.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2003-03-26 09:27:23 +08:00
|
|
|
#include "text/gimpfont.h"
|
|
|
|
|
2002-02-26 01:58:50 +08:00
|
|
|
#include "vectors/gimpvectors.h"
|
|
|
|
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "gimpdnd.h"
|
2005-03-25 22:23:35 +08:00
|
|
|
#include "gimpdnd-xds.h"
|
2005-04-10 01:56:04 +08:00
|
|
|
#include "gimppixbuf.h"
|
2004-06-29 04:39:54 +08:00
|
|
|
#include "gimpselectiondata.h"
|
2005-04-10 01:56:04 +08:00
|
|
|
#include "gimpview.h"
|
2005-01-15 22:55:15 +08:00
|
|
|
#include "gimpviewrendererimage.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
#include "gimp-log.h"
|
2003-03-26 00:38:19 +08:00
|
|
|
#include "gimp-intl.h"
|
2003-03-05 19:25:59 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2005-06-04 20:54:24 +08:00
|
|
|
#define DRAG_PREVIEW_SIZE GIMP_VIEW_SIZE_LARGE
|
|
|
|
#define DRAG_ICON_OFFSET -8
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-03-10 22:00:52 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
typedef GtkWidget * (* GimpDndGetIconFunc) (GtkWidget *widget,
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_data_func,
|
|
|
|
gpointer get_data_data);
|
|
|
|
typedef void (* GimpDndDragDataFunc) (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_data_func,
|
|
|
|
gpointer get_data_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-29 04:39:54 +08:00
|
|
|
typedef gboolean (* GimpDndDropDataFunc) (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_data_func,
|
|
|
|
gpointer set_data_data,
|
|
|
|
GtkSelectionData *selection);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
typedef struct _GimpDndDataDef GimpDndDataDef;
|
|
|
|
|
|
|
|
struct _GimpDndDataDef
|
|
|
|
{
|
|
|
|
GtkTargetEntry target_entry;
|
|
|
|
|
2005-03-26 01:16:07 +08:00
|
|
|
const gchar *get_data_func_name;
|
|
|
|
const gchar *get_data_data_name;
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2005-03-26 01:16:07 +08:00
|
|
|
const gchar *set_data_func_name;
|
|
|
|
const gchar *set_data_data_name;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
GimpDndGetIconFunc get_icon_func;
|
|
|
|
GimpDndDragDataFunc get_data_func;
|
|
|
|
GimpDndDropDataFunc set_data_func;
|
|
|
|
};
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static GtkWidget * gimp_dnd_get_viewable_icon (GtkWidget *widget,
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_viewable_func,
|
|
|
|
gpointer get_viewable_data);
|
2005-01-15 22:55:15 +08:00
|
|
|
static GtkWidget * gimp_dnd_get_component_icon (GtkWidget *widget,
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GdkDragContext *context,
|
2005-01-15 22:55:15 +08:00
|
|
|
GCallback get_comp_func,
|
|
|
|
gpointer get_comp_data);
|
2004-06-29 04:39:54 +08:00
|
|
|
static GtkWidget * gimp_dnd_get_color_icon (GtkWidget *widget,
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_color_func,
|
|
|
|
gpointer get_color_data);
|
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
static void gimp_dnd_get_uri_list_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-30 22:47:23 +08:00
|
|
|
GCallback get_uri_list_func,
|
|
|
|
gpointer get_uri_list_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-30 22:47:23 +08:00
|
|
|
static gboolean gimp_dnd_set_uri_list_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-30 22:47:23 +08:00
|
|
|
GCallback set_uri_list_func,
|
|
|
|
gpointer set_uri_list_data,
|
2004-06-29 04:39:54 +08:00
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
static void gimp_dnd_get_xds_data (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_image_func,
|
|
|
|
gpointer get_image_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2005-03-25 22:23:35 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void gimp_dnd_get_color_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_color_func,
|
|
|
|
gpointer get_color_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-29 04:39:54 +08:00
|
|
|
static gboolean gimp_dnd_set_color_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_color_func,
|
|
|
|
gpointer set_color_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
static void gimp_dnd_get_stream_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-30 19:57:17 +08:00
|
|
|
GCallback get_stream_func,
|
|
|
|
gpointer get_stream_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-30 19:57:17 +08:00
|
|
|
static gboolean gimp_dnd_set_stream_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-30 19:57:17 +08:00
|
|
|
GCallback set_stream_func,
|
|
|
|
gpointer set_stream_data,
|
2004-06-29 04:39:54 +08:00
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
static void gimp_dnd_get_pixbuf_data (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_pixbuf_func,
|
|
|
|
gpointer get_pixbuf_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_pixbuf_data (GtkWidget *widget,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GCallback set_pixbuf_func,
|
|
|
|
gpointer set_pixbuf_data,
|
|
|
|
GtkSelectionData *selection);
|
2005-01-15 10:24:38 +08:00
|
|
|
static void gimp_dnd_get_component_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2005-01-15 10:24:38 +08:00
|
|
|
GCallback get_comp_func,
|
|
|
|
gpointer get_comp_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2005-01-15 10:24:38 +08:00
|
|
|
static gboolean gimp_dnd_set_component_data (GtkWidget *widget,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GCallback set_comp_func,
|
|
|
|
gpointer set_comp_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void gimp_dnd_get_image_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_image_func,
|
|
|
|
gpointer get_image_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-29 04:39:54 +08:00
|
|
|
static gboolean gimp_dnd_set_image_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_image_func,
|
|
|
|
gpointer set_image_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
|
|
|
static void gimp_dnd_get_item_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_item_func,
|
|
|
|
gpointer get_item_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-29 04:39:54 +08:00
|
|
|
static gboolean gimp_dnd_set_item_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_item_func,
|
|
|
|
gpointer set_item_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
static void gimp_dnd_get_object_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2005-07-25 21:53:00 +08:00
|
|
|
GCallback get_object_func,
|
|
|
|
gpointer get_object_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection);
|
2004-06-29 04:39:54 +08:00
|
|
|
|
|
|
|
static gboolean gimp_dnd_set_brush_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_brush_func,
|
|
|
|
gpointer set_brush_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_pattern_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_pattern_func,
|
|
|
|
gpointer set_pattern_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_gradient_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_gradient_func,
|
|
|
|
gpointer set_gradient_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_palette_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_palette_func,
|
|
|
|
gpointer set_palette_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_font_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_font_func,
|
|
|
|
gpointer set_font_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_buffer_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_buffer_func,
|
|
|
|
gpointer set_buffer_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_imagefile_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_imagefile_func,
|
|
|
|
gpointer set_imagefile_data,
|
|
|
|
GtkSelectionData *selection);
|
|
|
|
static gboolean gimp_dnd_set_template_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_template_func,
|
|
|
|
gpointer set_template_data,
|
|
|
|
GtkSelectionData *selection);
|
2005-07-25 21:53:00 +08:00
|
|
|
static gboolean gimp_dnd_set_tool_info_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2005-07-25 21:53:00 +08:00
|
|
|
GCallback set_tool_info_func,
|
|
|
|
gpointer set_tool_info_data,
|
2004-06-29 04:39:54 +08:00
|
|
|
GtkSelectionData *selection);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
|
2005-03-26 01:16:07 +08:00
|
|
|
static const GimpDndDataDef dnd_data_defs[] =
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
|
|
|
{
|
|
|
|
{ NULL, 0, -1 },
|
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2000-04-01 02:10:25 +08:00
|
|
|
NULL
|
1999-10-28 23:05:49 +08:00
|
|
|
},
|
|
|
|
|
2001-05-01 22:58:13 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_URI_LIST,
|
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
"gimp-dnd-get-uri-list-func",
|
|
|
|
"gimp-dnd-get-uri-list-data",
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
"gimp-dnd-set-uri-list-func",
|
|
|
|
"gimp-dnd-set-uri-list-data",
|
2001-05-01 22:58:13 +08:00
|
|
|
|
|
|
|
NULL,
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_get_uri_list_data,
|
|
|
|
gimp_dnd_set_uri_list_data
|
2001-05-01 22:58:13 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_TEXT_PLAIN,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
"gimp-dnd-set-uri-list-func",
|
|
|
|
"gimp-dnd-set-uri-list-data",
|
2001-05-01 22:58:13 +08:00
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_set_uri_list_data
|
2001-05-01 22:58:13 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_NETSCAPE_URL,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
"gimp-dnd-set-uri-list-func",
|
|
|
|
"gimp-dnd-set-uri-list-data",
|
2001-05-01 22:58:13 +08:00
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_set_uri_list_data
|
2001-05-01 22:58:13 +08:00
|
|
|
},
|
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_XDS,
|
|
|
|
|
|
|
|
"gimp-dnd-get-xds-func",
|
|
|
|
"gimp-dnd-get-xds-data",
|
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
|
|
|
gimp_dnd_get_xds_data,
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_COLOR,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-color-func",
|
|
|
|
"gimp-dnd-get-color-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-color-func",
|
|
|
|
"gimp-dnd-set-color-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_color_icon,
|
|
|
|
gimp_dnd_get_color_data,
|
|
|
|
gimp_dnd_set_color_data
|
|
|
|
},
|
|
|
|
|
2003-12-21 03:51:21 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_SVG,
|
|
|
|
|
|
|
|
"gimp-dnd-get-svg-func",
|
|
|
|
"gimp-dnd-get-svg-data",
|
|
|
|
|
|
|
|
"gimp-dnd-set-svg-func",
|
|
|
|
"gimp-dnd-set-svg-data",
|
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_get_stream_data,
|
|
|
|
gimp_dnd_set_stream_data
|
2003-12-21 03:51:21 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_SVG_XML,
|
|
|
|
|
|
|
|
"gimp-dnd-get-svg-xml-func",
|
|
|
|
"gimp-dnd-get-svg-xml-data",
|
|
|
|
|
|
|
|
"gimp-dnd-set-svg-xml-func",
|
|
|
|
"gimp-dnd-set-svg-xml-data",
|
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_get_stream_data,
|
|
|
|
gimp_dnd_set_stream_data
|
2003-12-21 03:51:21 +08:00
|
|
|
},
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_PIXBUF,
|
|
|
|
|
|
|
|
"gimp-dnd-get-pixbuf-func",
|
|
|
|
"gimp-dnd-get-pixbuf-data",
|
|
|
|
|
|
|
|
"gimp-dnd-set-pixbuf-func",
|
|
|
|
"gimp-dnd-set-pixbuf-data",
|
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
|
|
|
gimp_dnd_get_pixbuf_data,
|
|
|
|
gimp_dnd_set_pixbuf_data
|
|
|
|
},
|
|
|
|
|
2001-04-13 20:10:22 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_IMAGE,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-image-func",
|
|
|
|
"gimp-dnd-get-image-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-image-func",
|
|
|
|
"gimp-dnd-set-image-data",
|
2001-04-13 20:10:22 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
|
|
|
gimp_dnd_get_image_data,
|
|
|
|
gimp_dnd_set_image_data,
|
|
|
|
},
|
|
|
|
|
2005-01-15 10:24:38 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_COMPONENT,
|
|
|
|
|
|
|
|
"gimp-dnd-get-component-func",
|
|
|
|
"gimp-dnd-get-component-data",
|
|
|
|
|
|
|
|
"gimp-dnd-set-component-func",
|
|
|
|
"gimp-dnd-set-component-data",
|
|
|
|
|
2005-01-15 22:55:15 +08:00
|
|
|
gimp_dnd_get_component_icon,
|
2005-01-15 10:24:38 +08:00
|
|
|
gimp_dnd_get_component_data,
|
|
|
|
gimp_dnd_set_component_data,
|
|
|
|
},
|
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_LAYER,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-layer-func",
|
|
|
|
"gimp-dnd-get-layer-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-layer-func",
|
|
|
|
"gimp-dnd-set-layer-data",
|
2001-02-20 06:54:12 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2002-02-26 01:58:50 +08:00
|
|
|
gimp_dnd_get_item_data,
|
|
|
|
gimp_dnd_set_item_data,
|
2001-02-20 06:54:12 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_CHANNEL,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-channel-func",
|
|
|
|
"gimp-dnd-get-channel-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-channel-func",
|
|
|
|
"gimp-dnd-set-channel-data",
|
2001-02-20 06:54:12 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2002-02-26 01:58:50 +08:00
|
|
|
gimp_dnd_get_item_data,
|
|
|
|
gimp_dnd_set_item_data,
|
2001-02-20 06:54:12 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_LAYER_MASK,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-layer-mask-func",
|
|
|
|
"gimp-dnd-get-layer-mask-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-layer-mask-func",
|
|
|
|
"gimp-dnd-set-layer-mask-data",
|
2001-02-20 06:54:12 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2002-02-26 01:58:50 +08:00
|
|
|
gimp_dnd_get_item_data,
|
|
|
|
gimp_dnd_set_item_data,
|
2001-02-20 06:54:12 +08:00
|
|
|
},
|
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
{
|
2002-02-26 01:58:50 +08:00
|
|
|
GIMP_TARGET_VECTORS,
|
2001-09-20 03:06:36 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-vectors-func",
|
|
|
|
"gimp-dnd-get-vectors-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-vectors-func",
|
|
|
|
"gimp-dnd-set-vectors-data",
|
2001-09-20 03:06:36 +08:00
|
|
|
|
2002-02-26 01:58:50 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
|
|
|
gimp_dnd_get_item_data,
|
|
|
|
gimp_dnd_set_item_data,
|
2001-09-20 03:06:36 +08:00
|
|
|
},
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_BRUSH,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-brush-func",
|
|
|
|
"gimp-dnd-get-brush-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-brush-func",
|
|
|
|
"gimp-dnd-set-brush-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_set_brush_data
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_PATTERN,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-pattern-func",
|
|
|
|
"gimp-dnd-get-pattern-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-pattern-func",
|
|
|
|
"gimp-dnd-set-pattern-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_set_pattern_data
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_GRADIENT,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-gradient-func",
|
|
|
|
"gimp-dnd-get-gradient-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-gradient-func",
|
|
|
|
"gimp-dnd-set-gradient-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_set_gradient_data
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_PALETTE,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-palette-func",
|
|
|
|
"gimp-dnd-get-palette-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-palette-func",
|
|
|
|
"gimp-dnd-set-palette-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_set_palette_data
|
|
|
|
},
|
|
|
|
|
2003-03-26 09:27:23 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_FONT,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-font-func",
|
|
|
|
"gimp-dnd-get-font-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-font-func",
|
|
|
|
"gimp-dnd-set-font-data",
|
2003-03-26 09:27:23 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
2003-03-26 09:27:23 +08:00
|
|
|
gimp_dnd_set_font_data
|
|
|
|
},
|
|
|
|
|
2001-06-26 20:09:43 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_BUFFER,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-buffer-func",
|
|
|
|
"gimp-dnd-get-buffer-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-buffer-func",
|
|
|
|
"gimp-dnd-set-buffer-data",
|
2001-06-26 20:09:43 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
2001-06-26 20:09:43 +08:00
|
|
|
gimp_dnd_set_buffer_data
|
|
|
|
},
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GIMP_TARGET_IMAGEFILE,
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-imagefile-func",
|
|
|
|
"gimp-dnd-get-imagefile-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-imagefile-func",
|
|
|
|
"gimp-dnd-set-imagefile-data",
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-08-11 15:47:35 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
2001-08-11 15:47:35 +08:00
|
|
|
gimp_dnd_set_imagefile_data
|
|
|
|
},
|
|
|
|
|
2003-04-06 03:56:38 +08:00
|
|
|
{
|
|
|
|
GIMP_TARGET_TEMPLATE,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
"gimp-dnd-get-template-func",
|
|
|
|
"gimp-dnd-get-template-data",
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
"gimp-dnd-set-template-func",
|
|
|
|
"gimp-dnd-set-template-data",
|
2003-04-06 03:56:38 +08:00
|
|
|
|
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
2003-04-06 03:56:38 +08:00
|
|
|
gimp_dnd_set_template_data
|
|
|
|
},
|
|
|
|
|
2001-08-11 15:47:35 +08:00
|
|
|
{
|
2005-07-25 21:53:00 +08:00
|
|
|
GIMP_TARGET_TOOL_INFO,
|
2001-08-11 15:47:35 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
"gimp-dnd-get-tool-info-func",
|
|
|
|
"gimp-dnd-get-tool-info-data",
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
"gimp-dnd-set-tool-info-func",
|
|
|
|
"gimp-dnd-set-tool-info-data",
|
2001-08-11 15:47:35 +08:00
|
|
|
|
2001-02-21 20:18:09 +08:00
|
|
|
gimp_dnd_get_viewable_icon,
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data,
|
|
|
|
gimp_dnd_set_tool_info_data
|
2001-09-20 03:06:36 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
GIMP_TARGET_DIALOG,
|
|
|
|
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
};
|
1999-08-21 03:59:06 +08:00
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2003-11-04 07:24:32 +08:00
|
|
|
static Gimp *the_dnd_gimp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_init (Gimp *gimp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
g_return_if_fail (the_dnd_gimp == NULL);
|
|
|
|
|
|
|
|
the_dnd_gimp = gimp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-27 00:39:51 +08:00
|
|
|
/**********************/
|
|
|
|
/* helper functions */
|
|
|
|
/**********************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dnd_target_list_add (GtkTargetList *list,
|
|
|
|
const GtkTargetEntry *entry)
|
|
|
|
{
|
|
|
|
GdkAtom atom = gdk_atom_intern (entry->target, FALSE);
|
|
|
|
guint info;
|
|
|
|
|
|
|
|
if (! gtk_target_list_find (list, atom, &info) || info != entry->info)
|
|
|
|
{
|
|
|
|
gtk_target_list_add (list, atom, entry->flags, entry->info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
/********************************/
|
|
|
|
/* general data dnd functions */
|
|
|
|
/********************************/
|
1999-08-23 22:19:26 +08:00
|
|
|
|
|
|
|
static void
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_data_drag_begin (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GdkDragContext *context,
|
|
|
|
gpointer data)
|
1999-08-23 22:19:26 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
|
|
|
GimpDndType data_type;
|
|
|
|
GCallback get_data_func = NULL;
|
|
|
|
gpointer get_data_data = NULL;
|
|
|
|
GtkWidget *icon_widget;
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
data_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-get-data-type"));
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "data type %d", data_type);
|
2005-03-25 22:23:35 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
if (! data_type)
|
1999-08-23 22:19:26 +08:00
|
|
|
return;
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
|
|
|
if (dnd_data->get_data_func_name)
|
|
|
|
get_data_func = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_func_name);
|
|
|
|
|
|
|
|
if (dnd_data->get_data_data_name)
|
|
|
|
get_data_data = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_data_name);
|
1999-08-23 22:19:26 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
if (! get_data_func)
|
|
|
|
return;
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
icon_widget = dnd_data->get_icon_func (widget,
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
context,
|
2003-11-21 00:26:15 +08:00
|
|
|
get_data_func,
|
|
|
|
get_data_data);
|
1999-08-23 22:19:26 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
if (icon_widget)
|
|
|
|
{
|
2000-02-09 03:49:12 +08:00
|
|
|
GtkWidget *frame;
|
|
|
|
GtkWidget *window;
|
|
|
|
|
|
|
|
window = gtk_window_new (GTK_WINDOW_POPUP);
|
2007-10-16 21:56:34 +08:00
|
|
|
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
|
|
|
|
gtk_window_set_screen (GTK_WINDOW (window),
|
|
|
|
gtk_widget_get_screen (widget));
|
|
|
|
|
2000-02-09 03:49:12 +08:00
|
|
|
gtk_widget_realize (window);
|
|
|
|
|
|
|
|
frame = gtk_frame_new (NULL);
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
|
|
|
gtk_container_add (GTK_CONTAINER (window), frame);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
|
|
|
gtk_container_add (GTK_CONTAINER (frame), icon_widget);
|
|
|
|
gtk_widget_show (icon_widget);
|
|
|
|
|
2003-11-20 19:32:53 +08:00
|
|
|
g_object_set_data_full (G_OBJECT (widget), "gimp-dnd-data-widget",
|
|
|
|
window, (GDestroyNotify) gtk_widget_destroy);
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2000-02-09 03:49:12 +08:00
|
|
|
gtk_drag_set_icon_widget (context, window,
|
2004-06-29 04:39:54 +08:00
|
|
|
DRAG_ICON_OFFSET, DRAG_ICON_OFFSET);
|
2004-10-07 02:55:24 +08:00
|
|
|
|
|
|
|
/* remember for which drag context the widget was made */
|
|
|
|
g_object_set_data (G_OBJECT (window), "gimp-gdk-drag-context", context);
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
1999-08-23 22:19:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-10-28 23:05:49 +08:00
|
|
|
gimp_dnd_data_drag_end (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GdkDragContext *context)
|
1999-08-23 22:19:26 +08:00
|
|
|
{
|
2007-11-15 21:21:23 +08:00
|
|
|
GimpDndType data_type;
|
|
|
|
GtkWidget *icon_widget;
|
|
|
|
|
|
|
|
data_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-get-data-type"));
|
2004-10-07 02:55:24 +08:00
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "data type %d", data_type);
|
2005-03-25 22:23:35 +08:00
|
|
|
|
2004-10-07 02:55:24 +08:00
|
|
|
icon_widget = g_object_get_data (G_OBJECT (widget), "gimp-dnd-data-widget");
|
|
|
|
|
|
|
|
if (icon_widget)
|
|
|
|
{
|
|
|
|
/* destroy the icon_widget only if it was made for this drag
|
|
|
|
* context. See bug #139337.
|
|
|
|
*/
|
|
|
|
if (g_object_get_data (G_OBJECT (icon_widget),
|
|
|
|
"gimp-gdk-drag-context") ==
|
|
|
|
(gpointer) context)
|
|
|
|
{
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-data-widget", NULL);
|
|
|
|
}
|
|
|
|
}
|
1999-08-23 22:19:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-10-06 18:35:40 +08:00
|
|
|
gimp_dnd_data_drag_handle (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GdkDragContext *context,
|
|
|
|
GtkSelectionData *selection_data,
|
|
|
|
guint info,
|
|
|
|
guint time,
|
|
|
|
gpointer data)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2003-11-21 00:26:15 +08:00
|
|
|
GCallback get_data_func = NULL;
|
|
|
|
gpointer get_data_data = NULL;
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType data_type;
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "data type %d", info);
|
2003-12-22 05:57:46 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
for (data_type = GIMP_DND_TYPE_NONE + 1;
|
|
|
|
data_type <= GIMP_DND_TYPE_LAST;
|
|
|
|
data_type++)
|
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data = dnd_data_defs + data_type;
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
if (dnd_data->target_entry.info == info)
|
2004-06-29 04:39:54 +08:00
|
|
|
{
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "target %s", dnd_data->target_entry.target);
|
2003-11-20 19:32:53 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
if (dnd_data->get_data_func_name)
|
|
|
|
get_data_func = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_func_name);
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
if (dnd_data->get_data_data_name)
|
|
|
|
get_data_data = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_data_name);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
if (! get_data_func)
|
|
|
|
return;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
dnd_data->get_data_func (widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
context,
|
2004-06-29 04:39:54 +08:00
|
|
|
get_data_func,
|
|
|
|
get_data_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
selection_data);
|
2003-11-21 00:26:15 +08:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-10-06 18:35:40 +08:00
|
|
|
gimp_dnd_data_drop_handle (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GdkDragContext *context,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GtkSelectionData *selection_data,
|
|
|
|
guint info,
|
|
|
|
guint time,
|
|
|
|
gpointer data)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2003-12-21 18:53:56 +08:00
|
|
|
GimpDndType data_type;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "data type %d", info);
|
2003-12-22 05:57:46 +08:00
|
|
|
|
2009-03-23 07:16:59 +08:00
|
|
|
if (gtk_selection_data_get_length (selection_data) <= 0)
|
2003-12-21 18:53:56 +08:00
|
|
|
{
|
|
|
|
gtk_drag_finish (context, FALSE, FALSE, time);
|
|
|
|
return;
|
|
|
|
}
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
for (data_type = GIMP_DND_TYPE_NONE + 1;
|
|
|
|
data_type <= GIMP_DND_TYPE_LAST;
|
1999-10-28 23:05:49 +08:00
|
|
|
data_type++)
|
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data = dnd_data_defs + data_type;
|
2003-10-06 18:35:40 +08:00
|
|
|
|
|
|
|
if (dnd_data->target_entry.info == info)
|
2004-06-29 04:39:54 +08:00
|
|
|
{
|
2003-12-21 18:53:56 +08:00
|
|
|
GCallback set_data_func = NULL;
|
|
|
|
gpointer set_data_data = NULL;
|
|
|
|
|
2007-11-15 21:21:23 +08:00
|
|
|
GIMP_LOG (DND, "target %s", dnd_data->target_entry.target);
|
2003-10-06 18:35:40 +08:00
|
|
|
|
|
|
|
if (dnd_data->set_data_func_name)
|
|
|
|
set_data_func = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->set_data_func_name);
|
2002-11-30 06:40:10 +08:00
|
|
|
|
2003-10-06 18:35:40 +08:00
|
|
|
if (dnd_data->set_data_data_name)
|
|
|
|
set_data_data = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->set_data_data_name);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
if (set_data_func &&
|
2004-12-31 22:36:30 +08:00
|
|
|
dnd_data->set_data_func (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
set_data_func,
|
|
|
|
set_data_data,
|
2004-06-29 04:39:54 +08:00
|
|
|
selection_data))
|
2003-12-21 18:53:56 +08:00
|
|
|
{
|
|
|
|
gtk_drag_finish (context, TRUE, FALSE, time);
|
|
|
|
return;
|
|
|
|
}
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
gtk_drag_finish (context, FALSE, FALSE, time);
|
2004-06-29 04:39:54 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_data_source_add (GimpDndType data_type,
|
|
|
|
GtkWidget *widget,
|
|
|
|
GCallback get_data_func,
|
|
|
|
gpointer get_data_data)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
|
|
|
gboolean drag_connected;
|
2003-11-21 00:26:15 +08:00
|
|
|
|
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
|
|
|
/* set a default drag source if not already done */
|
|
|
|
if (! g_object_get_data (G_OBJECT (widget), "gtk-site-data"))
|
|
|
|
gtk_drag_source_set (widget, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
|
2005-04-10 01:56:04 +08:00
|
|
|
NULL, 0,
|
2003-11-21 00:26:15 +08:00
|
|
|
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
drag_connected =
|
2001-09-20 03:06:36 +08:00
|
|
|
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-drag-connected"));
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
if (! drag_connected)
|
|
|
|
{
|
2005-08-03 17:34:55 +08:00
|
|
|
g_signal_connect (widget, "drag-begin",
|
2001-07-25 07:11:30 +08:00
|
|
|
G_CALLBACK (gimp_dnd_data_drag_begin),
|
|
|
|
NULL);
|
2005-08-03 17:34:55 +08:00
|
|
|
g_signal_connect (widget, "drag-end",
|
2001-07-25 07:11:30 +08:00
|
|
|
G_CALLBACK (gimp_dnd_data_drag_end),
|
|
|
|
NULL);
|
2005-08-03 17:34:55 +08:00
|
|
|
g_signal_connect (widget, "drag-data-get",
|
2001-07-25 07:11:30 +08:00
|
|
|
G_CALLBACK (gimp_dnd_data_drag_handle),
|
|
|
|
NULL);
|
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-drag-connected",
|
|
|
|
GINT_TO_POINTER (TRUE));
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->get_data_func_name,
|
2001-07-25 07:11:30 +08:00
|
|
|
get_data_func);
|
2003-11-21 00:26:15 +08:00
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->get_data_data_name,
|
2001-07-25 07:11:30 +08:00
|
|
|
get_data_data);
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2004-08-25 01:16:46 +08:00
|
|
|
/* remember the first set source type for drag view creation */
|
2003-11-21 00:26:15 +08:00
|
|
|
if (! g_object_get_data (G_OBJECT (widget), "gimp-dnd-get-data-type"))
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-get-data-type",
|
|
|
|
GINT_TO_POINTER (data_type));
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (dnd_data->target_entry.target)
|
2003-11-21 00:26:15 +08:00
|
|
|
{
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkTargetList *target_list;
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
target_list = gtk_drag_source_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
{
|
|
|
|
gimp_dnd_target_list_add (target_list, &dnd_data->target_entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
target_list = gtk_target_list_new (&dnd_data->target_entry, 1);
|
|
|
|
|
|
|
|
gtk_drag_source_set_target_list (widget, target_list);
|
|
|
|
gtk_target_list_unref (target_list);
|
|
|
|
}
|
2003-11-21 00:26:15 +08:00
|
|
|
}
|
1999-08-23 22:19:26 +08:00
|
|
|
}
|
|
|
|
|
2015-09-09 03:34:11 +08:00
|
|
|
static gboolean
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_data_source_remove (GimpDndType data_type,
|
|
|
|
GtkWidget *widget)
|
2001-03-05 06:07:19 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
|
|
|
gboolean drag_connected;
|
2015-09-09 03:34:11 +08:00
|
|
|
gboolean list_changed = FALSE;
|
2001-03-05 06:07:19 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
drag_connected =
|
|
|
|
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-drag-connected"));
|
2001-03-05 06:07:19 +08:00
|
|
|
|
|
|
|
if (! drag_connected)
|
2015-09-13 02:26:56 +08:00
|
|
|
return FALSE;
|
2001-03-05 06:07:19 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->get_data_func_name, NULL);
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->get_data_data_name, NULL);
|
|
|
|
|
|
|
|
/* remove the dnd type remembered for the dnd icon */
|
|
|
|
if (data_type ==
|
|
|
|
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-get-data-type")))
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-get-data-type", NULL);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (dnd_data->target_entry.target)
|
2003-11-21 00:26:15 +08:00
|
|
|
{
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
/* Don't just remove the target from the existing list, create a
|
|
|
|
* new list without the target and replace the old list. The
|
|
|
|
* source's target list is part of a drag operation's state, but
|
|
|
|
* only by reference, it's not copied. So when we change the
|
|
|
|
* list, we would change the state of that ongoing drag, making
|
|
|
|
* it impossible to drop anything. See bug #676522.
|
|
|
|
*/
|
|
|
|
GtkTargetList *target_list = gtk_drag_source_get_target_list (widget);
|
2003-11-21 00:26:15 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (target_list)
|
|
|
|
{
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GtkTargetList *new_list;
|
|
|
|
GtkTargetEntry *targets;
|
2015-09-28 21:28:57 +08:00
|
|
|
gint n_targets_old;
|
|
|
|
gint n_targets_new;
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
gint i;
|
2005-04-10 01:56:04 +08:00
|
|
|
|
2015-09-28 21:28:57 +08:00
|
|
|
targets = gtk_target_table_new_from_list (target_list, &n_targets_old);
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
|
|
|
|
new_list = gtk_target_list_new (NULL, 0);
|
|
|
|
|
2015-09-28 21:28:57 +08:00
|
|
|
for (i = 0; i < n_targets_old; i++)
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
{
|
|
|
|
if (targets[i].info != data_type)
|
|
|
|
{
|
|
|
|
gtk_target_list_add (new_list,
|
|
|
|
gdk_atom_intern (targets[i].target, FALSE),
|
|
|
|
targets[i].flags,
|
|
|
|
targets[i].info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 21:28:57 +08:00
|
|
|
gtk_target_table_free (targets, n_targets_old);
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
|
2015-09-28 21:28:57 +08:00
|
|
|
targets = gtk_target_table_new_from_list (new_list, &n_targets_new);
|
|
|
|
gtk_target_table_free (targets, n_targets_new);
|
|
|
|
|
|
|
|
if (n_targets_old != n_targets_new)
|
2015-09-09 03:34:11 +08:00
|
|
|
{
|
|
|
|
list_changed = TRUE;
|
|
|
|
|
2015-09-28 21:28:57 +08:00
|
|
|
if (n_targets_new > 0)
|
2015-09-09 03:34:11 +08:00
|
|
|
gtk_drag_source_set_target_list (widget, new_list);
|
|
|
|
else
|
|
|
|
gtk_drag_source_set_target_list (widget, NULL);
|
|
|
|
}
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
gtk_target_list_unref (new_list);
|
2005-04-10 01:56:04 +08:00
|
|
|
}
|
2003-11-21 00:26:15 +08:00
|
|
|
}
|
2015-09-09 03:34:11 +08:00
|
|
|
|
|
|
|
return list_changed;
|
2001-03-05 06:07:19 +08:00
|
|
|
}
|
|
|
|
|
1999-08-23 22:19:26 +08:00
|
|
|
static void
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_add (GimpDndType data_type,
|
2004-06-29 04:39:54 +08:00
|
|
|
GtkWidget *widget,
|
|
|
|
gpointer set_data_func,
|
|
|
|
gpointer set_data_data)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
|
|
|
gboolean drop_connected;
|
2002-09-02 22:39:08 +08:00
|
|
|
|
|
|
|
/* set a default drag dest if not already done */
|
|
|
|
if (! g_object_get_data (G_OBJECT (widget), "gtk-drag-dest"))
|
|
|
|
gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
drop_connected =
|
2001-09-20 03:06:36 +08:00
|
|
|
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-drop-connected"));
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
if (set_data_func && ! drop_connected)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2005-08-03 17:34:55 +08:00
|
|
|
g_signal_connect (widget, "drag-data-received",
|
2001-07-25 07:11:30 +08:00
|
|
|
G_CALLBACK (gimp_dnd_data_drop_handle),
|
|
|
|
NULL);
|
1999-10-31 00:16:08 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-drop-connected",
|
|
|
|
GINT_TO_POINTER (TRUE));
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
if (set_data_func)
|
|
|
|
{
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->set_data_func_name,
|
|
|
|
set_data_func);
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->set_data_data_name,
|
|
|
|
set_data_data);
|
|
|
|
}
|
2002-09-02 22:39:08 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (dnd_data->target_entry.target)
|
2003-02-19 00:29:28 +08:00
|
|
|
{
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
target_list = gtk_drag_dest_get_target_list (widget);
|
2003-10-06 18:35:40 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (target_list)
|
|
|
|
{
|
|
|
|
gimp_dnd_target_list_add (target_list, &dnd_data->target_entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
target_list = gtk_target_list_new (&dnd_data->target_entry, 1);
|
|
|
|
|
|
|
|
gtk_drag_dest_set_target_list (widget, target_list);
|
|
|
|
gtk_target_list_unref (target_list);
|
|
|
|
}
|
2003-02-19 00:29:28 +08:00
|
|
|
}
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2001-02-10 05:49:47 +08:00
|
|
|
static void
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_remove (GimpDndType data_type,
|
|
|
|
GtkWidget *widget)
|
2001-02-10 05:49:47 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
2001-02-10 05:49:47 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->set_data_func_name, NULL);
|
|
|
|
g_object_set_data (G_OBJECT (widget), dnd_data->set_data_data_name, NULL);
|
2002-09-02 22:39:08 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (dnd_data->target_entry.target)
|
2002-09-02 22:39:08 +08:00
|
|
|
{
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
target_list = gtk_drag_dest_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
{
|
|
|
|
GdkAtom atom = gdk_atom_intern (dnd_data->target_entry.target, TRUE);
|
2002-09-02 22:39:08 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (atom != GDK_NONE)
|
|
|
|
gtk_target_list_remove (target_list, atom);
|
|
|
|
}
|
2002-09-02 22:39:08 +08:00
|
|
|
}
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
/****************************/
|
|
|
|
/* uri list dnd functions */
|
|
|
|
/****************************/
|
2001-05-01 22:58:13 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_get_uri_list_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-30 22:47:23 +08:00
|
|
|
GCallback get_uri_list_func,
|
|
|
|
gpointer get_uri_list_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
2002-04-14 22:38:55 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GList *uri_list;
|
2002-04-14 22:38:55 +08:00
|
|
|
|
2004-06-30 22:47:23 +08:00
|
|
|
uri_list = (* (GimpDndDragUriListFunc) get_uri_list_func) (widget,
|
|
|
|
get_uri_list_data);
|
2002-04-14 22:38:55 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "uri_list %p", uri_list);
|
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
if (uri_list)
|
2002-04-14 22:38:55 +08:00
|
|
|
{
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_selection_data_set_uri_list (selection, uri_list);
|
2004-06-30 22:47:23 +08:00
|
|
|
|
2011-03-08 00:10:18 +08:00
|
|
|
g_list_free_full (uri_list, (GDestroyNotify) g_free);
|
2002-04-14 22:38:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
static gboolean
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_set_uri_list_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-30 22:47:23 +08:00
|
|
|
GCallback set_uri_list_func,
|
|
|
|
gpointer set_uri_list_data,
|
|
|
|
GtkSelectionData *selection)
|
2001-05-01 22:58:13 +08:00
|
|
|
{
|
2004-06-30 22:47:23 +08:00
|
|
|
GList *uri_list = gimp_selection_data_get_uri_list (selection);
|
2003-03-05 19:25:59 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "uri_list %p", uri_list);
|
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
if (! uri_list)
|
|
|
|
return FALSE;
|
2003-03-05 19:25:59 +08:00
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropUriListFunc) set_uri_list_func) (widget, x, y, uri_list,
|
2004-06-30 22:47:23 +08:00
|
|
|
set_uri_list_data);
|
2003-03-05 19:25:59 +08:00
|
|
|
|
2011-03-08 00:10:18 +08:00
|
|
|
g_list_free_full (uri_list, (GDestroyNotify) g_free);
|
2002-04-19 22:09:53 +08:00
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_uri_list_source_add (GtkWidget *widget,
|
|
|
|
GimpDndDragUriListFunc get_uri_list_func,
|
|
|
|
gpointer data)
|
2004-06-03 00:56:00 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_URI_LIST, widget,
|
2004-06-30 22:47:23 +08:00
|
|
|
G_CALLBACK (get_uri_list_func),
|
2004-06-29 04:39:54 +08:00
|
|
|
data);
|
2004-06-03 00:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_uri_list_source_remove (GtkWidget *widget)
|
2004-06-03 00:56:00 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_URI_LIST, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_uri_list_dest_add (GtkWidget *widget,
|
|
|
|
GimpDndDropUriListFunc set_uri_list_func,
|
|
|
|
gpointer data)
|
2004-06-03 00:56:00 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2018-03-25 04:49:01 +08:00
|
|
|
/* Set a default drag dest if not already done. Explicitly set
|
2004-06-03 00:56:00 +08:00
|
|
|
* COPY and MOVE for file drag destinations. Some file managers
|
|
|
|
* such as Konqueror only offer MOVE by default.
|
|
|
|
*/
|
|
|
|
if (! g_object_get_data (G_OBJECT (widget), "gtk-drag-dest"))
|
|
|
|
gtk_drag_dest_set (widget,
|
|
|
|
GTK_DEST_DEFAULT_ALL, NULL, 0,
|
|
|
|
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
|
|
|
|
2004-09-16 22:28:10 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_URI_LIST, widget,
|
2004-06-30 22:47:23 +08:00
|
|
|
G_CALLBACK (set_uri_list_func),
|
2004-06-29 04:39:54 +08:00
|
|
|
data);
|
2004-06-03 00:56:00 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_TEXT_PLAIN, widget,
|
2004-06-30 22:47:23 +08:00
|
|
|
G_CALLBACK (set_uri_list_func),
|
2004-06-29 04:39:54 +08:00
|
|
|
data);
|
2004-09-16 22:28:10 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_NETSCAPE_URL, widget,
|
2004-06-30 22:47:23 +08:00
|
|
|
G_CALLBACK (set_uri_list_func),
|
2004-06-29 04:39:54 +08:00
|
|
|
data);
|
2004-06-03 00:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 22:47:23 +08:00
|
|
|
gimp_dnd_uri_list_dest_remove (GtkWidget *widget)
|
2004-06-03 00:56:00 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
2002-04-14 22:38:55 +08:00
|
|
|
|
2004-06-03 00:56:00 +08:00
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_URI_LIST, widget);
|
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_TEXT_PLAIN, widget);
|
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_NETSCAPE_URL, widget);
|
|
|
|
}
|
|
|
|
|
2001-05-01 22:58:13 +08:00
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
/******************************/
|
|
|
|
/* Direct Save Protocol (XDS) */
|
|
|
|
/******************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dnd_get_xds_data (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_image_func,
|
|
|
|
gpointer get_image_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
2005-03-25 22:23:35 +08:00
|
|
|
{
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpImage *image;
|
|
|
|
GimpContext *gimp_context;
|
2005-03-25 22:23:35 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
image = g_object_get_data (G_OBJECT (context), "gimp-dnd-viewable");
|
|
|
|
|
|
|
|
if (! image)
|
|
|
|
image = (GimpImage *)
|
|
|
|
(* (GimpDndDragViewableFunc) get_image_func) (widget, &gimp_context,
|
|
|
|
get_image_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "image %p", image);
|
2005-03-25 22:23:35 +08:00
|
|
|
|
|
|
|
if (image)
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_dnd_xds_save_image (context, image, selection);
|
2005-03-25 22:23:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dnd_xds_drag_begin (GtkWidget *widget,
|
2005-03-26 01:16:07 +08:00
|
|
|
GdkDragContext *context)
|
2005-03-25 22:23:35 +08:00
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data = dnd_data_defs + GIMP_DND_TYPE_XDS;
|
|
|
|
GCallback get_data_func;
|
|
|
|
gpointer get_data_data;
|
2005-03-25 22:23:35 +08:00
|
|
|
|
|
|
|
get_data_func = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_func_name);
|
|
|
|
get_data_data = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_data_name);
|
|
|
|
|
|
|
|
if (get_data_func)
|
|
|
|
{
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpImage *image;
|
|
|
|
GimpContext *gimp_context;
|
|
|
|
|
|
|
|
image = (GimpImage *)
|
|
|
|
(* (GimpDndDragViewableFunc) get_data_func) (widget, &gimp_context,
|
|
|
|
get_data_data);
|
2005-03-25 22:23:35 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "image %p", image);
|
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
gimp_dnd_xds_source_set (context, image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-26 01:16:07 +08:00
|
|
|
static void
|
|
|
|
gimp_dnd_xds_drag_end (GtkWidget *widget,
|
|
|
|
GdkDragContext *context)
|
|
|
|
{
|
|
|
|
gimp_dnd_xds_source_set (context, NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
void
|
|
|
|
gimp_dnd_xds_source_add (GtkWidget *widget,
|
|
|
|
GimpDndDragViewableFunc get_image_func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
gulong handler;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_XDS, widget,
|
|
|
|
G_CALLBACK (get_image_func),
|
|
|
|
data);
|
|
|
|
|
|
|
|
handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-xds-drag-begin"));
|
|
|
|
|
|
|
|
if (! handler)
|
|
|
|
{
|
2005-08-03 17:34:55 +08:00
|
|
|
handler = g_signal_connect (widget, "drag-begin",
|
2005-03-25 22:23:35 +08:00
|
|
|
G_CALLBACK (gimp_dnd_xds_drag_begin),
|
|
|
|
NULL);
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-xds-drag-begin",
|
|
|
|
GUINT_TO_POINTER (handler));
|
|
|
|
}
|
2005-03-26 01:16:07 +08:00
|
|
|
|
|
|
|
handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-xds-drag-end"));
|
|
|
|
|
|
|
|
if (! handler)
|
|
|
|
{
|
2005-08-03 17:34:55 +08:00
|
|
|
handler = g_signal_connect (widget, "drag-end",
|
2005-03-26 01:16:07 +08:00
|
|
|
G_CALLBACK (gimp_dnd_xds_drag_end),
|
|
|
|
NULL);
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-xds-drag-end",
|
|
|
|
GUINT_TO_POINTER (handler));
|
|
|
|
}
|
2005-03-25 22:23:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_xds_source_remove (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
gulong handler;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-xds-drag-begin"));
|
|
|
|
if (handler)
|
|
|
|
{
|
|
|
|
g_signal_handler_disconnect (widget, handler);
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-xds-drag-begin", NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-26 01:16:07 +08:00
|
|
|
handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-xds-drag-end"));
|
|
|
|
if (handler)
|
|
|
|
{
|
|
|
|
g_signal_handler_disconnect (widget, handler);
|
|
|
|
g_object_set_data (G_OBJECT (widget), "gimp-dnd-xds-drag-end", NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-25 22:23:35 +08:00
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_XDS, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
/*************************/
|
|
|
|
/* color dnd functions */
|
|
|
|
/*************************/
|
|
|
|
|
|
|
|
static GtkWidget *
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
gimp_dnd_get_color_icon (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_color_func,
|
|
|
|
gpointer get_color_data)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2001-01-11 06:49:45 +08:00
|
|
|
GtkWidget *color_area;
|
|
|
|
GimpRGB color;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
(* (GimpDndDragColorFunc) get_color_func) (widget, &color, get_color_data);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "called");
|
|
|
|
|
|
|
|
g_object_set_data_full (G_OBJECT (context),
|
|
|
|
"gimp-dnd-color", g_memdup (&color, sizeof (GimpRGB)),
|
|
|
|
(GDestroyNotify) g_free);
|
|
|
|
|
2005-05-29 21:48:03 +08:00
|
|
|
color_area = gimp_color_area_new (&color, GIMP_COLOR_AREA_SMALL_CHECKS, 0);
|
2016-05-30 03:32:05 +08:00
|
|
|
gimp_color_area_set_color_config (GIMP_COLOR_AREA (color_area),
|
|
|
|
the_dnd_gimp->config->color_management);
|
2005-05-29 21:48:03 +08:00
|
|
|
gtk_widget_set_size_request (color_area,
|
|
|
|
DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
|
2000-02-09 03:49:12 +08:00
|
|
|
|
2001-01-11 06:49:45 +08:00
|
|
|
return color_area;
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
|
|
|
gimp_dnd_get_color_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_color_func,
|
|
|
|
gpointer get_color_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
1999-08-23 22:19:26 +08:00
|
|
|
{
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GimpRGB *c;
|
|
|
|
GimpRGB color;
|
2001-01-15 09:48:53 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
c = g_object_get_data (G_OBJECT (context), "gimp-dnd-color");
|
|
|
|
|
|
|
|
if (c)
|
|
|
|
color = *c;
|
|
|
|
else
|
|
|
|
(* (GimpDndDragColorFunc) get_color_func) (widget, &color, get_color_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "called");
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_selection_data_set_color (selection, &color);
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
1999-08-23 22:19:26 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_color_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_color_func,
|
|
|
|
gpointer set_color_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpRGB color;
|
1999-08-23 22:19:26 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "called");
|
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
if (! gimp_selection_data_get_color (selection, &color))
|
|
|
|
return FALSE;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropColorFunc) set_color_func) (widget, x, y, &color,
|
2004-06-29 04:39:54 +08:00
|
|
|
set_color_data);
|
2003-12-21 18:53:56 +08:00
|
|
|
|
|
|
|
return TRUE;
|
1999-08-23 22:19:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_color_source_add (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpDndDragColorFunc get_color_func,
|
|
|
|
gpointer data)
|
1999-08-23 22:19:26 +08:00
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_COLOR, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (get_color_func),
|
|
|
|
data);
|
1999-08-23 22:19:26 +08:00
|
|
|
}
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
void
|
|
|
|
gimp_dnd_color_source_remove (GtkWidget *widget)
|
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_COLOR, widget);
|
|
|
|
}
|
|
|
|
|
1999-08-23 22:19:26 +08:00
|
|
|
void
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_color_dest_add (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpDndDropColorFunc set_color_func,
|
|
|
|
gpointer data)
|
1999-08-23 22:19:26 +08:00
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_COLOR, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (set_color_func),
|
|
|
|
data);
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2001-02-10 05:49:47 +08:00
|
|
|
void
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_color_dest_remove (GtkWidget *widget)
|
2001-02-10 05:49:47 +08:00
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_COLOR, widget);
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
/**************************/
|
|
|
|
/* stream dnd functions */
|
|
|
|
/**************************/
|
2003-12-21 03:51:21 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_get_stream_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-30 19:57:17 +08:00
|
|
|
GCallback get_stream_func,
|
|
|
|
gpointer get_stream_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
2003-12-21 03:51:21 +08:00
|
|
|
{
|
2004-06-30 19:57:17 +08:00
|
|
|
guchar *stream;
|
|
|
|
gsize stream_length;
|
2003-12-21 03:51:21 +08:00
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
stream = (* (GimpDndDragStreamFunc) get_stream_func) (widget, &stream_length,
|
|
|
|
get_stream_data);
|
2003-12-21 03:51:21 +08:00
|
|
|
|
2014-05-03 01:56:09 +08:00
|
|
|
GIMP_LOG (DND, "stream %p, length %" G_GSIZE_FORMAT, stream, stream_length);
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
if (stream)
|
2004-06-29 04:39:54 +08:00
|
|
|
{
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_selection_data_set_stream (selection, stream, stream_length);
|
2004-06-30 19:57:17 +08:00
|
|
|
g_free (stream);
|
2004-06-29 04:39:54 +08:00
|
|
|
}
|
2003-12-21 03:51:21 +08:00
|
|
|
}
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_set_stream_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-30 19:57:17 +08:00
|
|
|
GCallback set_stream_func,
|
|
|
|
gpointer set_stream_data,
|
|
|
|
GtkSelectionData *selection)
|
2003-12-21 03:51:21 +08:00
|
|
|
{
|
2004-06-30 19:57:17 +08:00
|
|
|
const guchar *stream;
|
|
|
|
gsize stream_length;
|
2004-06-29 04:39:54 +08:00
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
stream = gimp_selection_data_get_stream (selection, &stream_length);
|
2004-06-29 04:39:54 +08:00
|
|
|
|
2014-05-03 01:56:09 +08:00
|
|
|
GIMP_LOG (DND, "stream %p, length %" G_GSIZE_FORMAT, stream, stream_length);
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
|
2004-06-30 19:57:17 +08:00
|
|
|
if (! stream)
|
2004-06-29 04:39:54 +08:00
|
|
|
return FALSE;
|
2003-12-21 03:51:21 +08:00
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropStreamFunc) set_stream_func) (widget, x, y,
|
2004-06-30 19:57:17 +08:00
|
|
|
stream, stream_length,
|
|
|
|
set_stream_data);
|
2003-12-21 18:53:56 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2003-12-21 03:51:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_svg_source_add (GtkWidget *widget,
|
|
|
|
GimpDndDragStreamFunc get_svg_func,
|
|
|
|
gpointer data)
|
2003-12-21 03:51:21 +08:00
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_SVG, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (get_svg_func),
|
|
|
|
data);
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_SVG_XML, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (get_svg_func),
|
|
|
|
data);
|
2003-12-21 03:51:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_svg_source_remove (GtkWidget *widget)
|
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_SVG, widget);
|
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_SVG_XML, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-06-30 19:57:17 +08:00
|
|
|
gimp_dnd_svg_dest_add (GtkWidget *widget,
|
|
|
|
GimpDndDropStreamFunc set_svg_func,
|
|
|
|
gpointer data)
|
2003-12-21 03:51:21 +08:00
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_SVG, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (set_svg_func),
|
|
|
|
data);
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_SVG_XML, widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
G_CALLBACK (set_svg_func),
|
|
|
|
data);
|
2003-12-21 03:51:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_svg_dest_remove (GtkWidget *widget)
|
|
|
|
{
|
2004-06-03 00:56:00 +08:00
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
2003-12-21 03:51:21 +08:00
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_SVG, widget);
|
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_SVG_XML, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
/**************************/
|
|
|
|
/* pixbuf dnd functions */
|
|
|
|
/**************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_dnd_get_pixbuf_data (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_pixbuf_func,
|
|
|
|
gpointer get_pixbuf_data,
|
|
|
|
GtkSelectionData *selection)
|
|
|
|
{
|
|
|
|
GdkPixbuf *pixbuf;
|
|
|
|
|
|
|
|
pixbuf = (* (GimpDndDragPixbufFunc) get_pixbuf_func) (widget,
|
|
|
|
get_pixbuf_data);
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "pixbuf %p", pixbuf);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (pixbuf)
|
|
|
|
{
|
2005-05-25 18:05:17 +08:00
|
|
|
gimp_set_busy (the_dnd_gimp);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
gtk_selection_data_set_pixbuf (selection, pixbuf);
|
|
|
|
g_object_unref (pixbuf);
|
2005-05-25 18:05:17 +08:00
|
|
|
|
|
|
|
gimp_unset_busy (the_dnd_gimp);
|
2005-04-10 01:56:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dnd_set_pixbuf_data (GtkWidget *widget,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GCallback set_pixbuf_func,
|
|
|
|
gpointer set_pixbuf_data,
|
|
|
|
GtkSelectionData *selection)
|
|
|
|
{
|
|
|
|
GdkPixbuf *pixbuf;
|
|
|
|
|
2005-05-25 18:05:17 +08:00
|
|
|
gimp_set_busy (the_dnd_gimp);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
pixbuf = gtk_selection_data_get_pixbuf (selection);
|
|
|
|
|
2005-05-25 18:05:17 +08:00
|
|
|
gimp_unset_busy (the_dnd_gimp);
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "pixbuf %p", pixbuf);
|
|
|
|
|
2005-04-10 01:56:04 +08:00
|
|
|
if (! pixbuf)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
(* (GimpDndDropPixbufFunc) set_pixbuf_func) (widget, x, y,
|
|
|
|
pixbuf,
|
|
|
|
set_pixbuf_data);
|
|
|
|
|
|
|
|
g_object_unref (pixbuf);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_pixbuf_source_add (GtkWidget *widget,
|
|
|
|
GimpDndDragPixbufFunc get_pixbuf_func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_PIXBUF, widget,
|
|
|
|
G_CALLBACK (get_pixbuf_func),
|
|
|
|
data);
|
|
|
|
|
|
|
|
target_list = gtk_drag_source_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
gtk_target_list_ref (target_list);
|
|
|
|
else
|
|
|
|
target_list = gtk_target_list_new (NULL, 0);
|
|
|
|
|
|
|
|
gimp_pixbuf_targets_add (target_list, GIMP_DND_TYPE_PIXBUF, TRUE);
|
|
|
|
|
|
|
|
gtk_drag_source_set_target_list (widget, target_list);
|
|
|
|
gtk_target_list_unref (target_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_pixbuf_source_remove (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_PIXBUF, widget);
|
|
|
|
|
|
|
|
target_list = gtk_drag_source_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
gimp_pixbuf_targets_remove (target_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_pixbuf_dest_add (GtkWidget *widget,
|
|
|
|
GimpDndDropPixbufFunc set_pixbuf_func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_PIXBUF, widget,
|
|
|
|
G_CALLBACK (set_pixbuf_func),
|
|
|
|
data);
|
|
|
|
|
|
|
|
target_list = gtk_drag_dest_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
gtk_target_list_ref (target_list);
|
|
|
|
else
|
|
|
|
target_list = gtk_target_list_new (NULL, 0);
|
|
|
|
|
|
|
|
gimp_pixbuf_targets_add (target_list, GIMP_DND_TYPE_PIXBUF, FALSE);
|
|
|
|
|
|
|
|
gtk_drag_dest_set_target_list (widget, target_list);
|
|
|
|
gtk_target_list_unref (target_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_pixbuf_dest_remove (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkTargetList *target_list;
|
|
|
|
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_PIXBUF, widget);
|
|
|
|
|
|
|
|
target_list = gtk_drag_dest_get_target_list (widget);
|
|
|
|
|
|
|
|
if (target_list)
|
|
|
|
gimp_pixbuf_targets_remove (target_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-15 10:24:38 +08:00
|
|
|
/*****************************/
|
|
|
|
/* component dnd functions */
|
|
|
|
/*****************************/
|
|
|
|
|
2005-01-15 22:55:15 +08:00
|
|
|
static GtkWidget *
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
gimp_dnd_get_component_icon (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_comp_func,
|
|
|
|
gpointer get_comp_data)
|
2005-01-15 22:55:15 +08:00
|
|
|
{
|
|
|
|
GtkWidget *view;
|
|
|
|
GimpImage *image;
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GimpContext *gimp_context;
|
2005-01-15 22:55:15 +08:00
|
|
|
GimpChannelType channel;
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
image = (* (GimpDndDragComponentFunc) get_comp_func) (widget, &gimp_context,
|
2006-08-30 05:44:51 +08:00
|
|
|
&channel,
|
2005-01-15 22:55:15 +08:00
|
|
|
get_comp_data);
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "image %p, component %d", image, channel);
|
|
|
|
|
2005-01-15 22:55:15 +08:00
|
|
|
if (! image)
|
|
|
|
return NULL;
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
g_object_set_data_full (G_OBJECT (context),
|
|
|
|
"gimp-dnd-viewable", g_object_ref (image),
|
|
|
|
(GDestroyNotify) g_object_unref);
|
|
|
|
g_object_set_data (G_OBJECT (context),
|
|
|
|
"gimp-dnd-component", GINT_TO_POINTER (channel));
|
|
|
|
|
|
|
|
view = gimp_view_new (gimp_context, GIMP_VIEWABLE (image),
|
2006-08-30 05:44:51 +08:00
|
|
|
DRAG_PREVIEW_SIZE, 0, TRUE);
|
2005-01-15 22:55:15 +08:00
|
|
|
|
|
|
|
GIMP_VIEW_RENDERER_IMAGE (GIMP_VIEW (view)->renderer)->channel = channel;
|
|
|
|
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
2005-01-15 10:24:38 +08:00
|
|
|
static void
|
|
|
|
gimp_dnd_get_component_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2005-01-15 10:24:38 +08:00
|
|
|
GCallback get_comp_func,
|
|
|
|
gpointer get_comp_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
2005-01-15 10:24:38 +08:00
|
|
|
{
|
|
|
|
GimpImage *image;
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpContext *gimp_context;
|
2005-01-15 10:24:38 +08:00
|
|
|
GimpChannelType channel = 0;
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
image = g_object_get_data (G_OBJECT (context), "gimp-dnd-viewable");
|
|
|
|
channel = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context),
|
|
|
|
"gimp-dnd-component"));
|
|
|
|
|
|
|
|
if (! image)
|
|
|
|
image = (* (GimpDndDragComponentFunc) get_comp_func) (widget, &gimp_context,
|
|
|
|
&channel,
|
|
|
|
get_comp_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "image %p, component %d", image, channel);
|
2005-01-15 10:24:38 +08:00
|
|
|
|
|
|
|
if (image)
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_selection_data_set_component (selection, image, channel);
|
2005-01-15 10:24:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gimp_dnd_set_component_data (GtkWidget *widget,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GCallback set_comp_func,
|
|
|
|
gpointer set_comp_data,
|
|
|
|
GtkSelectionData *selection)
|
|
|
|
{
|
|
|
|
GimpImage *image;
|
|
|
|
GimpChannelType channel = 0;
|
|
|
|
|
|
|
|
image = gimp_selection_data_get_component (selection, the_dnd_gimp,
|
|
|
|
&channel);
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "image %p, component %d", image, channel);
|
|
|
|
|
2005-01-15 10:24:38 +08:00
|
|
|
if (! image)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
(* (GimpDndDropComponentFunc) set_comp_func) (widget, x, y,
|
|
|
|
image, channel,
|
|
|
|
set_comp_data);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_component_source_add (GtkWidget *widget,
|
|
|
|
GimpDndDragComponentFunc get_comp_func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_add (GIMP_DND_TYPE_COMPONENT, widget,
|
|
|
|
G_CALLBACK (get_comp_func),
|
|
|
|
data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_component_source_remove (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_source_remove (GIMP_DND_TYPE_COMPONENT, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_component_dest_add (GtkWidget *widget,
|
|
|
|
GimpDndDropComponentFunc set_comp_func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_dest_add (GIMP_DND_TYPE_COMPONENT, widget,
|
|
|
|
G_CALLBACK (set_comp_func),
|
|
|
|
data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_dnd_component_dest_remove (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
|
|
|
|
gimp_dnd_data_dest_remove (GIMP_DND_TYPE_COMPONENT, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
/*******************************************/
|
|
|
|
/* GimpViewable (by GType) dnd functions */
|
|
|
|
/*******************************************/
|
2001-02-10 05:49:47 +08:00
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
static GtkWidget *
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
gimp_dnd_get_viewable_icon (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_viewable_func,
|
|
|
|
gpointer get_viewable_data)
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
|
|
|
GimpViewable *viewable;
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GimpContext *gimp_context;
|
2005-06-04 07:55:05 +08:00
|
|
|
GtkWidget *view;
|
2005-06-04 20:54:24 +08:00
|
|
|
gchar *desc;
|
2001-02-20 06:54:12 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
viewable = (* (GimpDndDragViewableFunc) get_viewable_func) (widget,
|
|
|
|
&gimp_context,
|
2004-06-29 04:39:54 +08:00
|
|
|
get_viewable_data);
|
2001-02-20 06:54:12 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "viewable %p", viewable);
|
|
|
|
|
2001-02-20 06:54:12 +08:00
|
|
|
if (! viewable)
|
|
|
|
return NULL;
|
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
g_object_set_data_full (G_OBJECT (context),
|
|
|
|
"gimp-dnd-viewable", g_object_ref (viewable),
|
|
|
|
(GDestroyNotify) g_object_unref);
|
|
|
|
|
|
|
|
view = gimp_view_new (gimp_context, viewable,
|
2006-08-30 05:44:51 +08:00
|
|
|
DRAG_PREVIEW_SIZE, 0, TRUE);
|
2001-02-20 06:54:12 +08:00
|
|
|
|
2005-06-04 20:54:24 +08:00
|
|
|
desc = gimp_viewable_get_description (viewable, NULL);
|
2005-06-04 07:55:05 +08:00
|
|
|
|
2005-06-04 20:54:24 +08:00
|
|
|
if (desc)
|
2005-06-04 07:55:05 +08:00
|
|
|
{
|
|
|
|
GtkWidget *hbox;
|
|
|
|
GtkWidget *label;
|
|
|
|
|
2011-09-30 17:29:11 +08:00
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
|
2005-06-04 07:55:05 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 3);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), view, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (view);
|
|
|
|
|
|
|
|
label = g_object_new (GTK_TYPE_LABEL,
|
2005-06-04 20:54:24 +08:00
|
|
|
"label", desc,
|
2005-06-04 07:55:05 +08:00
|
|
|
"xpad", 3,
|
|
|
|
"xalign", 0.0,
|
|
|
|
"yalign", 0.5,
|
2005-06-04 18:12:03 +08:00
|
|
|
"max-width-chars", 30,
|
2005-06-04 07:55:05 +08:00
|
|
|
"ellipsize", PANGO_ELLIPSIZE_END,
|
|
|
|
NULL);
|
|
|
|
|
2005-06-04 20:54:24 +08:00
|
|
|
g_free (desc);
|
|
|
|
|
2005-06-04 07:55:05 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
return hbox;
|
|
|
|
}
|
|
|
|
|
2004-08-25 01:16:46 +08:00
|
|
|
return view;
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
static GimpDndType
|
|
|
|
gimp_dnd_data_type_get_by_g_type (GType type)
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type = GIMP_DND_TYPE_NONE;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (g_type_is_a (type, GIMP_TYPE_IMAGE))
|
2001-04-13 20:10:22 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_IMAGE;
|
2001-04-13 20:10:22 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_LAYER))
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_LAYER;
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_LAYER_MASK))
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_LAYER_MASK;
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_CHANNEL))
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_CHANNEL;
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
2002-02-26 01:58:50 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_VECTORS))
|
|
|
|
{
|
|
|
|
dnd_type = GIMP_DND_TYPE_VECTORS;
|
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_BRUSH))
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_BRUSH;
|
2003-11-20 19:32:53 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_PATTERN))
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_PATTERN;
|
2001-02-19 03:44:28 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_GRADIENT))
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_GRADIENT;
|
2001-02-19 03:44:28 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_PALETTE))
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_PALETTE;
|
2001-02-19 03:44:28 +08:00
|
|
|
}
|
2003-03-26 09:27:23 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_FONT))
|
|
|
|
{
|
|
|
|
dnd_type = GIMP_DND_TYPE_FONT;
|
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_BUFFER))
|
2001-06-26 20:09:43 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_BUFFER;
|
2001-06-26 20:09:43 +08:00
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_IMAGEFILE))
|
2001-08-11 15:47:35 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_IMAGEFILE;
|
2001-08-11 15:47:35 +08:00
|
|
|
}
|
2003-04-06 03:56:38 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_TEMPLATE))
|
|
|
|
{
|
|
|
|
dnd_type = GIMP_DND_TYPE_TEMPLATE;
|
|
|
|
}
|
2001-09-20 03:06:36 +08:00
|
|
|
else if (g_type_is_a (type, GIMP_TYPE_TOOL_INFO))
|
2001-02-21 20:18:09 +08:00
|
|
|
{
|
2005-07-25 21:53:00 +08:00
|
|
|
dnd_type = GIMP_DND_TYPE_TOOL_INFO;
|
2001-02-21 20:18:09 +08:00
|
|
|
}
|
2001-02-10 05:49:47 +08:00
|
|
|
|
2001-03-06 21:28:39 +08:00
|
|
|
return dnd_type;
|
|
|
|
}
|
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_drag_source_set_by_type (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GdkModifierType start_button_mask,
|
|
|
|
GType type,
|
|
|
|
GdkDragAction actions)
|
2001-03-06 21:28:39 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-02-10 05:49:47 +08:00
|
|
|
|
2001-03-06 21:28:39 +08:00
|
|
|
gtk_drag_source_set (widget, start_button_mask,
|
2004-06-29 04:39:54 +08:00
|
|
|
&dnd_data_defs[dnd_type].target_entry, 1,
|
2003-11-21 00:26:15 +08:00
|
|
|
actions);
|
2003-02-20 20:47:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-19 03:44:28 +08:00
|
|
|
}
|
2001-02-11 03:35:29 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_drag_dest_set_by_type (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GtkDestDefaults flags,
|
|
|
|
GType type,
|
|
|
|
GdkDragAction actions)
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-02-12 00:14:25 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-02-10 05:49:47 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-03-06 21:28:39 +08:00
|
|
|
|
|
|
|
gtk_drag_dest_set (widget, flags,
|
2004-06-29 04:39:54 +08:00
|
|
|
&dnd_data_defs[dnd_type].target_entry, 1,
|
2003-11-21 00:26:15 +08:00
|
|
|
actions);
|
2003-02-20 20:47:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_viewable_source_add (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GType type,
|
|
|
|
GimpDndDragViewableFunc get_viewable_func,
|
|
|
|
gpointer data)
|
2001-02-19 03:44:28 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
|
|
|
g_return_val_if_fail (get_viewable_func != NULL, FALSE);
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_data_source_add (dnd_type, widget,
|
|
|
|
G_CALLBACK (get_viewable_func),
|
|
|
|
data);
|
2003-02-20 20:47:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-19 03:44:28 +08:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2003-11-21 00:26:15 +08:00
|
|
|
gimp_dnd_viewable_source_remove (GtkWidget *widget,
|
|
|
|
GType type)
|
2001-03-05 06:07:19 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-03-05 06:07:19 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
2001-03-05 06:07:19 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-03-05 06:07:19 +08:00
|
|
|
|
2015-09-09 03:34:11 +08:00
|
|
|
return gimp_dnd_data_source_remove (dnd_type, widget);
|
2001-03-05 06:07:19 +08:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_viewable_dest_add (GtkWidget *widget,
|
2004-06-29 04:39:54 +08:00
|
|
|
GType type,
|
|
|
|
GimpDndDropViewableFunc set_viewable_func,
|
|
|
|
gpointer data)
|
2001-02-10 05:49:47 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_add (dnd_type, widget,
|
2003-11-21 00:26:15 +08:00
|
|
|
G_CALLBACK (set_viewable_func),
|
|
|
|
data);
|
2003-02-20 20:47:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
gboolean
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_viewable_dest_remove (GtkWidget *widget,
|
|
|
|
GType type)
|
2001-02-10 05:49:47 +08:00
|
|
|
{
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType dnd_type;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2003-02-20 20:47:42 +08:00
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
dnd_type = gimp_dnd_data_type_get_by_g_type (type);
|
2001-03-06 21:28:39 +08:00
|
|
|
|
2001-09-20 03:06:36 +08:00
|
|
|
if (dnd_type == GIMP_DND_TYPE_NONE)
|
2003-02-20 20:47:42 +08:00
|
|
|
return FALSE;
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2002-09-02 22:39:08 +08:00
|
|
|
gimp_dnd_data_dest_remove (dnd_type, widget);
|
2003-02-20 20:47:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-03-04 07:23:36 +08:00
|
|
|
GimpViewable *
|
|
|
|
gimp_dnd_get_drag_data (GtkWidget *widget)
|
|
|
|
{
|
2005-03-26 01:16:07 +08:00
|
|
|
const GimpDndDataDef *dnd_data;
|
2001-09-20 03:06:36 +08:00
|
|
|
GimpDndType data_type;
|
2003-11-21 00:26:15 +08:00
|
|
|
GimpDndDragViewableFunc get_data_func = NULL;
|
|
|
|
gpointer get_data_data = NULL;
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpContext *context;
|
2001-03-04 07:23:36 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
data_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-dnd-get-data-type"));
|
2001-03-04 07:23:36 +08:00
|
|
|
|
|
|
|
if (! data_type)
|
|
|
|
return NULL;
|
|
|
|
|
2003-11-21 00:26:15 +08:00
|
|
|
dnd_data = dnd_data_defs + data_type;
|
|
|
|
|
|
|
|
if (dnd_data->get_data_func_name)
|
|
|
|
get_data_func = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_func_name);
|
|
|
|
|
|
|
|
if (dnd_data->get_data_data_name)
|
|
|
|
get_data_data = g_object_get_data (G_OBJECT (widget),
|
|
|
|
dnd_data->get_data_data_name);
|
2001-03-04 07:23:36 +08:00
|
|
|
|
|
|
|
if (! get_data_func)
|
|
|
|
return NULL;
|
|
|
|
|
2006-08-30 05:44:51 +08:00
|
|
|
return (GimpViewable *) (* get_data_func) (widget, &context, get_data_data);
|
2001-03-04 07:23:36 +08:00
|
|
|
}
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2001-04-13 20:10:22 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/*****************************/
|
|
|
|
/* GimpImage dnd functions */
|
|
|
|
/*****************************/
|
2001-04-13 20:10:22 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
|
|
|
gimp_dnd_get_image_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_image_func,
|
|
|
|
gpointer get_image_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
2001-04-13 20:10:22 +08:00
|
|
|
{
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpImage *image;
|
|
|
|
GimpContext *gimp_context;
|
2001-04-13 20:10:22 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
image = g_object_get_data (G_OBJECT (context), "gimp-dnd-viewable");
|
|
|
|
|
|
|
|
if (! image)
|
|
|
|
image = (GimpImage *)
|
|
|
|
(* (GimpDndDragViewableFunc) get_image_func) (widget, &gimp_context,
|
|
|
|
get_image_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "image %p", image);
|
2001-04-13 20:10:22 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
if (image)
|
|
|
|
gimp_selection_data_set_image (selection, image);
|
2001-04-13 20:10:22 +08:00
|
|
|
}
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_image_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_image_func,
|
|
|
|
gpointer set_image_data,
|
|
|
|
GtkSelectionData *selection)
|
2001-04-13 20:10:22 +08:00
|
|
|
{
|
2006-03-29 01:08:36 +08:00
|
|
|
GimpImage *image = gimp_selection_data_get_image (selection, the_dnd_gimp);
|
2001-04-13 20:10:22 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "image %p", image);
|
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
if (! image)
|
2003-12-21 18:53:56 +08:00
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_image_func) (widget, x, y,
|
2006-03-29 01:08:36 +08:00
|
|
|
GIMP_VIEWABLE (image),
|
2003-12-21 18:53:56 +08:00
|
|
|
set_image_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-04-13 20:10:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/****************************/
|
|
|
|
/* GimpItem dnd functions */
|
|
|
|
/****************************/
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
|
|
|
gimp_dnd_get_item_data (GtkWidget *widget,
|
2005-03-25 22:23:35 +08:00
|
|
|
GdkDragContext *context,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback get_item_func,
|
|
|
|
gpointer get_item_data,
|
2005-04-10 01:56:04 +08:00
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpItem *item;
|
|
|
|
GimpContext *gimp_context;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
item = g_object_get_data (G_OBJECT (context), "gimp-dnd-viewable");
|
|
|
|
|
|
|
|
if (! item)
|
|
|
|
item = (GimpItem *)
|
|
|
|
(* (GimpDndDragViewableFunc) get_item_func) (widget, &gimp_context,
|
|
|
|
get_item_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "item %p", item);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
if (item)
|
2005-04-10 01:56:04 +08:00
|
|
|
gimp_selection_data_set_item (selection, item);
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_item_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_item_func,
|
|
|
|
gpointer set_item_data,
|
|
|
|
GtkSelectionData *selection)
|
2001-02-20 06:54:12 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpItem *item = gimp_selection_data_get_item (selection, the_dnd_gimp);
|
2001-02-20 06:54:12 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "item %p", item);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! item)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_item_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (item),
|
|
|
|
set_item_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-02-20 06:54:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/******************************/
|
|
|
|
/* GimpObject dnd functions */
|
|
|
|
/******************************/
|
2001-02-20 06:54:12 +08:00
|
|
|
|
2004-06-29 04:39:54 +08:00
|
|
|
static void
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_get_object_data (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GCallback get_object_func,
|
|
|
|
gpointer get_object_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2006-08-30 05:44:51 +08:00
|
|
|
GimpObject *object;
|
|
|
|
GimpContext *gimp_context;
|
1999-10-28 23:05:49 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
object = g_object_get_data (G_OBJECT (context), "gimp-dnd-viewable");
|
|
|
|
|
|
|
|
if (! object)
|
|
|
|
object = (GimpObject *)
|
|
|
|
(* (GimpDndDragViewableFunc) get_object_func) (widget, &gimp_context,
|
|
|
|
get_object_data);
|
|
|
|
|
|
|
|
GIMP_LOG (DND, "object %p", object);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
if (GIMP_IS_OBJECT (object))
|
|
|
|
gimp_selection_data_set_object (selection, object);
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/*****************************/
|
|
|
|
/* GimpBrush dnd functions */
|
|
|
|
/*****************************/
|
2001-02-20 07:37:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_brush_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_brush_func,
|
|
|
|
gpointer set_brush_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpBrush *brush = gimp_selection_data_get_brush (selection, the_dnd_gimp);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "brush %p", brush);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! brush)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_brush_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (brush),
|
|
|
|
set_brush_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/*******************************/
|
|
|
|
/* GimpPattern dnd functions */
|
|
|
|
/*******************************/
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_pattern_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_pattern_func,
|
|
|
|
gpointer set_pattern_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpPattern *pattern = gimp_selection_data_get_pattern (selection,
|
|
|
|
the_dnd_gimp);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "pattern %p", pattern);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! pattern)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_pattern_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (pattern),
|
|
|
|
set_pattern_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/********************************/
|
|
|
|
/* GimpGradient dnd functions */
|
|
|
|
/********************************/
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_gradient_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_gradient_func,
|
|
|
|
gpointer set_gradient_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpGradient *gradient = gimp_selection_data_get_gradient (selection,
|
|
|
|
the_dnd_gimp);
|
1999-11-14 19:43:03 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "gradient %p", gradient);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! gradient)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_gradient_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (gradient),
|
|
|
|
set_gradient_data);
|
|
|
|
|
|
|
|
return TRUE;
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/*******************************/
|
|
|
|
/* GimpPalette dnd functions */
|
|
|
|
/*******************************/
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_palette_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_palette_func,
|
|
|
|
gpointer set_palette_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpPalette *palette = gimp_selection_data_get_palette (selection,
|
|
|
|
the_dnd_gimp);
|
2001-02-12 00:14:25 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "palette %p", palette);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! palette)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_palette_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (palette),
|
|
|
|
set_palette_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|
|
|
|
|
2001-02-14 03:53:07 +08:00
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/****************************/
|
|
|
|
/* GimpFont dnd functions */
|
|
|
|
/****************************/
|
2003-03-26 09:27:23 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_font_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_font_func,
|
|
|
|
gpointer set_font_data,
|
|
|
|
GtkSelectionData *selection)
|
2003-03-26 09:27:23 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpFont *font = gimp_selection_data_get_font (selection, the_dnd_gimp);
|
2003-03-26 09:27:23 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "font %p", font);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! font)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_font_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (font),
|
|
|
|
set_font_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-03-26 09:27:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/******************************/
|
|
|
|
/* GimpBuffer dnd functions */
|
|
|
|
/******************************/
|
2001-06-26 20:09:43 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_buffer_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_buffer_func,
|
|
|
|
gpointer set_buffer_data,
|
|
|
|
GtkSelectionData *selection)
|
2001-06-26 20:09:43 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpBuffer *buffer = gimp_selection_data_get_buffer (selection, the_dnd_gimp);
|
2001-06-26 20:09:43 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "buffer %p", buffer);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! buffer)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_buffer_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (buffer),
|
|
|
|
set_buffer_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-06-26 20:09:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/*********************************/
|
|
|
|
/* GimpImagefile dnd functions */
|
|
|
|
/*********************************/
|
2001-08-11 15:47:35 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_imagefile_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_imagefile_func,
|
|
|
|
gpointer set_imagefile_data,
|
|
|
|
GtkSelectionData *selection)
|
2001-08-11 15:47:35 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpImagefile *imagefile = gimp_selection_data_get_imagefile (selection,
|
|
|
|
the_dnd_gimp);
|
2001-08-11 15:47:35 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "imagefile %p", imagefile);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! imagefile)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_imagefile_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (imagefile),
|
|
|
|
set_imagefile_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2001-08-11 15:47:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/********************************/
|
|
|
|
/* GimpTemplate dnd functions */
|
|
|
|
/********************************/
|
2003-04-06 03:56:38 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2004-06-29 04:39:54 +08:00
|
|
|
gimp_dnd_set_template_data (GtkWidget *widget,
|
2004-12-31 22:36:30 +08:00
|
|
|
gint x,
|
|
|
|
gint y,
|
2004-06-29 04:39:54 +08:00
|
|
|
GCallback set_template_func,
|
|
|
|
gpointer set_template_data,
|
|
|
|
GtkSelectionData *selection)
|
2003-04-06 03:56:38 +08:00
|
|
|
{
|
2004-06-29 04:39:54 +08:00
|
|
|
GimpTemplate *template = gimp_selection_data_get_template (selection,
|
|
|
|
the_dnd_gimp);
|
2003-04-06 03:56:38 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "template %p", template);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! template)
|
|
|
|
return FALSE;
|
|
|
|
|
2004-12-31 22:36:30 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_template_func) (widget, x, y,
|
2003-12-21 18:53:56 +08:00
|
|
|
GIMP_VIEWABLE (template),
|
|
|
|
set_template_data);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-04-06 03:56:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
/********************************/
|
|
|
|
/* GimpToolInfo dnd functions */
|
|
|
|
/********************************/
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
static gboolean
|
2005-07-25 21:53:00 +08:00
|
|
|
gimp_dnd_set_tool_info_data (GtkWidget *widget,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GCallback set_tool_info_func,
|
|
|
|
gpointer set_tool_info_data,
|
|
|
|
GtkSelectionData *selection)
|
1999-10-28 23:05:49 +08:00
|
|
|
{
|
2005-07-25 21:53:00 +08:00
|
|
|
GimpToolInfo *tool_info = gimp_selection_data_get_tool_info (selection,
|
|
|
|
the_dnd_gimp);
|
2000-02-09 03:49:12 +08:00
|
|
|
|
Bug 676522 - Make DND work between images in *one* dockable...
...after in-DND image switching
This was actually two issues:
First, DND data is normally transferred on drop. In this situation the
contents of the source widget change in the middle of DND, so when the
drop happens there is nothing to transfer. Fixed this by attaching the
thing to transfer (image, item, color etc) to the GdkDragContext when
the DND operation starts, and trying to retrieve it on drop. Only when
nothing is attached we fall back to the traditional way of asking the
source widget. This is expected and an obvious fix.
Second, and not so obvious, the source part of the GTK+-internal state
of the DND operation (GtkDragSourceInfo) contains a *reference* (not a
copy) of the source widget's target list. When we change images in the
middle of DND, the source layer view's target list gets modified, and
because GtkDragSourceInfo only references it, the state of the ongoing
DND operation gets destroyed with it. Fixed this by changing
gimp_dnd_data_source_remove() to never change a source widget's target
list but instead create a new list without the removed target and
replace the source widget's list, keeping the ongoing drag's list
unaffected.
Also kept all the GIMP_LOG() stuff I added during debugging there, it
turned out to be quite useful.
2014-02-16 04:29:36 +08:00
|
|
|
GIMP_LOG (DND, "tool_info %p", tool_info);
|
|
|
|
|
2003-12-21 18:53:56 +08:00
|
|
|
if (! tool_info)
|
|
|
|
return FALSE;
|
|
|
|
|
2005-07-25 21:53:00 +08:00
|
|
|
(* (GimpDndDropViewableFunc) set_tool_info_func) (widget, x, y,
|
|
|
|
GIMP_VIEWABLE (tool_info),
|
|
|
|
set_tool_info_data);
|
2003-12-21 18:53:56 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2001-02-10 05:49:47 +08:00
|
|
|
}
|