2 * dnd.c - These are generic functions which add Drag N' Drop support
5 * Copyright (C) 2000 Jos�é Antonio Caminero Granja
8 * Jos�é Antonio Caminero Granja <JCamGra@alumnos.uva.es>>
9 * Archit Baweja <bighead@crosswinds.net>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
38 * Table (array) of mime types for which "droppings" will be accepted.
40 static GtkTargetEntry dnd_mime_accepted
[DND_MAX_MIME_TYPES
];
43 * Number of entries in the mime type table for "droppings".
45 static int dnd_mime_table_length
= 0;
48 * A pointer to the user supplied function which handles the "droppings".
50 static void (* dnd_data_dropped
) (const gchar
*uri
, gpointer user_data
) = NULL
;
53 * Callback for the drag_data_received signal, emitted whenever something is
54 * dragged onto the widget.
57 drag_data_received_cb (GtkWidget
*widget
, GdkDragContext
*context
,
58 gint x
, gint y
, GtkSelectionData
*data
,
59 guint info
, guint time
, gpointer user_data
)
61 gchar
*current
, *current_end
/*, *current_fixed */;
62 /* gchar *hostname, *filename */;
65 * Check to see that we got the name of the file. Impossible that it is
68 g_return_if_fail (data
->data
!= NULL
);
70 current
= (gchar
*)data
->data
;
75 * get each file:path in buffer and process
77 current_end
= current
;
78 while (*current_end
&& *current_end
!= '\n') current_end
++;
80 /* remove the \r if necessary and end the string */
81 if (*current_end
== '\n' && current_end
!= current
&&
82 *(current_end
- 1) == '\r')
84 *(current_end
- 1) = '\0';
90 dnd_data_dropped (current
, user_data
);
92 filename = g_filename_from_uri (current, &hostname, NULL);
93 if (! filename && ! hostname)
95 // Some dumb software drops URI without "file:" in the begining
96 current_fixed = g_strconcat("file:", current, NULL);
97 filename = g_filename_from_uri (current, &hostname, NULL);
98 g_free (current_fixed);
105 g_warning (_("File %s is not local."), filename);
108 dnd_data_dropped (filename, user_data);
113 g_warning (_("Invalid filename %s."), current);
116 current
= current_end
+ 1;
123 * Initialize widget to start accepting "droppings" for the (NULL terminated)
124 * list of mime types.
127 dnd_drop_init (GtkWidget
*widget
,
128 void (* data_dropped
) (const gchar
*uri
, gpointer user_data
),
129 gpointer user_data
, ...)
135 * Defensive progamming at display! Check for NULL parameters.
137 g_return_if_fail (widget
!= NULL
);
138 g_return_if_fail (data_dropped
!= NULL
);
139 g_return_if_fail (dnd_data_dropped
== NULL
);
142 * Get all the mime types given by user and prepare the GtkTargetEntry
145 dnd_mime_table_length
= 0;
146 va_start (list
, user_data
);
147 while ((mime_type
= va_arg (list
, gchar
*)) != NULL
) {
148 g_assert (mime_type
!= NULL
);
149 g_assert (dnd_mime_table_length
< DND_MAX_MIME_TYPES
);
154 dnd_mime_accepted
[dnd_mime_table_length
].target
= mime_type
;
155 dnd_mime_accepted
[dnd_mime_table_length
].flags
= 0;
156 dnd_mime_accepted
[dnd_mime_table_length
].info
=
157 dnd_mime_table_length
;
158 dnd_mime_table_length
++;
163 * Assign the address of the user supplied function (which will handle
164 * the "droppings") to our own global pointer.
166 dnd_data_dropped
= *data_dropped
;
169 * Set the widget to start accepting "droppings" for the given mime
172 gtk_drag_dest_set (widget
, GTK_DEST_DEFAULT_ALL
, dnd_mime_accepted
,
173 dnd_mime_table_length
, GDK_ACTION_COPY
);
176 * Connect callback for the "drag_data_received" signal, emitted by the
177 * wigdet whenever a "drop" is made.
179 g_signal_connect (G_OBJECT (widget
), "drag_data_received",
180 G_CALLBACK (drag_data_received_cb
),
181 (gpointer
) user_data
);
186 dnd_drop_finalize (GtkWidget
*widget
, gpointer user_data
)
188 g_signal_handlers_disconnect_by_func (G_OBJECT (widget
),
189 G_CALLBACK (drag_data_received_cb
), user_data
);
190 dnd_data_dropped
= NULL
;