1999-02-03 Federico Mena Quintero <federico@nuclecu.unam.mx>

* gdnd.c (gdnd_validate_action): Added an "on_desktop" argument;
	this specifies that the user is dragging over the desktop.  Added
	cases for drags of desktop icons and URLs.
	(gdnd_perform_drop): New public function to handle drops.  This is
	now the master function to handle drops -- use this to make all of
	MC consistent.
	(drop_on_directory): Made static and renamed from
	gdnd_drop_on_directory().  Made it fit for use by
	gdnd_perform_drop().
	(drop_url_on_directory): New function to drop an url on a
	directory, moved over from gdesktop.c.
	(drop_uri_list_on_directory): New function to handle drops of URI
	lists on a directory.
	(drop_on_file): New function to handle drops on a non-directory
	file entry.  This is moved over from gdesktop.c,
	desktop_icon_drop_uri_list().  This is yet to be finished.

	* gdesktop.c (desktop_icon_drop_uri_list): Fix memory leak.
	(desktop_drag_motion): Use gdnd_validate_action().
	(dnd_icon_targets): Allow dropping URLs on icons.
	(icon_drag_motion): Use gdnd_validate_action().
	(desktop_drag_data_received): Use gdnd_perform_drop().
	(icon_drag_data_received): Use gdnd_perform_drop().

	* gscreen.c (panel_icon_list_drag_data_received): Use
	gdnd_perform_drop().
	(panel_clist_drag_data_received): Use gdnd_perform_drop().
	(panel_tree_drag_data_received): Use gdnd_perform_drop().

	* gcmd.c (gnome_about_cmd): Fixed Foundation typo, and updated the
	copyright date.
This commit is contained in:
Miguel de Icaza 1999-02-03 11:46:01 +00:00
parent 89204b8f1c
commit 04c4abd818
5 changed files with 370 additions and 302 deletions

View File

@ -1,3 +1,37 @@
1999-02-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdnd.c (gdnd_validate_action): Added an "on_desktop" argument;
this specifies that the user is dragging over the desktop. Added
cases for drags of desktop icons and URLs.
(gdnd_perform_drop): New public function to handle drops. This is
now the master function to handle drops -- use this to make all of
MC consistent.
(drop_on_directory): Made static and renamed from
gdnd_drop_on_directory(). Made it fit for use by
gdnd_perform_drop().
(drop_url_on_directory): New function to drop an url on a
directory, moved over from gdesktop.c.
(drop_uri_list_on_directory): New function to handle drops of URI
lists on a directory.
(drop_on_file): New function to handle drops on a non-directory
file entry. This is moved over from gdesktop.c,
desktop_icon_drop_uri_list(). This is yet to be finished.
* gdesktop.c (desktop_icon_drop_uri_list): Fix memory leak.
(desktop_drag_motion): Use gdnd_validate_action().
(dnd_icon_targets): Allow dropping URLs on icons.
(icon_drag_motion): Use gdnd_validate_action().
(desktop_drag_data_received): Use gdnd_perform_drop().
(icon_drag_data_received): Use gdnd_perform_drop().
* gscreen.c (panel_icon_list_drag_data_received): Use
gdnd_perform_drop().
(panel_clist_drag_data_received): Use gdnd_perform_drop().
(panel_tree_drag_data_received): Use gdnd_perform_drop().
* gcmd.c (gnome_about_cmd): Fixed Foundation typo, and updated the
copyright date.
1999-02-02 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gnome-file-property-dialog.c (create_general_properties): Use

View File

