Commit a2530f59 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer
Browse files

Made file/url DND work like the other DND types. The drop callback gets

2001-05-01  Michael Natterer  <mitch@gimp.org>

	* app/gimpdnd.[ch]: Made file/url DND work like the other DND types.
	The drop callback gets passed a GList of filenames.
	Provide a default callback which calls file_open_with_display()
	for each filename.

	* app/docindex.c: changed accordingly.

	* app/gui/toolbox.c: same file DND changes and made dropping
	drawables work again with the new DND system.

	* app/widgets/gimpdrawablelistview.c: properly disconnect from the
	image in "destroy".

	* app/widgets/gimplayerlistitem.c: gtk_signal_connect_while_alive()
	to the layer's "mask_changed" signal.
parent d010bb5f
2001-05-01 Michael Natterer <mitch@gimp.org>
* app/gimpdnd.[ch]: Made file/url DND work like the other DND types.
The drop callback gets passed a GList of filenames.
Provide a default callback which calls file_open_with_display()
for each filename.
* app/docindex.c: changed accordingly.
* app/gui/toolbox.c: same file DND changes and made dropping
drawables work again with the new DND system.
* app/widgets/gimpdrawablelistview.c: properly disconnect from the
image in "destroy".
* app/widgets/gimplayerlistitem.c: gtk_signal_connect_while_alive()
to the layer's "mask_changed" signal.
2001-05-01 Michael Natterer <mitch@gimp.org>
* app/app_procs.c: removed more GUI initialisation code.
......@@ -12,9 +30,14 @@
* app/gui/dialogs.h: removed "extern" declaration of non-existant
variable.
* app/gui/gui.[ch]
* app/gui/tips-dialog.c
* app/gui/toolbox.[ch]
* app/gui/gui.[ch]: new function gui_post_init() which shows the
tips dialog.
* app/gui/tips-dialog.c: made signal handling nicer (clean up in a
"destroy" handler).
* app/gui/toolbox.[ch]: removed toolbox_raise(), removed the help
system (de)initialisation code which is now in gui.c, cleanup.
2001-04-30 Dave Neary <dneary@eircom.net>
......
......@@ -792,7 +792,7 @@ open_idea_window (void)
drag_types, n_drag_types,
GDK_ACTION_COPY);
gimp_dnd_file_dest_set (ideas->window);
gimp_dnd_file_dest_set (ideas->window, gimp_dnd_open_files, NULL);
dialog_register (ideas->window);
......
......@@ -62,6 +62,11 @@
typedef enum
{
GIMP_DND_DATA_NONE,
GIMP_DND_DATA_FIRST,
GIMP_DND_DATA_FILE_URI_LIST = GIMP_DND_DATA_FIRST,
GIMP_DND_DATA_FILE_TEXT_PLAIN,
GIMP_DND_DATA_FILE_NETSCAPE_URL,
GIMP_DND_DATA_COLOR,
GIMP_DND_DATA_IMAGE,
GIMP_DND_DATA_LAYER,
......@@ -72,6 +77,7 @@ typedef enum
GIMP_DND_DATA_GRADIENT,
GIMP_DND_DATA_PALETTE,
GIMP_DND_DATA_TOOL,
GIMP_DND_DATA_LAST = GIMP_DND_DATA_TOOL
} GimpDndDataType;
......@@ -140,6 +146,12 @@ static guchar * gimp_dnd_get_tool_data (GtkWidget *widget,
gint *format,
gint *length);
static void gimp_dnd_set_file_data (GtkWidget *widget,
GtkSignalFunc set_color_func,
gpointer set_color_data,
guchar *vals,
gint format,
gint length);
static void gimp_dnd_set_color_data (GtkWidget *widget,
GtkSignalFunc set_color_func,
gpointer set_color_data,
......@@ -203,6 +215,39 @@ static GimpDndDataDef dnd_data_defs[] =
NULL
},
{
GIMP_TARGET_URI_LIST,
"gimp_dnd_set_file_func",
"gimp_dnd_set_file_data",
NULL,
NULL,
gimp_dnd_set_file_data
},
{
GIMP_TARGET_TEXT_PLAIN,
"gimp_dnd_set_file_func",
"gimp_dnd_set_file_data",
NULL,
NULL,
gimp_dnd_set_file_data
},
{
GIMP_TARGET_NETSCAPE_URL,
"gimp_dnd_set_file_func",
"gimp_dnd_set_file_data",
NULL,
NULL,
gimp_dnd_set_file_data
},
{
GIMP_TARGET_COLOR,
......@@ -450,7 +495,7 @@ gimp_dnd_data_drop_handle (GtkWidget *widget,
if (selection_data->length < 0)
return;
for (data_type = GIMP_DND_DATA_COLOR;
for (data_type = GIMP_DND_DATA_FIRST;
data_type <= GIMP_DND_DATA_LAST;
data_type++)
{
......@@ -583,6 +628,114 @@ gimp_dnd_data_dest_unset (GimpDndDataType data_type,
}
/************************/
/* file dnd functions */
/************************/
static void
gimp_dnd_set_file_data (GtkWidget *widget,
GtkSignalFunc set_file_func,
gpointer set_file_data,
guchar *vals,
gint format,
gint length)
{
GList *files = NULL;
gchar *buffer;
if (format != 8)
{
g_warning ("Received invalid file data\n");
return;
}
buffer = (gchar *) vals;
{
gchar name_buffer[1024];
const gchar *data_type = "file:";
const gint sig_len = strlen (data_type);
while (*buffer)
{
gchar *name = name_buffer;
gint len = 0;
while ((*buffer != 0) && (*buffer != '\n') && len < 1024)
{
*name++ = *buffer++;
len++;
}
if (len == 0)
break;
if (*(name - 1) == 0xd) /* gmc uses RETURN+NEWLINE as delimiter */
*(name - 1) = '\0';
else
*name = '\0';
name = name_buffer;
if ((sig_len < len) && (! strncmp (name, data_type, sig_len)))
name += sig_len;
if (name && strlen (name) > 2)
files = g_list_append (files, name);
if (*buffer)
buffer++;
}
}
if (files)
{
(* (GimpDndDropFileFunc) set_file_func) (widget, files,
set_file_data);
g_list_free (files);
}
}
void
gimp_dnd_file_dest_set (GtkWidget *widget,
GimpDndDropFileFunc set_file_func,
gpointer data)
{
gimp_dnd_data_dest_set (GIMP_DND_DATA_FILE_URI_LIST, widget,
GTK_SIGNAL_FUNC (set_file_func),
data);
gimp_dnd_data_dest_set (GIMP_DND_DATA_FILE_TEXT_PLAIN, widget,
GTK_SIGNAL_FUNC (set_file_func),
data);
gimp_dnd_data_dest_set (GIMP_DND_DATA_FILE_NETSCAPE_URL, widget,
GTK_SIGNAL_FUNC (set_file_func),
data);
}
void
gimp_dnd_file_dest_unset (GtkWidget *widget)
{
gimp_dnd_data_dest_unset (GIMP_DND_DATA_FILE_URI_LIST, widget);
gimp_dnd_data_dest_unset (GIMP_DND_DATA_FILE_TEXT_PLAIN, widget);
gimp_dnd_data_dest_unset (GIMP_DND_DATA_FILE_NETSCAPE_URL, widget);
}
void
gimp_dnd_open_files (GtkWidget *widget,
GList *files,
gpointer data)
{
GList *list;
for (list = files; list; list = g_list_next (list))
{
gchar *filename = (gchar *) list->data;
file_open_with_display (filename, filename);
}
}
/*************************/
/* color dnd functions */
/*************************/
......@@ -1447,76 +1600,3 @@ gimp_dnd_set_drawable_preview_icon (GtkWidget *widget,
gtk_drag_set_icon_widget (context, window,
DRAG_ICON_OFFSET, DRAG_ICON_OFFSET);
}
/******************************/
/* file / url dnd functions */
/******************************/
static void
gimp_dnd_file_open_files (gchar *buffer)
{
gchar name_buffer[1024];
const gchar *data_type = "file:";
const gint sig_len = strlen (data_type);
while (*buffer)
{
gchar *name = name_buffer;
gint len = 0;
while ((*buffer != 0) && (*buffer != '\n') && len < 1024)
{
*name++ = *buffer++;
len++;
}
if (len == 0)
break;
if (*(name - 1) == 0xd) /* gmc uses RETURN+NEWLINE as delimiter */
*(name - 1) = '\0';
else
*name = '\0';
name = name_buffer;
if ((sig_len < len) && (! strncmp (name, data_type, sig_len)))
name += sig_len;
if (name && strlen (name) > 2)
file_open_with_display (name, name);
if (*buffer)
buffer++;
}
}
static void
gimp_dnd_file_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time)
{
switch (context->action)
{
case GDK_ACTION_DEFAULT:
case GDK_ACTION_COPY:
case GDK_ACTION_MOVE:
case GDK_ACTION_LINK:
case GDK_ACTION_ASK:
default:
gimp_dnd_file_open_files ((gchar *) data->data);
gtk_drag_finish (context, TRUE, FALSE, time);
break;
}
return;
}
void
gimp_dnd_file_dest_set (GtkWidget *widget)
{
gtk_signal_connect (GTK_OBJECT (widget), "drag_data_received",
GTK_SIGNAL_FUNC (gimp_dnd_file_drag_data_received),
widget);
}
......@@ -97,6 +97,25 @@ typedef enum
{ "GIMP_DIALOG", GTK_TARGET_SAME_APP, GIMP_DND_TYPE_DIALOG }
/* file / url dnd functions */
typedef void (* GimpDndDropFileFunc) (GtkWidget *widget,
GList *files,
gpointer data);
void gimp_dnd_file_dest_set (GtkWidget *widget,
GimpDndDropFileFunc set_file_func,
gpointer data);
void gimp_dnd_file_dest_unset (GtkWidget *widget);
/* standard callback */
void gimp_dnd_open_files (GtkWidget *widget,
GList *files,
gpointer data);
/* color dnd functions */
typedef void (* GimpDndDropColorFunc) (GtkWidget *widget,
......@@ -155,9 +174,4 @@ void gimp_dnd_set_drawable_preview_icon (GtkWidget *widget,
GimpDrawable *drawable);
/* file / url dnd functions */
void gimp_dnd_file_dest_set (GtkWidget *widget);
#endif /* __GIMP_DND_H__ */
......@@ -49,6 +49,7 @@
#include "gimage.h"
#include "gimpcontext.h"
#include "gimplayer.h"
#include "gimplayermask.h"
#include "gimplist.h"
#include "gimprc.h"
#include "pixel_region.h"
......@@ -61,31 +62,29 @@
/* local functions */
static void toolbox_tool_button_toggled (GtkWidget *widget,
gpointer data);
static gint toolbox_tool_button_press (GtkWidget *widget,
GdkEventButton *bevent,
gpointer data);
static void toolbox_destroy (void);
static gint toolbox_delete (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gint toolbox_check_device (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static void toolbox_style_set_callback (GtkWidget *window,
GtkStyle *previous_style,
gpointer data);
static gboolean toolbox_drag_drop (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time);
static void toolbox_drop_tool (GtkWidget *widget,
GimpViewable *viewable,
gpointer data);
static void toolbox_tool_button_toggled (GtkWidget *widget,
gpointer data);
static gint toolbox_tool_button_press (GtkWidget *widget,
GdkEventButton *bevent,
gpointer data);
static void toolbox_destroy (void);
static gint toolbox_delete (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gint toolbox_check_device (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static void toolbox_style_set_callback (GtkWidget *window,
GtkStyle *previous_style,
gpointer data);
static void toolbox_drop_drawable (GtkWidget *widget,
GimpViewable *viewable,
gpointer data);
static void toolbox_drop_tool (GtkWidget *widget,
GimpViewable *viewable,
gpointer data);
#define COLUMNS 3
......@@ -418,11 +417,14 @@ toolbox_create (void)
toolbox_target_table, toolbox_n_targets,
GDK_ACTION_COPY);
gimp_dnd_file_dest_set (window);
gimp_dnd_file_dest_set (window, gimp_dnd_open_files, NULL);
gtk_signal_connect (GTK_OBJECT (window), "drag_drop",
GTK_SIGNAL_FUNC (toolbox_drag_drop),
NULL);
gimp_dnd_viewable_dest_set (window, GIMP_TYPE_LAYER,
toolbox_drop_drawable, NULL);
gimp_dnd_viewable_dest_set (window, GIMP_TYPE_LAYER_MASK,
toolbox_drop_drawable, NULL);
gimp_dnd_viewable_dest_set (window, GIMP_TYPE_CHANNEL,
toolbox_drop_drawable, NULL);
gimp_dnd_viewable_dest_set (window, GIMP_TYPE_TOOL_INFO,
toolbox_drop_tool, NULL);
......@@ -465,161 +467,96 @@ toolbox_style_set_callback (GtkWidget *window,
GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
}
static gboolean
toolbox_drag_drop (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
guint time)
static void
toolbox_drop_drawable (GtkWidget *widget,
GimpViewable *viewable,
gpointer data)
{
GtkWidget *src_widget;
gboolean return_val = FALSE;
GimpDrawable *drawable;
GimpImage *gimage;
GimpImage *new_gimage;
GimpLayer *new_layer;
gint width, height;
gint off_x, off_y;
gint bytes;
GimpImageBaseType type;
drawable = GIMP_DRAWABLE (viewable);
gimage = gimp_drawable_gimage (drawable);
width = gimp_drawable_width (drawable);
height = gimp_drawable_height (drawable);
bytes = gimp_drawable_bytes (drawable);
switch (gimp_drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = RGB; break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = GRAY; break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = INDEXED; break;
default:
type = RGB; break;
}
if ((src_widget = gtk_drag_get_source_widget (context)))
new_gimage = gimage_new (width, height, type);
gimp_image_undo_disable (new_gimage);
if (type == INDEXED) /* copy the colormap */
{
GimpDrawable *drawable = NULL;
GimpLayer *layer = NULL;
GimpChannel *channel = NULL;
GimpLayerMask *layer_mask = NULL;
GimpImage *component = NULL;
ChannelType component_type = -1;
layer = (GimpLayer *) gtk_object_get_data (GTK_OBJECT (src_widget),
"gimp_layer");
channel = (GimpChannel *) gtk_object_get_data (GTK_OBJECT (src_widget),
"gimp_channel");
layer_mask = (GimpLayerMask *) gtk_object_get_data (GTK_OBJECT (src_widget),
"gimp_layer_mask");
component = (GimpImage *) gtk_object_get_data (GTK_OBJECT (src_widget),
"gimp_component");
if (layer)
{
drawable = GIMP_DRAWABLE (layer);
}
else if (channel)
{
drawable = GIMP_DRAWABLE (channel);
}
else if (layer_mask)
{
drawable = GIMP_DRAWABLE (layer_mask);
}
else if (component)
{
component_type =
(ChannelType) gtk_object_get_data (GTK_OBJECT (src_widget),
"gimp_component_type");
}
new_gimage->num_cols = gimage->num_cols;
memcpy (new_gimage->cmap, gimage->cmap, COLORMAP_SIZE);
}
if (drawable)
{
GimpImage *gimage;
GimpImage *new_gimage;
GimpLayer *new_layer;
gint width, height;
gint off_x, off_y;
gint bytes;
GimpImageBaseType type;
gimage = gimp_drawable_gimage (drawable);
width = gimp_drawable_width (drawable);
height = gimp_drawable_height (drawable);
bytes = gimp_drawable_bytes (drawable);
switch (gimp_drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = RGB; break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = GRAY; break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = INDEXED; break;
default:
type = RGB; break;
}
new_gimage = gimage_new (width, height, type);
gimp_image_undo_disable (new_gimage);
if (type == INDEXED) /* copy the colormap */
{
new_gimage->num_cols = gimage->num_cols;
memcpy (new_gimage->cmap, gimage->cmap, COLORMAP_SIZE);
}
gimp_image_set_resolution (new_gimage,
gimage->xresolution, gimage->yresolution);
gimp_image_set_unit (new_gimage, gimage->unit);
if (layer)
{
new_layer = gimp_layer_copy (layer, FALSE);
}
else
{
/* a non-layer drawable can't have an alpha channel,
* so add one
*/
PixelRegion srcPR, destPR;
TileManager *tiles;
tiles = tile_manager_new (width, height, bytes + 1);
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
0, 0, width, height, FALSE);
pixel_region_init (&destPR, tiles,
0, 0, width, height, TRUE);
add_alpha_region (&srcPR, &destPR);
new_layer =
gimp_layer_new_from_tiles (new_gimage,
gimp_image_base_type_with_alpha (new_gimage),
tiles,
"", OPAQUE_OPACITY, NORMAL_MODE);
tile_manager_destroy (tiles);
}
gimp_drawable_set_gimage (GIMP_DRAWABLE (new_layer), new_gimage);
gimp_object_set_name (GIMP_OBJECT (new_layer),
gimp_object_get_name (GIMP_OBJECT (drawable)));
if (layer)
{
GimpLayerMask *mask;
GimpLayerMask *new_mask;
mask = gimp_layer_get_mask (layer);
new_mask = gimp_layer_get_mask (new_layer);
if (new_mask)
{
gimp_object_set_name (GIMP_OBJECT (new_mask),
gimp_object_get_name (GIMP_OBJECT (mask)));
}
}
gimp_drawable_offsets (GIMP_DRAWABLE (new_layer), &off_x, &off_y);
gimp_layer_translate (new_layer, -off_x, -off_y);
gimp_image_add_layer (new_gimage, new_layer, 0);
gimp_context_set_display (gimp_context_get_user (),
gdisplay_new (new_gimage, 0x0101));
gimp_image_undo_enable (new_gimage);
return_val = TRUE;
}
gimp_image_set_resolution (new_gimage,
gimage->xresolution, gimage->yresolution);
gimp_image_set_unit (new_gimage, gimage->unit);