1999-08-30 Federico Mena Quintero <federico@redhat.com>

* gdnd.c (file_has_drop_action): New function to test whether a
	file has the drop-action metadata or MIME action property.
	(gdnd_validate_action): Take the drop-action metadata/MIME
	property into account.
	(gdnd_can_drop_on_file): New function to see whether a
	non-directory file can take drops.

	* gscreen.c (drop_on_panel): New helper function to drop stuff on
	a panel.  This uses gdnd_can_drop_on_file so that we have the
	correct behavior.  This enables dropping on executables and files
	with the drop-action metadata/MIME property again.
	(panel_icon_list_drag_data_received): Use drop_on_panel().
	(panel_clist_drag_data_received): Use drop_on_panel().  Normalize
	the Y coordinate to the clist_window.
This commit is contained in:
Miguel de Icaza 1999-08-30 20:07:33 +00:00
parent 00785b29c6
commit 9e2bb07d6e
5 changed files with 147 additions and 79 deletions

View File

@ -1,3 +1,20 @@
1999-08-30 Federico Mena Quintero <federico@redhat.com>
* gdnd.c (file_has_drop_action): New function to test whether a
file has the drop-action metadata or MIME action property.
(gdnd_validate_action): Take the drop-action metadata/MIME
property into account.
(gdnd_can_drop_on_file): New function to see whether a
non-directory file can take drops.
* gscreen.c (drop_on_panel): New helper function to drop stuff on
a panel. This uses gdnd_can_drop_on_file so that we have the
correct behavior. This enables dropping on executables and files
with the drop-action metadata/MIME property again.
(panel_icon_list_drag_data_received): Use drop_on_panel().
(panel_clist_drag_data_received): Use drop_on_panel(). Normalize
the Y coordinate to the clist_window.
1999-08-26 Federico Mena Quintero <federico@redhat.com>
* gscreen.c (panel_clist_drag_motion): Pass the full name to

View File

