Commit 0bc3233b authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

app/widgets/Makefile.am new files.

2005-03-25  Sven Neumann  <sven@gimp.org>

	* app/widgets/Makefile.am
	* app/widgets/gimpdnd-xds.[ch]: new files.

	* app/widgets/gimpdnd.[ch]
	* app/widgets/widgets-enums.h: added a basic XDS (Direct Save
	Protocol) implementation.

	* app/widgets/gimpimageview.c: allow to save images by dragging
	them from the Images dialog to an XDS capable file manager.
parent 1c10caba
2005-03-25 Sven Neumann <sven@gimp.org>
* app/widgets/Makefile.am
* app/widgets/gimpdnd-xds.[ch]: new files.
* app/widgets/gimpdnd.[ch]
* app/widgets/widgets-enums.h: added a basic XDS (Direct Save
Protocol) implementation.
* app/widgets/gimpimageview.c: allow to save images by dragging
them from the Images dialog to an XDS capable file manager.
2005-03-25 Kevin Cozens <kcozens@cvs.gimp.org>
* plug-ins/common/displace.c: Fixed off-by-one error in check for
......
......@@ -108,6 +108,8 @@ libappwidgets_a_sources = \
gimpdialogfactory.h \
gimpdnd.c \
gimpdnd.h \
gimpdnd-xds.c \
gimpdnd-xds.h \
gimpdock.c \
gimpdock.h \
gimpdockable.c \
......
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "widgets-types.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "file/file-save.h"
#include "file/file-utils.h"
#include "gimpdnd-xds.h"
#include "gimp-intl.h"
/* Saving Files Via Drag-and-Drop:
* The Direct Save Protocol for the X Window System
*
* http://www.newplanetsoftware.com/xds/
* http://rox.sourceforge.net/xds.html
*/
#define MAX_URI_LEN 4096
void
gimp_dnd_xds_source_set (GdkDragContext *context,
GimpImage *image)
{
GdkAtom property;
gchar *filename;
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
property = gdk_atom_intern ("XdndDirectSave0", FALSE);
if (image && (filename = gimp_image_get_filename (image)))
{
GdkAtom type = gdk_atom_intern ("text/plain", FALSE);
gchar *basename = g_path_get_basename (filename);
gdk_property_change (context->source_window,
property, type, 8, GDK_PROP_MODE_REPLACE,
basename, strlen (basename));
g_free (basename);
g_free (filename);
}
else
{
gdk_property_delete (context->source_window, property);
}
}
void
gimp_dnd_xds_save_image (GdkDragContext *context,
GimpImage *image,
GtkSelectionData *selection,
GdkAtom atom)
{
PlugInProcDef *proc;
GdkAtom property = gdk_atom_intern ("XdndDirectSave0", FALSE);
GdkAtom type = gdk_atom_intern ("text/plain", FALSE);
gint length;
guchar *data;
gchar *uri;
GError *error = NULL;
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
g_return_if_fail (GIMP_IS_IMAGE (image));
if (! gdk_property_get (context->source_window, property, type,
0, MAX_URI_LEN, FALSE,
NULL, NULL, &length, &data))
return;
uri = g_strndup ((const gchar *) data, length);
g_free (data);
proc = file_utils_find_proc (image->gimp->save_procs, uri);
if (! proc)
proc = file_utils_find_proc (image->gimp->save_procs,
gimp_object_get_name (GIMP_OBJECT (image)));
if (proc)
{
if (file_save (image, gimp_get_user_context (image->gimp), NULL,
uri, proc, GIMP_RUN_INTERACTIVE, FALSE,
&error) == GIMP_PDB_SUCCESS)
{
gtk_selection_data_set (selection, atom, 8, "S", 1);
}
else
{
gtk_selection_data_set (selection, atom, 8, "F", 1);
if (error)
{
gchar *filename = file_utils_uri_to_utf8_filename (uri);
g_message (_("Saving '%s' failed:\n\n%s"),
filename, error->message);
g_free (filename);
g_error_free (error);
}
}
}
else
{
gtk_selection_data_set (selection, atom, 8, "F", 1);
g_message (_("The given filename does not have any known "
"file extension."));
}
g_free (uri);
gimp_dnd_xds_source_set (context, NULL);
}
/* The GIMP -- an image manipulation program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_DND_XDS_H__
#define __GIMP_DND_XDS_H__
void gimp_dnd_xds_source_set (GdkDragContext *context,
GimpImage *image);
void gimp_dnd_xds_save_image (GdkDragContext *context,
GimpImage *image,
GtkSelectionData *selection,
GdkAtom atom);
#endif /* __GIMP_DND_XDS_H__ */
......@@ -46,6 +46,7 @@
#include "vectors/gimpvectors.h"
#include "gimpdnd.h"
#include "gimpdnd-xds.h"
#include "gimpview.h"
#include "gimpselectiondata.h"
#include "gimpviewrendererimage.h"
......@@ -56,7 +57,7 @@
#define DRAG_PREVIEW_SIZE 32
#define DRAG_ICON_OFFSET -8
/* #define DEBUG_DND */
/* #define DEBUG_DND */
#ifdef DEBUG_DND
#define D(stmnt) stmnt
......@@ -69,6 +70,7 @@ typedef GtkWidget * (* GimpDndGetIconFunc) (GtkWidget *widget,
GCallback get_data_func,
gpointer get_data_data);
typedef void (* GimpDndDragDataFunc) (GtkWidget *widget,
GdkDragContext *context,
GCallback get_data_func,
gpointer get_data_data,
GtkSelectionData *selection,
......@@ -110,6 +112,7 @@ static GtkWidget * gimp_dnd_get_color_icon (GtkWidget *widget,
gpointer get_color_data);
static void gimp_dnd_get_uri_list_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_uri_list_func,
gpointer get_uri_list_data,
GtkSelectionData *selection,
......@@ -121,7 +124,15 @@ static gboolean gimp_dnd_set_uri_list_data (GtkWidget *widget,
gpointer set_uri_list_data,
GtkSelectionData *selection);
static void gimp_dnd_get_xds_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_image_func,
gpointer get_image_data,
GtkSelectionData *selection,
GdkAtom atom);
static void gimp_dnd_get_color_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_color_func,
gpointer get_color_data,
GtkSelectionData *selection,
......@@ -134,6 +145,7 @@ static gboolean gimp_dnd_set_color_data (GtkWidget *widget,
GtkSelectionData *selection);
static void gimp_dnd_get_stream_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_stream_func,
gpointer get_stream_data,
GtkSelectionData *selection,
......@@ -146,6 +158,7 @@ static gboolean gimp_dnd_set_stream_data (GtkWidget *widget,
GtkSelectionData *selection);
static void gimp_dnd_get_component_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_comp_func,
gpointer get_comp_data,
GtkSelectionData *selection,
......@@ -158,6 +171,7 @@ static gboolean gimp_dnd_set_component_data (GtkWidget *widget,
GtkSelectionData *selection);
static void gimp_dnd_get_image_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_image_func,
gpointer get_image_data,
GtkSelectionData *selection,
......@@ -170,6 +184,7 @@ static gboolean gimp_dnd_set_image_data (GtkWidget *widget,
GtkSelectionData *selection);
static void gimp_dnd_get_item_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_item_func,
gpointer get_item_data,
GtkSelectionData *selection,
......@@ -182,6 +197,7 @@ static gboolean gimp_dnd_set_item_data (GtkWidget *widget,
GtkSelectionData *selection);
static void gimp_dnd_get_data_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_data_func,
gpointer get_data_data,
GtkSelectionData *selection,
......@@ -299,6 +315,20 @@ static GimpDndDataDef dnd_data_defs[] =
gimp_dnd_set_uri_list_data
},
{
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
},
{
GIMP_TARGET_COLOR,
......@@ -612,6 +642,8 @@ gimp_dnd_data_drag_begin (GtkWidget *widget,
data_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gimp-dnd-get-data-type"));
D (g_print ("\ngimp_dnd_data_drag_begin (%d)\n", data_type));
if (! data_type)
return;
......@@ -665,6 +697,8 @@ gimp_dnd_data_drag_end (GtkWidget *widget,
{
GtkWidget *icon_widget;
D (g_print ("\ngimp_dnd_data_drag_end\n"));
icon_widget = g_object_get_data (G_OBJECT (widget), "gimp-dnd-data-widget");
if (icon_widget)
......@@ -722,6 +756,7 @@ gimp_dnd_data_drag_handle (GtkWidget *widget,
atom = gdk_atom_intern (dnd_data->target_entry.target, FALSE);
dnd_data->get_data_func (widget,
context,
get_data_func,
get_data_data,
selection_data,
......@@ -981,6 +1016,7 @@ gimp_dnd_data_dest_remove (GimpDndType data_type,
static void
gimp_dnd_get_uri_list_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_uri_list_func,
gpointer get_uri_list_data,
GtkSelectionData *selection,
......@@ -1080,6 +1116,95 @@ gimp_dnd_uri_list_dest_remove (GtkWidget *widget)
}
/******************************/
/* Direct Save Protocol (XDS) */
/******************************/
static void
gimp_dnd_get_xds_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_image_func,
gpointer get_image_data,
GtkSelectionData *selection,
GdkAtom atom)
{
GimpImage *image;
image = (GimpImage *)
(* (GimpDndDragViewableFunc) get_image_func) (widget, get_image_data);
if (image)
gimp_dnd_xds_save_image (context, image, selection, atom);
}
static void
gimp_dnd_xds_drag_begin (GtkWidget *widget,
GdkDragContext *context,
gpointer data)
{
GimpDndDataDef *dnd_data = dnd_data_defs + GIMP_DND_TYPE_XDS;
GCallback get_data_func;
gpointer get_data_data;
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)
{
GimpImage *image = (GimpImage *)
(* (GimpDndDragViewableFunc) get_data_func) (widget, get_data_data);
gimp_dnd_xds_source_set (context, image);
}
}
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)
{
handler = g_signal_connect (widget, "drag_begin",
G_CALLBACK (gimp_dnd_xds_drag_begin),
NULL);
g_object_set_data (G_OBJECT (widget), "gimp-dnd-xds-drag-begin",
GUINT_TO_POINTER (handler));
}
}
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);
}
gimp_dnd_data_source_remove (GIMP_DND_TYPE_XDS, widget);
}
/*************************/
/* color dnd functions */
/*************************/
......@@ -1102,6 +1227,7 @@ gimp_dnd_get_color_icon (GtkWidget *widget,
static void
gimp_dnd_get_color_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_color_func,
gpointer get_color_data,
GtkSelectionData *selection,
......@@ -1180,6 +1306,7 @@ gimp_dnd_color_dest_remove (GtkWidget *widget)
static void
gimp_dnd_get_stream_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_stream_func,
gpointer get_stream_data,
GtkSelectionData *selection,
......@@ -1298,6 +1425,7 @@ gimp_dnd_get_component_icon (GtkWidget *widget,
static void
gimp_dnd_get_component_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_comp_func,
gpointer get_comp_data,
GtkSelectionData *selection,
......@@ -1631,6 +1759,7 @@ gimp_dnd_get_drag_data (GtkWidget *widget)
static void
gimp_dnd_get_image_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_image_func,
gpointer get_image_data,
GtkSelectionData *selection,
......@@ -1672,6 +1801,7 @@ gimp_dnd_set_image_data (GtkWidget *widget,
static void
gimp_dnd_get_item_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_item_func,
gpointer get_item_data,
GtkSelectionData *selection,
......@@ -1713,6 +1843,7 @@ gimp_dnd_set_item_data (GtkWidget *widget,
static void
gimp_dnd_get_data_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_data_func,
gpointer get_data_data,
GtkSelectionData *selection,
......
......@@ -29,6 +29,9 @@
#define GIMP_TARGET_NETSCAPE_URL \
{ "_NETSCAPE_URL", 0, GIMP_DND_TYPE_NETSCAPE_URL }
#define GIMP_TARGET_XDS \
{ "XdndDirectSave0", 0, GIMP_DND_TYPE_XDS }
#define GIMP_TARGET_COLOR \
{ "application/x-color", 0, GIMP_DND_TYPE_COLOR }
......@@ -95,7 +98,7 @@
void gimp_dnd_init (Gimp *gimp);
/* uri list dnd functions */
/* uri list dnd functions */
typedef GList * (* GimpDndDragUriListFunc) (GtkWidget *widget,
gpointer data);
......@@ -221,4 +224,12 @@ gboolean gimp_dnd_viewable_dest_remove (GtkWidget *widget,
GimpViewable * gimp_dnd_get_drag_data (GtkWidget *widget);
/* Direct Save Protocol (XDS) */
void gimp_dnd_xds_source_add (GtkWidget *widget,
GimpDndDragViewableFunc get_image_func,
gpointer data);
void gimp_dnd_xds_source_remove (GtkWidget *widget);
#endif /* __GIMP_DND_H__ */
......@@ -45,6 +45,9 @@ static void gimp_image_view_init (GimpImageView *view);
static void gimp_image_view_activate_item (GimpContainerEditor *editor,
GimpViewable *viewable);
static const gchar * gimp_image_view_drag_xds (GtkWidget *widget,
gpointer data);
static GimpContainerEditorClass *parent_class = NULL;
......@@ -133,6 +136,17 @@ gimp_image_view_new (GimpViewType view_type,
gimp_editor_add_action_button (GIMP_EDITOR (editor->view), "images",
"images-delete", NULL);
if (view_type == GIMP_VIEW_TYPE_LIST)
{
GtkWidget *dnd_widget;
dnd_widget = gimp_container_view_get_dnd_widget (editor->view);
gimp_dnd_xds_source_add (dnd_widget,
(GimpDndDragViewableFunc) gimp_dnd_get_drag_data,
NULL);
}
gimp_container_view_enable_dnd (editor->view,
GTK_BUTTON (image_view->raise_button),
GIMP_TYPE_IMAGE);
......
......@@ -192,26 +192,27 @@ typedef enum /*< skip >*/
GIMP_DND_TYPE_URI_LIST = 1,
GIMP_DND_TYPE_TEXT_PLAIN = 2,
GIMP_DND_TYPE_NETSCAPE_URL = 3,
GIMP_DND_TYPE_COLOR = 4,
GIMP_DND_TYPE_PNG = 5,
GIMP_DND_TYPE_SVG = 6,
GIMP_DND_TYPE_SVG_XML = 7,
GIMP_DND_TYPE_IMAGE = 8,
GIMP_DND_TYPE_COMPONENT = 9,
GIMP_DND_TYPE_LAYER = 10,
GIMP_DND_TYPE_CHANNEL = 11,
GIMP_DND_TYPE_LAYER_MASK = 12,
GIMP_DND_TYPE_VECTORS = 13,
GIMP_DND_TYPE_BRUSH = 14,
GIMP_DND_TYPE_PATTERN = 15,
GIMP_DND_TYPE_GRADIENT = 16,
GIMP_DND_TYPE_PALETTE = 17,
GIMP_DND_TYPE_FONT = 18,
GIMP_DND_TYPE_BUFFER = 19,
GIMP_DND_TYPE_IMAGEFILE = 20,
GIMP_DND_TYPE_TEMPLATE = 21,
GIMP_DND_TYPE_TOOL = 22,
GIMP_DND_TYPE_DIALOG = 23,
GIMP_DND_TYPE_XDS = 4,
GIMP_DND_TYPE_COLOR = 5,
GIMP_DND_TYPE_PNG = 6,
GIMP_DND_TYPE_SVG = 7,
GIMP_DND_TYPE_SVG_XML = 8,
GIMP_DND_TYPE_IMAGE = 9,
GIMP_DND_TYPE_COMPONENT = 10,
GIMP_DND_TYPE_LAYER = 11,
GIMP_DND_TYPE_CHANNEL = 12,
GIMP_DND_TYPE_LAYER_MASK = 13,
GIMP_DND_TYPE_VECTORS = 14,
GIMP_DND_TYPE_BRUSH = 15,
GIMP_DND_TYPE_PATTERN = 16,
GIMP_DND_TYPE_GRADIENT = 17,
GIMP_DND_TYPE_PALETTE = 18,
GIMP_DND_TYPE_FONT = 19,
GIMP_DND_TYPE_BUFFER = 20,
GIMP_DND_TYPE_IMAGEFILE = 21,
GIMP_DND_TYPE_TEMPLATE = 22,
GIMP_DND_TYPE_TOOL = 23,
GIMP_DND_TYPE_DIALOG = 24,
GIMP_DND_TYPE_LAST = GIMP_DND_TYPE_DIALOG
} GimpDndType;
......
......@@ -321,6 +321,7 @@ app/widgets/gimpdataeditor.c
app/widgets/gimpdevices.c
app/widgets/gimpdevicestatus.c
app/widgets/gimpdnd.c
app/widgets/gimpdnd-xds.c
app/widgets/gimpdock.c
app/widgets/gimpdockable.c
app/widgets/gimpdocumentview.c
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment