1
1

Yes, we are a drop target. With all of the features requested on the

mail I got from DrMike some months ago :-)

It needs a bit of debugging still

Miguel
Этот коммит содержится в:
Miguel de Icaza 1998-10-21 18:05:08 +00:00
родитель 7b74fc9f5f
Коммит cd9efdc2dd
6 изменённых файлов: 248 добавлений и 114 удалений

Просмотреть файл

@ -1,3 +1,11 @@
1998-10-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gscreen.c (panel_create_icon_display): Small size adjustment.
* glayout.c (create_container): Small size adjustment.
* gmain.c (xtoolkit_create_dialog): Center windows.
1998-10-20 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gscreen.c (x_select_item): Force a canvas update when an icon

Просмотреть файл

@ -312,10 +312,10 @@ artificial_drag_start (GdkWindow *window, int x, int y)
}
#endif /* OLD_DND */
static int operation_value;
static GdkDragAction operation_value;
static void
set_option (GtkWidget *widget, int value)
set_option (GtkWidget *widget, GdkDragAction value)
{
operation_value = value;
gtk_main_quit ();
@ -324,11 +324,11 @@ set_option (GtkWidget *widget, int value)
static void
option_menu_gone ()
{
operation_value = -1;
operation_value = GDK_ACTION_ASK;
gtk_main_quit ();
}
static int
static GdkDragAction
get_operation (guint32 timestamp, int x, int y)
{
static GtkWidget *menu;
@ -339,33 +339,31 @@ get_operation (guint32 timestamp, int x, int y)
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label (_("Copy"));
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC(set_option), (void *) OPER_COPY);
gtk_signal_connect (GTK_OBJECT (item), "activate",
GTK_SIGNAL_FUNC(set_option), (void *) GDK_ACTION_COPY);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
item = gtk_menu_item_new_with_label (_("Move"));
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC(set_option), (void *) OPER_MOVE);
gtk_signal_connect (GTK_OBJECT (item), "activate",
GTK_SIGNAL_FUNC(set_option), (void *) GDK_ACTION_MOVE);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
/* Not yet implemented the Link bits, so better to not show what we dont have */
item = gtk_menu_item_new_with_label (_("Link"));
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC(set_option), (void *) OPER_LINK);
gtk_signal_connect (GTK_OBJECT (item), "activate",
GTK_SIGNAL_FUNC(set_option), (void *) GDK_ACTION_LINK);
gtk_menu_append (GTK_MENU (menu), item);
gtk_widget_show (item);
gtk_signal_connect (GTK_OBJECT (menu), "hide", GTK_SIGNAL_FUNC(option_menu_gone), 0);
}
/* Here, we could set the mask parameter (the last NULL) to a valid variable
* and find out if the shift/control keys were set and do something smart
* about that
*/
gtk_widget_set_uposition (menu, x, y);
/* FIXME: We should catch any events that escape this menu and cancel it */
operation_value = -1;
operation_value = GDK_ACTION_ASK;
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, 0, NULL, 1, timestamp);
gtk_grab_add (menu);
gtk_main ();
@ -375,41 +373,31 @@ get_operation (guint32 timestamp, int x, int y)
return operation_value;
}
/* Used by check_window_id_in_one_panel and find_panel_owning_window_id for finding
/*
* Used by check_window_id_in_one_panel and find_panel_owning_window_id for finding
* the panel that contains the specified window id (used to figure where the drag
* started)
*/
static WPanel *temp_panel;
static void
check_window_id_in_one_panel (gpointer data, gpointer user_data)
check_window_in_one_panel (gpointer data, gpointer user_data)
{
PanelContainer *pc = (PanelContainer *) data;
int id = (int) user_data;
GdkWindow *window = user_data;
WPanel *panel = pc->panel;
GdkWindowPrivate *gdk_wp;
if (panel->list_type == list_icons){
GnomeIconList *icon_list = GNOME_ICON_LIST (panel->icons);
gdk_wp = (GdkWindowPrivate *) GTK_WIDGET (icon_list)->window;
if (gdk_wp->xwindow == id){
if (window == GTK_WIDGET (icon_list)->window){
temp_panel = panel;
return;
}
} else {
GtkCList *clist = GTK_CLIST (panel->list);
gdk_wp = (GdkWindowPrivate *) clist->clist_window;
if (gdk_wp->xwindow == id){
temp_panel = panel;
return;
}
gdk_wp = (GdkWindowPrivate *) GTK_WIDGET (clist)->window;
if (gdk_wp->xwindow == id){
if (window == GTK_CLIST (panel->list)->clist_window){
temp_panel = panel;
return;
}
@ -417,56 +405,58 @@ check_window_id_in_one_panel (gpointer data, gpointer user_data)
}
static WPanel *
find_panel_owning_window_id (int id)
find_panel_owning_window (GdkWindow *window)
{
temp_panel = NULL;
g_list_foreach (containers, check_window_id_in_one_panel, (gpointer) id);
g_list_foreach (containers, check_window_in_one_panel, window);
return temp_panel;
}
static void
perform_drop_on_directory (WPanel *source_panel, int operation, char *dest)
perform_drop_on_directory (WPanel *source_panel, GdkDragAction action, char *dest)
{
switch (operation){
case OPER_COPY:
switch (action){
case GDK_ACTION_COPY:
panel_operate (source_panel, OP_COPY, dest);
break;
case OPER_MOVE:
case GDK_ACTION_MOVE:
panel_operate (source_panel, OP_MOVE, dest);
break;
}
}
#if OLD_DND
static void
perform_drop_manually (int operation, GdkEventDropDataAvailable *event, char *dest)
perform_drop_manually (GList *names, GdkDragAction action, char *dest)
{
struct stat buf;
int count = event->data_numbytes;
char *p = event->data;
int len;
switch (operation){
case OPER_COPY:
switch (action){
case GDK_ACTION_COPY:
create_op_win (OP_COPY, 0);
break;
case OPER_MOVE:
case GDK_ACTION_MOVE:
create_op_win (OP_MOVE, 0);
break;
default:
g_assert_not_reached ();
}
file_mask_defaults ();
do {
for (; names; names = names->next){
char *p = names->data;
char *tmpf;
int res, v;
len = 1 + strlen (p);
count -= len;
if (strncmp (p, "file:", 5) == 0)
p += 5;
switch (operation){
case OPER_COPY:
switch (action){
case GDK_ACTION_COPY:
tmpf = concat_dir_and_file (dest, x_basename (p));
do {
res = mc_stat (p, &buf);
@ -484,7 +474,7 @@ perform_drop_manually (int operation, GdkEventDropDataAvailable *event, char *de
free (tmpf);
break;
case OPER_MOVE:
case GDK_ACTION_MOVE:
tmpf = concat_dir_and_file (dest, x_basename (p));
do {
res = mc_stat (p, &buf);
@ -501,63 +491,33 @@ perform_drop_manually (int operation, GdkEventDropDataAvailable *event, char *de
} while (res != 0);
free (tmpf);
break;
default:
g_assert_not_reached ();
}
}
p += len;
} while (count > 0);
destroy_op_win ();
}
static void
do_symlinks (GdkEventDropDataAvailable *event, char *dest)
do_symlinks (GList *names, char *dest)
{
int count = event->data_numbytes;
char *p = event->data;
int len;
do {
for (; names; names = names->next){
char *full_dest_name;
len = 1 + strlen (p);
count -= len;
char *name = names->data;
full_dest_name = concat_dir_and_file (dest, x_basename (name));
if (strncmp (name, "file:", 5) == 0)
mc_symlink (name+5, full_dest_name);
else
mc_symlink (name, full_dest_name);
full_dest_name = concat_dir_and_file (dest, x_basename (p));
mc_symlink (p, full_dest_name);
free (full_dest_name);
p += len;
} while (count > 0);
}
void
drop_on_directory (GdkEventDropDataAvailable *event, char *dest, int force_manually)
{
WPanel *source_panel;
int operation;
operation = get_operation (event->timestamp, event->coords.x, event->coords.y);
if (operation == -1)
return;
/* Optimization: if we are dragging from the same process, we can
* display a nicer status bar.
*/
source_panel = find_panel_owning_window_id (event->requestor);
/* Symlinks do not use any panel/file.c optimization */
if (operation == OPER_LINK){
do_symlinks (event, dest);
return;
}
if (source_panel && !force_manually){
perform_drop_on_directory (source_panel, operation, dest);
update_one_panel_widget (source_panel, 0, UP_KEEPSEL);
panel_update_contents (source_panel);
} else
perform_drop_manually (operation, event, dest);
return;
}
}
#if OLD_DND
static char **
drops_from_event (GdkEventDropDataAvailable *event, int *argc)
{
@ -594,6 +554,57 @@ drops_from_event (GdkEventDropDataAvailable *event, int *argc)
}
#endif /* OLD_DND */
void
drop_on_directory (GtkSelectionData *sel_data, GdkDragContext *context,
GdkDragAction action, char *dest, int force_manually)
{
WPanel *source_panel;
GList *names;
g_warning ("Figure out the data type\n");
if (sel_data->data == NULL)
return;
printf ("action=%d\n", action);
if (action == GDK_ACTION_ASK){
g_warning ("I need the event here\n");
#if 0
action = get_operation (event->timestamp, event->coords.x, event->coords.y);
#endif
}
printf ("action=%d\n", action);
if (action == GDK_ACTION_ASK)
return;
/*
* Optimization: if we are dragging from the same process, we can
* display a nicer status bar.
*/
source_panel = find_panel_owning_window (context->source_window);
printf ("SOurce_Panel=%p\n", source_panel);
names = gnome_uri_list_extract_uris ((char *)sel_data->data);
/* Symlinks do not use any panel/file.c optimization */
if (action == GDK_ACTION_LINK){
do_symlinks (names, dest);
gnome_uri_list_free_strings (names);
return;
}
if (source_panel && !force_manually){
perform_drop_on_directory (source_panel, action, dest);
update_one_panel_widget (source_panel, 0, UP_KEEPSEL);
panel_update_contents (source_panel);
} else
perform_drop_manually (names, action, dest);
gnome_uri_list_free_strings (names);
return;
}
/*
* destroys a desktop_icon_t structure and anything that was held there,
* including the desktop widget.

Просмотреть файл

@ -3,6 +3,13 @@
#define MC_LIB_DESKTOP "mc.desktop"
/* Drag and drop types recognized by us */
enum {
TARGET_URI_LIST,
TARGET_URL_LIST,
TARGET_TEXT_PLAIN,
};
/* Types of desktop icons:
*
@ -44,6 +51,8 @@ GtkWidget *create_transparent_text_window (char *file, char *text, int extra_eve
GtkWidget *make_transparent_window (char *file);
/* gdesktop.c */
void drop_on_directory (GtkSelectionData *sel_data, GdkDragContext *context,
GdkDragAction action, char *dest, int force_manually);
#if 0
void drop_on_directory (GdkEventDropDataAvailable *event, char *dest, int force_manually);
void artificial_drag_start (GdkWindow *source_window, int x, int y);

Просмотреть файл

@ -442,7 +442,7 @@ create_container (Dlg_head *h, char *name, char *geometry)
if (width != -1 && height != -1)
gtk_widget_set_usize (GTK_WIDGET (app), width, height);
else
gtk_widget_set_usize (GTK_WIDGET (app), 500, 360);
gtk_widget_set_usize (GTK_WIDGET (app), 480, 360);
if (xpos != -1 && ypos != -1)
gtk_widget_set_uposition (GTK_WIDGET (app), xpos, ypos);

Просмотреть файл

@ -196,8 +196,10 @@ xtoolkit_create_dialog (Dlg_head *h, int flags)
if (!(flags & DLG_NO_TOPLEVEL)){
if (flags & DLG_GNOME_APP)
win = gnome_app_new ("mc", h->name);
else
else {
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
}
} else
win = 0;

Просмотреть файл

@ -64,18 +64,17 @@ static char *drag_types [] = { "text/plain", "file:ALL", "url:ALL" };
static char *drop_types [] = { "url:ALL" };
#endif
enum {
TARGET_URI_LIST,
TARGET_URL_LIST,
TARGET_TEXT_PLAIN,
};
static GtkTargetEntry drag_types [] = {
{ "text/uri-list", 0, TARGET_URI_LIST },
{ "text/url-list", 0, TARGET_URL_LIST },
{ "text/plain", 0, TARGET_TEXT_PLAIN },
};
static GtkTargetEntry drop_types [] = {
{ "text/uri-list", 0, TARGET_URI_LIST },
{ "text/url-list", 0, TARGET_URL_LIST },
};
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
/* GtkWidgets with the shaped windows for dragging */
@ -1023,6 +1022,94 @@ panel_drag_data_get (GtkWidget *widget,
}
}
/**
* panel_drag_data_delete:
*
* Invoked when the destination requests the information to be deleted
* possibly because the operation was MOVE.
*/
static void
panel_drag_data_delete (GtkWidget *widget, GdkDragContext *context, WPanel *panel)
{
printf ("Destination request we delete the data we sent\n");
}
/**
* panel_icon_list_drag_data_received:
*
* Invoked on the target side of a Drag and Drop operation when data has been
* dropped.
*/
static void
panel_icon_list_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time,
WPanel *panel)
{
GnomeIconList *gil = GNOME_ICON_LIST (widget);
char *dir;
int idx;
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);
}
drop_on_directory (selection_data, context, context->suggested_action, dir, 0);
free (dir);
update_one_panel_widget (panel, 0, UP_KEEPSEL);
panel_update_contents (panel);
}
/**
* panel_clist_drag_data_received:
*
* Invoked on the target side of a Drag and Drop operation when data has been
* dropped.
*/
static void
panel_clist_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint32 time,
WPanel *panel)
{
GtkCList *clist = GTK_CLIST (widget);
char *dir;
int idx;
int row;
if (gtk_clist_get_selection_info (clist, x, y, &row, NULL) == 0)
dir = g_strdup (panel->cwd);
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);
}
drop_on_directory (selection_data, context, context->suggested_action, dir, 0);
free (dir);
update_one_panel_widget (panel, 0, UP_KEEPSEL);
panel_update_contents (panel);
}
#ifdef OLD_DND
/*
* Handler for text/plain and url:ALL drag types
@ -1145,10 +1232,6 @@ panel_clist_drop_data_available (GtkWidget *widget, GdkEventDropDataAvailable *d
else {
g_assert (row < panel->count);
if (S_ISDIR (panel->dir.list [row].buf.st_mode))
drop_dir = concat_dir_and_file (panel->cwd, panel->dir.list [row].fname);
else
drop_dir = panel->cwd;
}
drop_on_directory (data, drop_dir, 0);
@ -1233,6 +1316,11 @@ load_dnd_icons (void)
#endif
}
static void
widget_connect_dnd_signals (GtkObject *obj, WPanel *panel)
{
}
/*
* Pixmaps can only be loaded once the window has been realized, so
* this is why this hook is here
@ -1240,7 +1328,7 @@ load_dnd_icons (void)
* FIXME: We no longer need to configure DnD on the realize handler
*/
static void
panel_realized (GtkWidget *file_list, WPanel *panel)
panel_clist_realized (GtkWidget *file_list, WPanel *panel)
{
GtkObject *obj = GTK_OBJECT (file_list);
@ -1249,8 +1337,16 @@ panel_realized (GtkWidget *file_list, WPanel *panel)
gtk_drag_source_set (GTK_WIDGET (file_list), GDK_BUTTON1_MASK,
drag_types, ELEMENTS (drag_types), GDK_ACTION_COPY);
gtk_drag_dest_set (GTK_WIDGET (obj), GTK_DEST_DEFAULT_ALL,
drop_types, ELEMENTS (drop_types),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
gtk_signal_connect (obj, "drag_data_get",
GTK_SIGNAL_FUNC (panel_drag_data_get), panel);
gtk_signal_connect (obj, "drag_data_delete",
GTK_SIGNAL_FUNC (panel_drag_data_delete), panel);
gtk_signal_connect (obj, "drag_data_received",
GTK_SIGNAL_FUNC (panel_clist_drag_data_received), panel);
#if OLD_DND
/* DND: Drag setup */
@ -1296,7 +1392,7 @@ panel_create_file_list (WPanel *panel)
GTK_SIGNAL_FUNC (panel_file_list_size_allocate_hook),
panel);
gtk_signal_connect (GTK_OBJECT (file_list), "realize",
GTK_SIGNAL_FUNC (panel_realized),
GTK_SIGNAL_FUNC (panel_clist_realized),
panel);
gtk_signal_connect (GTK_OBJECT (file_list), "select_row",
@ -1536,8 +1632,16 @@ panel_icon_list_realized (GtkObject *obj, WPanel *panel)
load_imlib_icons ();
load_dnd_icons ();
gtk_drag_dest_set (GTK_WIDGET (obj), GTK_DEST_DEFAULT_ALL,
drop_types, ELEMENTS (drop_types),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
gtk_signal_connect (obj, "drag_data_get",
GTK_SIGNAL_FUNC (panel_drag_data_get), panel);
gtk_signal_connect (obj, "drag_data_delete",
GTK_SIGNAL_FUNC (panel_drag_data_delete), panel);
gtk_signal_connect (obj, "drag_data_received",
GTK_SIGNAL_FUNC (panel_icon_list_drag_data_received), panel);
/*
* These implement our drag-start activation code, as we have a pretty
@ -1577,7 +1681,7 @@ panel_create_icon_display (WPanel *panel)
{
GnomeIconList *icon_field;
icon_field = GNOME_ICON_LIST (gnome_icon_list_new (100, NULL, TRUE));
icon_field = GNOME_ICON_LIST (gnome_icon_list_new (90, NULL, TRUE));
gnome_icon_list_set_separators (icon_field, " /-_.");
gnome_icon_list_set_row_spacing (icon_field, 2);
gnome_icon_list_set_col_spacing (icon_field, 2);