@ -73,6 +73,7 @@ static GtkTargetEntry dnd_icon_sources[] = {
static GtkTargetEntry dnd_icon_targets[] = {
{ TARGET_MC_DESKTOP_ICON_TYPE, 0, TARGET_MC_DESKTOP_ICON },
{ TARGET_URI_LIST_TYPE, 0, TARGET_URI_LIST },
{ TARGET_URL_TYPE, 0, TARGET_URL }
};
static GtkTargetEntry dnd_desktop_targets[] = {
@ -1163,8 +1164,7 @@ setup_icon_dnd_source (DesktopIconInfo *dii)
dii);
}
/*
* Callback used when we get a drag_motion event from a desktop icon. We have
/* Callback used when we get a drag_motion event from a desktop icon. We have
* to decide which operation to perform based on the type of the data the user
* is dragging.
*/
@ -1176,27 +1176,25 @@ icon_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
char *filename;
file_entry *fe;
GdkDragAction action;
GtkWidget *source_widget;
int is_desktop_icon;
dii = data;
filename = g_concat_dir_and_file (desktop_directory, dii->filename);
fe = file_entry_from_file (filename);
g_free (filename);
if (!fe)
return 0; /* eeek */
action = 0; /* be pessimistic by defaulting to nothing */
gdnd_find_panel_by_drag_context (context, &source_widget);
is_desktop_icon = gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON);
if (dii->selected
&& gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON)
&& (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
else if (gdnd_drag_context_has_target (context, TARGET_URI_LIST)) {
if (S_ISDIR (fe->buf.st_mode) || fe->f.link_to_dir)
action = context->suggested_action;
else if (is_exe (fe->buf.st_mode)
&& if_link_is_exe (fe)
&& (context->actions & GDK_ACTION_COPY))
action = GDK_ACTION_COPY;
}
action = gdnd_validate_action (context,
TRUE,
source_widget != NULL,
source_widget && is_desktop_icon,
fe,
dii->selected);
gdk_drag_status (context, action, time);
return TRUE;
@ -1245,11 +1243,6 @@ drop_desktop_icons (GdkDragContext *context, GtkSelectionData *data, int x, int
GList *l;
GSList *sel_icons, *sl;
/*
* FIXME: this needs to do the right thing (what Windows does)
* when desktop_auto_placement is enabled.
*/
/* Find the icon that the user is dragging */
source_dii = find_icon_by_drag_context (context);
@ -1292,94 +1285,6 @@ drop_desktop_icons (GdkDragContext *context, GtkSelectionData *data, int x, int
g_slist_free (sel_icons);
}
/**
* drop_on_file_entry
*/
static void
desktop_icon_drop_uri_list (DesktopIconInfo *dii, GdkDragContext *context, GtkSelectionData *data)
{
char *filename;
file_entry *fe;
int size;
char *buf;
const char *mime_type;
filename = g_concat_dir_and_file (desktop_directory, dii->filename);
fe = file_entry_from_file (filename);
if (!fe)
return; /* eek */
/* 1. If it is a directory, drop the files there */
if (fe->f.link_to_dir) {
gdnd_drop_on_directory (context, data, filename);
goto out;
}
/* 2. Try to use a metadata-based drop action */
if (gnome_metadata_get (filename, "drop-action", &size, &buf) == 0) {
/*action_drop (filename, buf, context, data);*/ /* Fixme: i'm undefined */
g_free (buf);
goto out;
}
/* 3. Try a drop action from the mime-type */
mime_type = gnome_mime_type_or_default (filename, NULL);
if (mime_type) {
char *action;
action = gnome_mime_get_value (mime_type, "drop-action");
if (action) {
/*action_drop (filename, action, context, data);*/ /* Fixme: i'm undefined */
goto out;
}
}
/* 4. Executable. Try metadata keys for "open" */
if (is_exe (fe->buf.st_mode) && if_link_is_exe (fe)) {
GList *names, *l;
int len, i;
char **drops;
/* Convert the list of filenames into an array of char */
names = gnome_uri_list_extract_uris (data->data);
len = g_list_length (names);
drops = (char **) g_malloc (sizeof (char *) * (len+1));
for (l = names, i = 0; i < len; i++, l = l->next) {
char *text = l->data;
if (strncmp (text, "file:", 5) == 0)
text += 5;
drops [i] = text;
}
drops [i] = NULL;
if (gnome_metadata_get (filename, "open", &size, &buf) == 0) {
exec_extension (filename, buf, drops, NULL, 0);
goto out2;
}
exec_extension (filename, "%f %q", drops, NULL, 0);
g_free (drops);
out2:
gnome_uri_list_free_strings (names);
g_free (buf);
}
out:
file_entry_free (fe);
}
static void
icon_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *data, guint info, guint time, gpointer user_data)
@ -1388,22 +1293,21 @@ icon_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gin
dii = user_data;
switch (info) {
case TARGET_MC_DESKTOP_ICON:
if (dii->selected)
drop_desktop_icons (context, data, x + dii->x, y + dii->y);
else
printf ("FIXME: what do drop?\n"); /* FIXME */
if (gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON) && dii->selected)
drop_desktop_icons (context, data, x + dii->x, y + dii->y);
else {
char *full_name;
file_entry *fe;
break;
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
fe = file_entry_from_file (full_name);
if (!fe)
return; /* eeeek */
case TARGET_URI_LIST:
printf ("Wheeeeee!\n");
desktop_icon_drop_uri_list (dii, context, data);
break;
if (gdnd_perform_drop (context, data, fe, full_name))
reload_desktop_icons (TRUE, x, y);
default:
break;
file_entry_free (fe);
}
}
@ -1727,73 +1631,27 @@ desktop_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
{
GdkDragAction action;
GtkWidget *source_widget;
int is_desktop_icon;
action = context->suggested_action; /* this is the default */
gdnd_find_panel_by_drag_context (context, &source_widget);
is_desktop_icon = gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON);
if (gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON))
action = GDK_ACTION_MOVE;
else if (gdnd_drag_context_has_target (context, TARGET_URI_LIST)) {
source_widget = gtk_drag_get_source_widget (context);
/* If it comes from ourselves, make move the default unless the
* user is explicitly asking for ASK.
*/
if (source_widget
&& context->suggested_action != GDK_ACTION_ASK
&& (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
} else if (gdnd_drag_context_has_target (context, TARGET_URL)) {
/* FIXME: right now we only allow links. We should see if we
* can move or copy stuff instead (for ftp instead of http
* sites, for example).
*/
if (context->actions & GDK_ACTION_LINK)
action = GDK_ACTION_LINK;
else
action = 0;
} else
action = 0; /* we cannot handle that type of data */
action = gdnd_validate_action (context,
TRUE,
source_widget != NULL,
source_widget && is_desktop_icon,
NULL,
FALSE);
gdk_drag_status (context, action, time);
return TRUE;
}
/*
* drop_url: Invoked when we have received an URL from Netscape.
* Install the url on the ~/desktop directory
*/
static void
drop_url (GdkDragContext *context, GtkSelectionData *data, gint x, gint y)
{
char *template;
template = g_concat_dir_and_file (desktop_directory, "urlXXXXXX");
if (mktemp (template)) {
FILE *f;
f = fopen (template, "w");
if (f){
fprintf (f, "URL: %s\n", data->data);
fclose (f);
gnome_metadata_set (template, "desktop-url",
strlen (data->data) + 1,
data->data);
reload_desktop_icons (TRUE, x, y);
}
}
g_free (template);
}
/* Callback used when the root window receives a drop */
static void
desktop_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *data, guint info, guint time, gpointer user_data)
{
int retval;
gint dx, dy;
/* Fix the proxy window offsets */
@ -1802,23 +1660,19 @@ desktop_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x,
x += dx;
y += dy;
switch (info) {
case TARGET_MC_DESKTOP_ICON:
if (gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON))
drop_desktop_icons (context, data, x, y);
break;
else {
file_entry *desktop_fe;
case TARGET_URI_LIST:
retval = gdnd_drop_on_directory (context, data, desktop_directory);
if (retval)
desktop_fe = file_entry_from_file (desktop_directory);
if (!desktop_fe)
return; /* eeek */
if (gdnd_perform_drop (context, data, desktop_fe, desktop_directory))
reload_desktop_icons (TRUE, x, y);
break;
case TARGET_URL:
drop_url (context, data, x, y);
break;
default:
break;
file_entry_free (desktop_fe);
}
}
@ -1984,11 +1838,6 @@ icon_is_in_area (DesktopIconInfo *dii, int x1, int y1, int x2, int y2)
dicon = DESKTOP_ICON (dii->dicon);
/* FIXME: this only intersects the rectangle with the icon image's
* bounds. Doing the "hard" intersection with the actual shape of the
* image is left as an exercise to the reader.
*/
x1 -= dii->x;
y1 -= dii->y;
x2 -= dii->x;

