Allow all sorts of things to be dropped on or in between the items of a

2004-06-28  Michael Natterer  <mitch@gimp.org>

	Allow all sorts of things to be dropped on or in between the
	items of a GimpContainerTreeView:

	* app/widgets/gimpcontainertreeview.[ch]: added more parameters to
	GimpContainerTreeView::drop_possible() to specify where ecactly
	the drop should take place (between or into items) and to support
	dropping all sorts of things.

	Renamed ::drop() to ::drop_viewable() and added ::drop_color(),
	::drop_files() and ::drop_svg(), which cover all possible drop
	types.

	* app/widgets/gimpcontainertreeview-dnd.[ch]: changed accordingly.
	Dispatch all kinds of drops to the resp. virtual functions.

	* app/widgets/gimpitemtreeview.c: changed accordingly.

	* app/widgets/gimplayertreeview.c: allow to drop URIs, colors
	and patterns to the layers dialog. Fixes bugs #119506 and #139246.
This commit is contained in:
Michael Natterer 2004-06-28 22:07:12 +00:00 committed by Michael Natterer
parent c5c63f31ee
commit 6a5e68c9e2
7 changed files with 469 additions and 78 deletions

View File

@ -1,3 +1,25 @@
2004-06-28 Michael Natterer <mitch@gimp.org>
Allow all sorts of things to be dropped on or in between the
items of a GimpContainerTreeView:
* app/widgets/gimpcontainertreeview.[ch]: added more parameters to
GimpContainerTreeView::drop_possible() to specify where ecactly
the drop should take place (between or into items) and to support
dropping all sorts of things.
Renamed ::drop() to ::drop_viewable() and added ::drop_color(),
::drop_files() and ::drop_svg(), which cover all possible drop
types.
* app/widgets/gimpcontainertreeview-dnd.[ch]: changed accordingly.
Dispatch all kinds of drops to the resp. virtual functions.
* app/widgets/gimpitemtreeview.c: changed accordingly.
* app/widgets/gimplayertreeview.c: allow to drop URIs, colors
and patterns to the layers dialog. Fixes bugs #119506 and #139246.
2004-06-28 Michael Natterer <mitch@gimp.org>
* app/file/file-open.[ch] (file_open_layer): new utility function

View File