@ -2039,7 +2039,7 @@ icon_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gin
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
fe = file_entry_from_file (full_name);
if (!fe){
if (!fe) {
g_free (full_name);
return;
}

View File

@ -298,6 +298,31 @@ drop_on_directory (GdkDragContext *context, GtkSelectionData *selection_data,
return retval;
}
/* Returns whether a file has the drop-action metadata or MIME property defined
* for it.
*/
static int
file_has_drop_action (char *filename)
{
char *buf;
int size;
const char *mime_type;
if (gnome_metadata_get (filename, "drop-action", &size, &buf) == 0) {
g_free (buf);
return TRUE;
} else {
mime_type = gnome_mime_type_or_default (filename, NULL);
if (!mime_type)
return FALSE;
if (gnome_mime_get_value (mime_type, "drop-action") != NULL)
return TRUE;
else
return FALSE;
}
}
/* Drop stuff on a non-directory file. This uses metadata and MIME as well. */
static int
drop_on_file (GdkDragContext *context, GtkSelectionData *selection_data,
@ -374,6 +399,17 @@ drop_on_file (GdkDragContext *context, GtkSelectionData *selection_data,
return retval;
}
/**
* gdnd_perform_drop:
* @context: Drag context for operation.
* @selection_data: Selection data from drag_data_received.
* @dest_full_name: Complete name of the destination file or directory.
* @dest_fe: File entry for the destination file or directory.
*
* Performs a drop operation on a directory or file.
*
* Return value: TRUE if the drop is successful, FALSE otherwise.
**/
int
gdnd_perform_drop (GdkDragContext *context, GtkSelectionData *selection_data,
char *dest_full_name, file_entry *dest_fe)
@ -471,7 +507,8 @@ gdnd_find_panel_by_drag_context (GdkDragContext *context, GtkWidget **source_wid
* @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.
* @dest_full_name: Complete name of the destination file or directory.
* @dest_fe: File entry for the destination file, or NULL if directory.
* @dest_selected: If dest is non-NULL, whether it is selected or not.
*
* Computes the final drag action based on the suggested action of the specified
@ -520,6 +557,9 @@ gdnd_validate_action (GdkDragContext *context,
} else if (on_exe) {
if (context->actions & GDK_ACTION_COPY)
return GDK_ACTION_COPY;
} else if (file_has_drop_action (dest_full_name)) {
if (context->actions & GDK_ACTION_COPY)
return GDK_ACTION_COPY;
} else if (same_source)
return 0;
else if (same_process
@ -557,3 +597,25 @@ gdnd_validate_action (GdkDragContext *context,
return 0;
}
/**
* gdnd_can_drop_on_file:
* @full_name: Complete name of the file.
* @fe: File entry for the file.
*
* Computes whether a non-directory file can take drops.
*
* Return value: TRUE if the file can take drops, FALSE otherwise.
**/
int
gdnd_can_drop_on_file (char *full_name, file_entry *fe)
{
g_return_val_if_fail (full_name != NULL, FALSE);
g_return_val_if_fail (fe != NULL, FALSE);
if ((is_exe (fe->buf.st_mode) && if_link_is_exe (full_name, fe))
|| file_has_drop_action (full_name))
return TRUE;
else
return FALSE;
}

View File

@ -55,5 +55,8 @@ GdkDragAction gdnd_validate_action (GdkDragContext *context,
int on_desktop, int same_process, int same_source,
char *dest_full_name, file_entry *dest_fe, int dest_selected);
/* Returns whether a non-directory file can take drops */
int gdnd_can_drop_on_file (char *full_name, file_entry *fe);
#endif

View File

@ -757,6 +757,58 @@ panel_drag_data_delete (GtkWidget *widget, GdkDragContext *context, WPanel *pane
/* Things is: The File manager already handles file moving */
}
/* Performs a drop on a panel. If idx is -1, then drops on the panel's cwd
* itself.
*/
static void
drop_on_panel (WPanel *panel, int idx, GdkDragContext *context, GtkSelectionData *selection_data)
{
char *file;
file_entry *fe;
int drop_on_dir;
int reload;
g_assert (panel != NULL);
g_assert (idx == -1 || idx < panel->count);
g_assert (context != NULL);
g_assert (selection_data != NULL);
drop_on_dir = FALSE;
if (idx == -1)
drop_on_dir = TRUE;
else {
fe = &panel->dir.list[idx];
file = g_concat_dir_and_file (panel->cwd, fe->fname);
if (!((S_ISDIR (fe->buf.st_mode) || fe->f.link_to_dir)
|| gdnd_can_drop_on_file (file, fe))) {
g_free (file);
drop_on_dir = TRUE;
}
}
if (drop_on_dir) {
file = panel->cwd;
fe = file_entry_from_file (file);
if (!fe)
return; /* eeeek */
}
reload = gdnd_perform_drop (context, selection_data, file, fe);
if (file != panel->cwd)
g_free (file);
if (drop_on_dir)
file_entry_free (fe);
if (reload) {
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
}
/**
* panel_icon_list_drag_data_received:
*
@ -773,48 +825,10 @@ panel_icon_list_drag_data_received (GtkWidget *widget,
guint32 time,
WPanel *panel)
{
GnomeIconList *gil = GNOME_ICON_LIST (widget);
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) {
file = panel->cwd;
fe = file_entry_from_file (file);
if (!fe)
return; /* eeeek */
free_file = FALSE;
free_fe = TRUE;
} else {
fe = &panel->dir.list[idx];
if (S_ISDIR (fe->buf.st_mode) || fe->f.link_to_dir){
file = g_concat_dir_and_file (panel->cwd, panel->dir.list[idx].fname);
free_file = TRUE;
} else {
file = panel->cwd;
free_file = FALSE;
}
free_fe = FALSE;
}
reload = gdnd_perform_drop (context, selection_data, file, fe);
if (free_file)
g_free (file);
if (free_fe)
file_entry_free (fe);
if (reload) {
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
idx = gnome_icon_list_get_icon_at (GNOME_ICON_LIST (widget), x, y);
drop_on_panel (panel, idx, context, selection_data);
}
/**
@ -833,49 +847,21 @@ panel_clist_drag_data_received (GtkWidget *widget,
guint32 time,
WPanel *panel)
{
GtkCList *clist = GTK_CLIST (widget);
file_entry *fe;
char *file;
int free_file, free_fe;
GtkCList *clist;
int row;
int reload;
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 */
clist = GTK_CLIST (widget);
free_file = FALSE;
free_fe = TRUE;
} else {
g_assert (row < panel->count);
/* Normalize the y coordinate to the clist_window */
fe = &panel->dir.list[row];
y -= (GTK_CONTAINER (clist)->border_width
+ clist->column_title_area.y
+ clist->column_title_area.height);
if (S_ISDIR (fe->buf.st_mode) || fe->f.link_to_dir){
file = g_concat_dir_and_file (panel->cwd, panel->dir.list[row].fname);
free_file = TRUE;
} else {
file = panel->cwd;
free_file = FALSE;
}
if (gtk_clist_get_selection_info (GTK_CLIST (widget), x, y, &row, NULL) == 0)
row = -1;
free_fe = FALSE;
}
reload = gdnd_perform_drop (context, selection_data, file, fe);
if (free_file)
g_free (file);
if (free_fe)
file_entry_free (fe);
if (reload) {
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
drop_on_panel (panel, row, context, selection_data);
}
/**