View File

@ -13,6 +13,7 @@
#include "fileopctx.h"
#include "main.h"
#include "panel.h"
#include "ext.h"
#include "gscreen.h"
#include "../vfs/vfs.h"
#include <gdk/gdkprivate.h>
@ -96,21 +97,20 @@ get_action (GdkDragContext *context)
return action;
}
/*
* Performs a drop action on the specified panel. Only supports copy
* and move operations. The files are moved or copied to the
* specified destination directory.
/* Performs a drop action on the specified panel. Only supports copy and move
* operations. The files are moved or copied to the specified destination
* directory.
*/
static void
perform_action_on_panel (WPanel *source_panel, GdkDragAction action, char *destdir, int ask)
perform_action_on_panel (WPanel *source_panel, GdkDragAction action, char *destdir)
{
switch (action) {
case GDK_ACTION_COPY:
panel_operate (source_panel, OP_COPY, destdir, ask);
panel_operate (source_panel, OP_COPY, destdir, FALSE);
break;
case GDK_ACTION_MOVE:
panel_operate (source_panel, OP_MOVE, destdir, ask);
panel_operate (source_panel, OP_MOVE, destdir, FALSE);
break;
default:
@ -146,11 +146,10 @@ perform_links (GList *names, char *destdir)
}
}
/*
* Performs a drop action manually, by going through the list of files
* to operate on. The files are copied or moved to the specified
* directory. This should also encompass symlinking when the file
* operations window supports links.
/* Performs a drop action manually, by going through the list of files to
* operate on. The files are copied or moved to the specified directory. This
* should also encompass symlinking when the file operations window supports
* links.
*/
static void
perform_action (GList *names, GdkDragAction action, char *destdir)
@ -226,46 +225,24 @@ perform_action (GList *names, GdkDragAction action, char *destdir)
file_op_context_destroy (ctx);
}
/**
* gdnd_drop_on_directory:
* @context: The drag context received from the drag_data_received callback
* @selection_data: The selection data from the drag_data_received callback
* @dirname: The name of the directory to drop onto
*
* Extracts an URI list from the selection data and drops all the files in the
* specified directory.
*
* Return Value: TRUE if the drop was sucessful, FALSE if it was not.
**/
int
gdnd_drop_on_directory (GdkDragContext *context, GtkSelectionData *selection_data, char *destdir)
/* Drop a URI list on a directory. If the data comes from a panel, use the nice
* MC progress display; otherwise `do it by hand'.
*/
static void
drop_uri_list_on_directory (GdkDragContext *context, GtkSelectionData *selection_data,
GdkDragAction action, char *destdir)
{
GdkDragAction action;
WPanel *source_panel;
GtkWidget *source_widget;
GList *names;
if (context->action == GDK_ACTION_ASK) {
action = get_action (context);
if (action == GDK_ACTION_ASK)
return FALSE;
} else
action = context->action;
/* If we are dragging from a file panel, we can display a nicer status
* display. But if the drag was from the tree, we cannot do this.
*/
source_panel = gdnd_find_panel_by_drag_context (context, &source_widget);
if (source_widget == source_panel->tree)
source_panel = NULL;
/* Symlinks do not use file.c */
if (source_panel && action != GDK_ACTION_LINK)
perform_action_on_panel (source_panel, action, destdir,
context->action == GDK_ACTION_ASK);
/* We cannot use file.c if we are going to symlink or if we are dragging
* from a tree.
*/
if (source_panel && source_widget != source_panel->tree && action != GDK_ACTION_LINK)
perform_action_on_panel (source_panel, action, destdir);
else {
names = gnome_uri_list_extract_uris (selection_data->data);
@ -276,10 +253,153 @@ gdnd_drop_on_directory (GdkDragContext *context, GtkSelectionData *selection_dat
gnome_uri_list_free_strings (names);
}
}
/* Drop a Netscape URL in a directory */
static void
drop_url_on_directory (GdkDragContext *context, GtkSelectionData *selection_data, char *destdir)
{
char *template;
template = g_concat_dir_and_file (destdir, "urlXXXXXX");
if (mktemp (template)) {
FILE *f;
f = fopen (template, "w");
if (f) {
fprintf (f, "URL: %s\n", selection_data->data);
fclose (f);
gnome_metadata_set (template, "desktop-url",
strlen (selection_data->data) + 1,
selection_data->data);
}
}
g_free (template);
}
/* Drop stuff on a directory */
static int
drop_on_directory (GdkDragContext *context, GtkSelectionData *selection_data, char *destdir)
{
GdkDragAction action;
if (context->action == GDK_ACTION_ASK) {
action = get_action (context);
if (action == GDK_ACTION_ASK)
return FALSE;
} else
action = context->action;
if (gdnd_drag_context_has_target (context, TARGET_URI_LIST))
drop_uri_list_on_directory (context, selection_data, action, destdir);
else if (gdnd_drag_context_has_target (context, TARGET_URL))
drop_url_on_directory (context, selection_data, destdir);
else
return FALSE;
return TRUE;
}
/* Drop stuff on a non-directory file. This uses metadata and MIME as well. */
static int
drop_on_file (GdkDragContext *context, GtkSelectionData *selection_data,
file_entry *dest_fe, char *dest_name)
{
int size;
char *buf;
const char *mime_type;
/* 1. Try to use a metadata-based drop action */
if (gnome_metadata_get (dest_name, "drop-action", &size, &buf) == 0) {
/*action_drop (dest_name, buf, context, selection_data);*/ /* Fixme: i'm undefined */
g_free (buf);
return TRUE;
}
/* 2. Try a drop action from the MIME-type */
mime_type = gnome_mime_type_or_default (dest_name, NULL);
if (mime_type) {
char *action;
action = gnome_mime_get_value (mime_type, "drop-action");
if (action) {
/* Fixme: i'm undefined */
/*action_drop (dest_name, action, context, selection_data);*/
return TRUE;
}
}
/* 3. If executable, try metadata keys for "open" */
if (is_exe (dest_fe->buf.st_mode) && if_link_is_exe (dest_fe)) {
GList *names, *l;
int len, i;
char **drops;
/* FIXME: handle the case for Netscape URLs */
/* Convert the data list into an array of strings */
names = gnome_uri_list_extract_uris (selection_data->data);
len = g_list_length (names);
drops = g_new (char *, len + 1);
for (l = names, i = 0; i < len; i++, l = l->next) {
char *text = l->data;
if (strncmp (text, "file:", 5) == 0)
text += 5;
drops[i] = text;
}
drops[i] = NULL;
if (gnome_metadata_get (dest_name, "open", &size, &buf) == 0)
exec_extension (dest_name, buf, drops, NULL, 0);
else
exec_extension (dest_name, "%f %q", drops, NULL, 0);
g_free (drops);
gnome_uri_list_free_strings (names);
g_free (buf);
return TRUE;
}
return FALSE; /* could not drop */
}
int
gdnd_perform_drop (GdkDragContext *context, GtkSelectionData *selection_data,
file_entry *dest_fe, char *dest_name)
{
GdkDragAction action;
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (selection_data != NULL, FALSE);
g_return_val_if_fail (dest_fe != NULL, FALSE);
/* Get action */
if (context->action == GDK_ACTION_ASK) {
action = get_action (context);
if (action == GDK_ACTION_ASK)
return FALSE;
} else
action = context->action;
if (S_ISDIR (dest_fe->buf.st_mode) || dest_fe->f.link_to_dir)
return drop_on_directory (context, selection_data, dest_name);
else
return drop_on_file (context, selection_data, dest_fe, dest_name);
}
/**
* gdnd_drag_context_has_target:
* @context: The context to query for a target type
@ -348,6 +468,7 @@ gdnd_find_panel_by_drag_context (GdkDragContext *context, GtkWidget **source_wid
/**
* gdnd_validate_action:
* @context: The drag context for this drag operation.
* @on_desktop: Whether we are dragging onto the desktop or a desktop icon.
* @same_process: Whether the drag comes from the same process or not.
* @same_source: If same_process, then whether the source and dest widgets are the same.
* @dest: The destination file entry, or NULL if dropping on empty space.
@ -359,48 +480,70 @@ gdnd_find_panel_by_drag_context (GdkDragContext *context, GtkWidget **source_wid
* Return value: The computed action, meant to be passed to gdk_drag_action().
**/
GdkDragAction
gdnd_validate_action (GdkDragContext *context, int same_process, int same_source,
gdnd_validate_action (GdkDragContext *context,
int on_desktop, int same_process, int same_source,
file_entry *dest_fe, int dest_selected)
{
int on_directory;
int on_exe;
if (dest_fe) {
on_directory = dest_fe->f.link_to_dir || S_ISDIR (dest_fe->buf.st_mode);
on_exe = is_exe (dest_fe->buf.st_mode) && if_link_is_exe (dest_fe);
}
g_return_val_if_fail (context != NULL, 0);
if (dest_fe) {
if (same_source && dest_selected)
return 0;
/* If we are dragging a desktop icon onto the desktop or onto a selected
* desktop icon, unconditionally specify MOVE.
*/
if (on_desktop
&& gdnd_drag_context_has_target (context, TARGET_MC_DESKTOP_ICON)
&& (!dest_fe || dest_selected))
return GDK_ACTION_MOVE;
if (on_directory) {
if ((same_source || same_process)
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
if (gdnd_drag_context_has_target (context, TARGET_URI_LIST)) {
if (dest_fe) {
on_directory = S_ISDIR (dest_fe->buf.st_mode) || dest_fe->f.link_to_dir;
on_exe = is_exe (dest_fe->buf.st_mode) && if_link_is_exe (dest_fe);
}
if (dest_fe) {
if (same_source && dest_selected)
return 0;
if (on_directory) {
if ((same_source || same_process)
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
return GDK_ACTION_MOVE;
else
return context->suggested_action;
} else if (on_exe) {
if (context->actions & GDK_ACTION_COPY)
return GDK_ACTION_COPY;
} else if (same_source)
return 0;
else if (same_process
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
return GDK_ACTION_MOVE;
else
return context->suggested_action;
} else if (on_exe) {
if (context->actions & GDK_ACTION_COPY)
return GDK_ACTION_COPY;
} else if (same_source)
return 0;
else if (same_process
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
return GDK_ACTION_MOVE;
else
return context->suggested_action;
} else {
if (same_source)
return 0;
else if (same_process
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
return GDK_ACTION_MOVE;
else
return context->suggested_action;
} else {
if (same_source)
return 0;
else if (same_process
&& (context->actions & GDK_ACTION_MOVE)
&& context->suggested_action != GDK_ACTION_ASK)
return GDK_ACTION_MOVE;
else
return context->suggested_action;
}
}
if (gdnd_drag_context_has_target (context, TARGET_URL)) {
/* FIXME: right now we only allow links. We should see if we
* can move or copy stuff instead (for ftp instead of http
* sites, for example).
*/
if (context->actions & GDK_ACTION_LINK)
return GDK_ACTION_LINK;
}
return 0;

View File

@ -35,8 +35,12 @@ extern GdkAtom dnd_target_atoms[];
/* Initializes drag and drop by interning the target convenience atoms */
void gdnd_init (void);
/* Drop the list of URIs in the selection data to the specified directory */
int gdnd_drop_on_directory (GdkDragContext *context, GtkSelectionData *selection_data, char *dirname);
/* Perform a drop on the specified file entry. This function takes care of
* determining how to drop the stuff epending on the type of the file entry.
* Returns TRUE if an action was performed, FALSE otherwise (i.e. invalid drop).
*/
int gdnd_perform_drop (GdkDragContext *context, GtkSelectionData *selection_data,
file_entry *dest_fe, char *dest_name);
/* Test whether the specified context has a certain target type */
int gdnd_drag_context_has_target (GdkDragContext *context, TargetType type);
@ -47,7 +51,8 @@ WPanel *gdnd_find_panel_by_drag_context (GdkDragContext *context, GtkWidget **so
/* Computes the final drag action based on the suggested actions and the
* specified conditions.
*/
GdkDragAction gdnd_validate_action (GdkDragContext *context, int same_process, int same_source,
GdkDragAction gdnd_validate_action (GdkDragContext *context,
int on_desktop, int same_process, int same_source,
file_entry *dest_fe, int dest_selected);

View File

@ -776,25 +776,38 @@ panel_icon_list_drag_data_received (GtkWidget *widget,
WPanel *panel)
{
GnomeIconList *gil = GNOME_ICON_LIST (widget);
char *dir;
file_entry *fe;
char *file;
int free_file, free_fe;
int idx;
gboolean reload;
idx = gnome_icon_list_get_icon_at (gil, x, y);
if (idx == -1)
dir = g_strdup (panel->cwd);
else {
if (panel->dir.list [idx].f.link_to_dir ||
S_ISDIR (panel->dir.list [idx].buf.st_mode))
dir = concat_dir_and_file (panel->cwd, panel->dir.list [idx].fname);
else
dir = g_strdup (panel->cwd);
if (idx == -1) {
file = panel->cwd;
fe = file_entry_from_file (file);
if (!fe)
return; /* eeeek */
free_file = FALSE;
free_fe = TRUE;
} else {
file = g_concat_dir_and_file (panel->cwd, panel->dir.list[idx].fname);
fe = &panel->dir.list[idx];
free_file = TRUE;
free_fe = FALSE;
}
reload = gdnd_drop_on_directory (context, selection_data, dir);
g_free (dir);
reload = gdnd_perform_drop (context, selection_data, fe, file);
if (reload){
if (free_file)
g_free (file);
if (free_fe)
file_entry_free (fe);
if (reload) {
update_one_panel_widget (panel, 0, UP_KEEPSEL);
panel_update_contents (panel);
}
@ -817,26 +830,42 @@ panel_clist_drag_data_received (GtkWidget *widget,
WPanel *panel)
{
GtkCList *clist = GTK_CLIST (widget);
char *dir;
file_entry *fe;
char *file;
int free_file, free_fe;
int row;
int reload;
if (gtk_clist_get_selection_info (clist, x, y, &row, NULL) == 0)
dir = g_strdup (panel->cwd);
else {
if (gtk_clist_get_selection_info (clist, x, y, &row, NULL) == 0) {
file = panel->cwd;
fe = file_entry_from_file (file);
if (!fe)
return; /* eeeek */
free_file = FALSE;
free_fe = TRUE;
} else {
g_assert (row < panel->count);
if (S_ISDIR (panel->dir.list [row].buf.st_mode) ||
panel->dir.list [row].f.link_to_dir)
dir = concat_dir_and_file (panel->cwd, panel->dir.list [row].fname);
else
dir = g_strdup (panel->cwd);
file = g_concat_dir_and_file (panel->cwd, panel->dir.list[row].fname);
fe = &panel->dir.list[row];
free_file = TRUE;
free_fe = FALSE;
}
gdnd_drop_on_directory (context, selection_data, dir);
g_free (dir);
reload = gdnd_perform_drop (context, selection_data, fe, file);
update_one_panel_widget (panel, 0, UP_KEEPSEL);
panel_update_contents (panel);
if (free_file)
g_free (file);
if (free_fe)
file_entry_free (fe);
if (reload) {
update_one_panel_widget (panel, 0, UP_KEEPSEL);
panel_update_contents (panel);
}
}
/**
@ -857,6 +886,7 @@ panel_tree_drag_data_received (GtkWidget *widget,
GtkDTree *dtree = GTK_DTREE (widget);
GtkCTreeNode *node;
int row, col;
file_entry *fe;
char *path;
if (!gtk_clist_get_selection_info (GTK_CLIST (dtree), x, y, &row, &col))
@ -866,10 +896,15 @@ panel_tree_drag_data_received (GtkWidget *widget,
if (!node)
return;
gtk_ctree_expand_recursive (GTK_CTREE (dtree), node);
path = gtk_dtree_get_row_path (dtree, node, 0);
fe = file_entry_from_file (path);
if (!fe)
return; /* eeeek */
gdnd_drop_on_directory (context, selection_data, path);
gdnd_perform_drop (context, selection_data, fe, path);
file_entry_free (fe);
g_free (path);
}
@ -1073,6 +1108,7 @@ panel_clist_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gin
fe = &panel->dir.list[idx];
action = gdnd_validate_action (context,
FALSE,
source_widget != NULL,
source_widget == widget,
fe,
@ -1187,6 +1223,7 @@ panel_icon_list_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x,
fe = (idx == -1) ? NULL : &panel->dir.list[idx];
action = gdnd_validate_action (context,
FALSE,
source_widget != NULL,
source_widget == widget,
fe,