@ -33,6 +33,7 @@
#include "gimpcontainerview.h"
#include "gimpdnd.h"
#include "gimppreviewrenderer.h"
#include "gimpselectiondata.h"
static gboolean
@ -42,26 +43,53 @@ gimp_container_tree_view_drop_status (GimpContainerTreeView *tree_view,
gint y,
guint time,
GtkTreePath **return_path,
GdkAtom *return_atom,
GimpDndType *return_src_type,
GimpViewable **return_src,
GimpViewable **return_dest,
GtkTreeViewDropPosition *return_pos)
{
GtkWidget *src_widget;
GimpViewable *src_viewable;
GtkTreePath *path;
GimpViewable *src_viewable = NULL;
GtkTreePath *path;
GtkTargetList *target_list;
GdkAtom target_atom;
GimpDndType src_type;
if (! gimp_container_view_get_reorderable (GIMP_CONTAINER_VIEW (tree_view)))
return FALSE;
src_widget = gtk_drag_get_source_widget (context);
if (! src_widget)
target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (tree_view->view));
target_atom = gtk_drag_dest_find_target (GTK_WIDGET (tree_view->view),
context, target_list);
if (! gtk_target_list_find (target_list, target_atom, &src_type))
return FALSE;
src_viewable = gimp_dnd_get_drag_data (src_widget);
switch (src_type)
{
case GIMP_DND_TYPE_URI_LIST:
case GIMP_DND_TYPE_TEXT_PLAIN:
case GIMP_DND_TYPE_NETSCAPE_URL:
case GIMP_DND_TYPE_COLOR:
case GIMP_DND_TYPE_SVG:
case GIMP_DND_TYPE_SVG_XML:
break;
if (! GIMP_IS_VIEWABLE (src_viewable))
return FALSE;
default:
{
GtkWidget *src_widget;
src_widget = gtk_drag_get_source_widget (context);
if (! src_widget)
return FALSE;
src_viewable = gimp_dnd_get_drag_data (src_widget);
if (! GIMP_IS_VIEWABLE (src_viewable))
return FALSE;
}
break;
}
if (gtk_tree_view_get_path_at_pos (tree_view->view, x, y,
&path, NULL, NULL, NULL))
@ -81,19 +109,25 @@ gimp_container_tree_view_drop_status (GimpContainerTreeView *tree_view,
dest_viewable = renderer->viewable;
g_object_unref (renderer);
gtk_tree_view_get_cell_area (tree_view->view, path, NULL, &cell_area);
if (y >= (cell_area.y + cell_area.height / 2))
drop_pos = GTK_TREE_VIEW_DROP_AFTER;
{
drop_pos = GTK_TREE_VIEW_DROP_AFTER;
}
else
drop_pos = GTK_TREE_VIEW_DROP_BEFORE;
g_object_unref (renderer);
{
drop_pos = GTK_TREE_VIEW_DROP_BEFORE;
}
if (GIMP_CONTAINER_TREE_VIEW_GET_CLASS (tree_view)->drop_possible (tree_view,
src_type,
src_viewable,
dest_viewable,
drop_pos,
&drop_pos,
&drag_action))
{
gdk_drag_status (context, drag_action, time);
@ -103,6 +137,9 @@ gimp_container_tree_view_drop_status (GimpContainerTreeView *tree_view,
else
gtk_tree_path_free (path);
if (return_atom)
*return_atom = target_atom;
if (return_src)
*return_src = src_viewable;
@ -225,7 +262,8 @@ gimp_container_tree_view_drag_motion (GtkWidget *widget,
if (gimp_container_tree_view_drop_status (tree_view,
context, x, y, time,
&path, NULL, NULL, &drop_pos))
&path, NULL, NULL, NULL, NULL,
&drop_pos))
{
gtk_tree_view_set_drag_dest_row (tree_view->view, path, drop_pos);
gtk_tree_path_free (path);
@ -246,8 +284,10 @@ gimp_container_tree_view_drag_drop (GtkWidget *widget,
guint time,
GimpContainerTreeView *tree_view)
{
GimpDndType src_type;
GimpViewable *src_viewable;
GimpViewable *dest_viewable;
GdkAtom target;
GtkTreeViewDropPosition drop_pos;
if (tree_view->scroll_timeout_id)
@ -258,42 +298,149 @@ gimp_container_tree_view_drag_drop (GtkWidget *widget,
if (gimp_container_tree_view_drop_status (tree_view,
context, x, y, time,
NULL, &src_viewable, &dest_viewable,
&drop_pos))
NULL, &target, &src_type,
&src_viewable,
&dest_viewable, &drop_pos))
{
GIMP_CONTAINER_TREE_VIEW_GET_CLASS (tree_view)->drop (tree_view,
src_viewable,
dest_viewable,
drop_pos);
GimpContainerTreeViewClass *tree_view_class;
tree_view_class = GIMP_CONTAINER_TREE_VIEW_GET_CLASS (tree_view);
if (src_viewable)
tree_view_class->drop_viewable (tree_view,
src_viewable,
dest_viewable,
drop_pos);
else
gtk_drag_get_data (widget, context, target, time);
return TRUE;
}
return TRUE;
return FALSE;
}
void
gimp_container_tree_view_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
GimpContainerTreeView *tree_view)
{
GimpViewable *dest_viewable;
GtkTreeViewDropPosition drop_pos;
gboolean success = FALSE;
if (gimp_container_tree_view_drop_status (tree_view,
context, x, y, time,
NULL, NULL, NULL, NULL,
&dest_viewable, &drop_pos))
{
GimpContainerTreeViewClass *tree_view_class;
tree_view_class = GIMP_CONTAINER_TREE_VIEW_GET_CLASS (tree_view);
switch (info)
{
case GIMP_DND_TYPE_URI_LIST:
case GIMP_DND_TYPE_TEXT_PLAIN:
case GIMP_DND_TYPE_NETSCAPE_URL:
if (tree_view_class->drop_files)
{
GList *uri_list;
uri_list = gimp_selection_data_get_uris (selection_data);
if (uri_list)
{
tree_view_class->drop_files (tree_view, uri_list,
dest_viewable, drop_pos);
g_list_foreach (uri_list, (GFunc) g_free, NULL);
g_list_free (uri_list);
success = TRUE;
}
}
break;
case GIMP_DND_TYPE_COLOR:
if (tree_view_class->drop_color)
{
GimpRGB color;
if (gimp_selection_data_get_color (selection_data, &color))
{
tree_view_class->drop_color (tree_view, &color,
dest_viewable, drop_pos);
success = TRUE;
}
}
break;
case GIMP_DND_TYPE_SVG:
case GIMP_DND_TYPE_SVG_XML:
if (tree_view_class->drop_svg)
{
gchar *svg_data;
gint svg_data_length;
svg_data = gimp_selection_data_get_svg (selection_data,
&svg_data_length);
if (svg_data)
{
tree_view_class->drop_svg (tree_view,
svg_data, svg_data_length,
dest_viewable, drop_pos);
g_free (svg_data);
success = TRUE;
}
}
break;
default:
break;
}
}
gtk_drag_finish (context, success, FALSE, time);
}
gboolean
gimp_container_tree_view_real_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action)
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action)
{
GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
GimpContainer *container = gimp_container_view_get_container (view);
gint src_index;
gint dest_index;
GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
GimpContainer *container = gimp_container_view_get_container (view);
gint src_index = -1;
gint dest_index = -1;
if (src_viewable == dest_viewable)
return FALSE;
if (src_viewable && g_type_is_a (G_TYPE_FROM_INSTANCE (src_viewable),
container->children_type))
{
if (src_viewable == dest_viewable)
return FALSE;
src_index = gimp_container_get_child_index (container,
GIMP_OBJECT (src_viewable));
dest_index = gimp_container_get_child_index (container,
GIMP_OBJECT (dest_viewable));
src_index = gimp_container_get_child_index (container,
GIMP_OBJECT (src_viewable));
dest_index = gimp_container_get_child_index (container,
GIMP_OBJECT (dest_viewable));
if (src_index == -1 || dest_index == -1)
return FALSE;
if (src_index == -1 || dest_index == -1)
return FALSE;
}
if (drop_pos == GTK_TREE_VIEW_DROP_BEFORE)
{
@ -306,17 +453,26 @@ gimp_container_tree_view_real_drop_possible (GimpContainerTreeView *tree_view,
return FALSE;
}
if (drag_action)
*drag_action = GDK_ACTION_MOVE;
if (return_drop_pos)
*return_drop_pos = drop_pos;
if (return_drag_action)
{
if (src_viewable && g_type_is_a (G_TYPE_FROM_INSTANCE (src_viewable),
container->children_type))
*return_drag_action = GDK_ACTION_MOVE;
else
*return_drag_action = GDK_ACTION_COPY;
}
return TRUE;
}
void
gimp_container_tree_view_real_drop (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
gimp_container_tree_view_real_drop_viewable (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
GimpContainer *container = gimp_container_view_get_container (view);

View File

@ -39,15 +39,26 @@ gboolean gimp_container_tree_view_drag_drop (GtkWidget *widget,
gint y,
guint time,
GimpContainerTreeView *view);
void gimp_container_tree_view_drag_data_received
(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
GimpContainerTreeView *view);
gboolean
gimp_container_tree_view_real_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action);
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
void
gimp_container_tree_view_real_drop (GimpContainerTreeView *tree_view,
gimp_container_tree_view_real_drop_viewable (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);

View File

@ -155,7 +155,10 @@ gimp_container_tree_view_class_init (GimpContainerTreeViewClass *klass)
widget_class->popup_menu = gimp_container_tree_view_popup_menu;
klass->drop_possible = gimp_container_tree_view_real_drop_possible;
klass->drop = gimp_container_tree_view_real_drop;
klass->drop_viewable = gimp_container_tree_view_real_drop_viewable;
klass->drop_color = NULL;
klass->drop_files = NULL;
klass->drop_svg = NULL;
}
static void
@ -274,6 +277,9 @@ gimp_container_tree_view_constructor (GType type,
g_signal_connect (tree_view->view, "drag_drop",
G_CALLBACK (gimp_container_tree_view_drag_drop),
tree_view);
g_signal_connect (tree_view->view, "drag_data_received",
G_CALLBACK (gimp_container_tree_view_drag_data_received),
tree_view);
return object;
}

View File

@ -73,14 +73,29 @@ struct _GimpContainerTreeViewClass
GimpContainerBoxClass parent_class;
gboolean (* drop_possible) (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action);
void (* drop) (GimpContainerTreeView *tree_view,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
void (* drop_viewable) (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
void (* drop_color) (GimpContainerTreeView *tree_view,
const GimpRGB *src_color,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
void (* drop_files) (GimpContainerTreeView *tree_view,
GList *files,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
void (* drop_svg) (GimpContainerTreeView *tree_view,
const gchar *svg_data,
gint svg_data_length,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
};

View File

@ -112,11 +112,13 @@ static void gimp_item_tree_view_context_item (GimpContainerView *view,
gpointer insert_data);
static gboolean gimp_item_tree_view_drop_possible (GimpContainerTreeView *view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action);
static void gimp_item_tree_view_drop (GimpContainerTreeView *view,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
static void gimp_item_tree_view_drop_viewable (GimpContainerTreeView *view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
@ -266,7 +268,7 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass)
gtk_object_class->destroy = gimp_item_tree_view_destroy;
tree_view_class->drop_possible = gimp_item_tree_view_drop_possible;
tree_view_class->drop = gimp_item_tree_view_drop;
tree_view_class->drop_viewable = gimp_item_tree_view_drop_viewable;
klass->set_image = gimp_item_tree_view_real_set_image;
@ -530,7 +532,7 @@ gimp_item_tree_view_constructor (GType type,
gimp_container_view_set_dnd_widget (GIMP_CONTAINER_VIEW (item_view), NULL);
gimp_dnd_drag_dest_set_by_type (GTK_WIDGET (tree_view->view),
GTK_DEST_DEFAULT_ALL,
GTK_DEST_DEFAULT_HIGHLIGHT,
item_view->item_type,
GDK_ACTION_MOVE | GDK_ACTION_COPY);
@ -893,32 +895,40 @@ gimp_item_tree_view_context_item (GimpContainerView *view,
static gboolean
gimp_item_tree_view_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action)
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action)
{
if (gimp_item_get_image (GIMP_ITEM (src_viewable)) !=
if (GIMP_IS_ITEM (src_viewable) &&
gimp_item_get_image (GIMP_ITEM (src_viewable)) !=
gimp_item_get_image (GIMP_ITEM (dest_viewable)))
{
if (drag_action)
*drag_action = GDK_ACTION_COPY;
if (return_drop_pos)
*return_drop_pos = drop_pos;
if (return_drag_action)
*return_drag_action = GDK_ACTION_COPY;
return TRUE;
}
return GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view,
src_type,
src_viewable,
dest_viewable,
drop_pos,
drag_action);
return_drop_pos,
return_drag_action);
}
static void
gimp_item_tree_view_drop (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
gimp_item_tree_view_drop_viewable (GimpContainerTreeView *tree_view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tree_view);
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (tree_view);

View File

@ -30,14 +30,21 @@
#include "widgets-types.h"
#include "core/gimpcontainer.h"
#include "core/gimpdrawable-bucket-fill.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimplayer-floating-sel.h"
#include "core/gimplist.h"
#include "core/gimpimage.h"
#include "core/gimpitemundo.h"
#include "core/gimppattern.h"
#include "core/gimpundostack.h"
#include "text/gimptextlayer.h"
#include "file/file-open.h"
#include "file/file-utils.h"
#include "gimpcellrenderertoggle.h"
#include "gimpcellrendererviewable.h"
#include "gimpcontainerview.h"
@ -76,10 +83,24 @@ static gboolean gimp_layer_tree_view_select_item (GimpContainerView *view,
static void gimp_layer_tree_view_set_preview_size (GimpContainerView *view);
static gboolean gimp_layer_tree_view_drop_possible(GimpContainerTreeView *view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action);
GtkTreeViewDropPosition drop_pos,
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action);
static void gimp_layer_tree_view_drop_viewable (GimpContainerTreeView *view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
static void gimp_layer_tree_view_drop_color (GimpContainerTreeView *view,
const GimpRGB *color,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
static void gimp_layer_tree_view_drop_files (GimpContainerTreeView *view,
GList *files,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos);
static void gimp_layer_tree_view_set_image (GimpItemTreeView *view,
GimpImage *gimage);
@ -198,6 +219,9 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
widget_class->style_set = gimp_layer_tree_view_style_set;
tree_view_class->drop_possible = gimp_layer_tree_view_drop_possible;
tree_view_class->drop_viewable = gimp_layer_tree_view_drop_viewable;
tree_view_class->drop_color = gimp_layer_tree_view_drop_color;
tree_view_class->drop_files = gimp_layer_tree_view_drop_files;
item_view_class->set_image = gimp_layer_tree_view_set_image;
item_view_class->get_container = gimp_image_get_layers;
@ -384,6 +408,13 @@ gimp_layer_tree_view_constructor (GType type,
G_CALLBACK (gimp_layer_tree_view_mask_clicked),
layer_view);
gimp_dnd_file_dest_add (GTK_WIDGET (tree_view->view),
NULL, tree_view);
gimp_dnd_color_dest_add (GTK_WIDGET (tree_view->view),
NULL, tree_view);
gimp_dnd_viewable_dest_add (GTK_WIDGET (tree_view->view), GIMP_TYPE_PATTERN,
NULL, tree_view);
layer_view->anchor_button =
gimp_editor_add_action_button (GIMP_EDITOR (layer_view), "layers",
"layers-anchor", NULL);
@ -629,32 +660,172 @@ gimp_layer_tree_view_set_preview_size (GimpContainerView *view)
static gboolean
gimp_layer_tree_view_drop_possible (GimpContainerTreeView *tree_view,
GimpDndType src_type,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos,
GdkDragAction *drag_action)
GtkTreeViewDropPosition *return_drop_pos,
GdkDragAction *return_drag_action)
{
GimpLayer *src_layer = GIMP_LAYER (src_viewable);
GimpLayer *dest_layer = GIMP_LAYER (dest_viewable);
GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (src_layer));
GimpImage *dest_image = gimp_item_get_image (GIMP_ITEM (dest_layer));
if (src_type == GIMP_DND_TYPE_URI_LIST ||
src_type == GIMP_DND_TYPE_TEXT_PLAIN ||
src_type == GIMP_DND_TYPE_NETSCAPE_URL ||
GIMP_IS_LAYER (src_viewable))
{
GimpLayer *dest_layer = GIMP_LAYER (dest_viewable);
GimpImage *dest_image = gimp_item_get_image (GIMP_ITEM (dest_layer));
if (gimp_image_floating_sel (dest_image))
return FALSE;
if (gimp_image_floating_sel (dest_image))
return FALSE;
if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (dest_layer)) &&
drop_pos == GTK_TREE_VIEW_DROP_AFTER)
return FALSE;
if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (dest_layer)) &&
drop_pos == GTK_TREE_VIEW_DROP_AFTER)
return FALSE;
if (src_image == dest_image &&
! gimp_drawable_has_alpha (GIMP_DRAWABLE (src_layer)))
return FALSE;
if (GIMP_IS_LAYER (src_viewable))
{
GimpLayer *src_layer = GIMP_LAYER (src_viewable);
GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (src_layer));
return GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view,
src_viewable,
dest_viewable,
drop_pos,
drag_action);
if (src_image == dest_image &&
! gimp_drawable_has_alpha (GIMP_DRAWABLE (src_layer)))
return FALSE;
}
}
if (GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view,
src_type,
src_viewable,
dest_viewable,
drop_pos,
return_drop_pos,
return_drag_action))
{
if (return_drop_pos &&
(src_type == GIMP_DND_TYPE_COLOR ||
src_type == GIMP_DND_TYPE_PATTERN))
{
if (drop_pos == GTK_TREE_VIEW_DROP_BEFORE)
*return_drop_pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
else
*return_drop_pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER;
}
return TRUE;
}
return FALSE;
}
static void
gimp_layer_tree_view_drop_viewable (GimpContainerTreeView *view,
GimpViewable *src_viewable,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
if (GIMP_IS_PATTERN (src_viewable))
{
gimp_drawable_bucket_fill_full (GIMP_DRAWABLE (dest_viewable),
GIMP_PATTERN_BUCKET_FILL,
GIMP_NORMAL_MODE, GIMP_OPACITY_OPAQUE,
FALSE, /* no seed fill */
FALSE, 0.0, FALSE, /* fill params */
0.0, 0.0, /* ignored */
NULL, GIMP_PATTERN (src_viewable));
gimp_image_flush (GIMP_ITEM_TREE_VIEW (view)->gimage);
return;
}
GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_viewable (view,
src_viewable,
dest_viewable,
drop_pos);
}
static void
gimp_layer_tree_view_drop_color (GimpContainerTreeView *view,
const GimpRGB *color,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
if (gimp_drawable_is_text_layer (GIMP_DRAWABLE (dest_viewable)))
{
gimp_text_layer_set (GIMP_TEXT_LAYER (dest_viewable), NULL,
"color", color,
NULL);
}
else
{
gimp_drawable_bucket_fill_full (GIMP_DRAWABLE (dest_viewable),
GIMP_FG_BUCKET_FILL,
GIMP_NORMAL_MODE, GIMP_OPACITY_OPAQUE,
FALSE, /* no seed fill */
FALSE, 0.0, FALSE, /* fill params */
0.0, 0.0, /* ignored */
color, NULL);
}
gimp_image_flush (GIMP_ITEM_TREE_VIEW (view)->gimage);
}
static void
gimp_layer_tree_view_drop_files (GimpContainerTreeView *view,
GList *files,
GimpViewable *dest_viewable,
GtkTreeViewDropPosition drop_pos)
{
GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
GimpImage *gimage = item_view->gimage;
GList *list;
gint index;
index = gimp_image_get_layer_index (gimage, GIMP_LAYER (dest_viewable));
if (drop_pos == GTK_TREE_VIEW_DROP_AFTER)
index++;
for (list = files; list; list = g_list_next (list))
{
const gchar *uri = list->data;
GimpLayer *new_layer;
GimpPDBStatusType status;
GError *error = NULL;
new_layer = file_open_layer (gimage->gimp, item_view->context, gimage,
uri,
&status, &error);
if (new_layer)
{
GimpItem *new_item = GIMP_ITEM (new_layer);
gint width, height;
gint off_x, off_y;
width = gimp_image_get_width (gimage);
height = gimp_image_get_height (gimage);
gimp_item_offsets (new_item, &off_x, &off_y);
off_x = (width - gimp_item_width (new_item)) / 2 - off_x;
off_y = (height - gimp_item_height (new_item)) / 2 - off_y;
gimp_item_translate (new_item, off_x, off_y, FALSE);
gimp_image_add_layer (gimage, new_layer, index++);
}
else if (status != GIMP_PDB_CANCEL)
{
gchar *filename = file_utils_uri_to_utf8_filename (uri);
g_message (_("Opening '%s' failed:\n\n%s"),
filename, error->message);
g_clear_error (&error);
g_free (filename);
}
}
gimp_image_flush (gimage);
}