Browse Source

The clist is not working, I'll fix that when I get home - Federico

1998-11-09  Federico Mena Quintero  <federico@nuclecu.unam.mx>

	* gdnd.c: New file that handles all the DnD stuff.  Mainly used to
	clean up gdesktop.c.

	* gscreen.c (panel_icon_list_drag_data_received): Use
	gdnd_drop_on_directory().
	(CLIST_FROM_SW): Added this macro to fetch the clist from the
	scrolled window in panel->list.
	(panel_create_file_list): Create a scrolled window and put the
	clist inside it.  This is required per the new clist API.
	(panel_configure_file_list): Use the scrolled window's adjustment.
	(panel_file_list_size_allocate_hook): Use the scrolled window
	instead of the clist.
	(panel_file_list_compute_lines): Use the scrolled window instead
	of the clist.
	(panel_file_list_configure_contents): Use the scrolled window
	instead of the clist.
	(panel_create_file_list): Do the DnD setup here, not in the
	realization callback.
	(x_create_panel): Do not realize the panel explicitly.
	(panel_create_pixmaps): Create the pixmaps using imlib instead of
	Gdk.
Miguel de Icaza 26 years ago
parent
commit
2c1226f796
5 changed files with 424 additions and 208 deletions
  1. 24 0
      gnome/ChangeLog
  2. 3 0
      gnome/Makefile.in
  3. 211 0
      gnome/gdnd.c
  4. 17 0
      gnome/gdnd.h
  5. 169 208
      gnome/gscreen.c

+ 24 - 0
gnome/ChangeLog

@@ -1,3 +1,27 @@
+1998-11-09  Federico Mena Quintero  <federico@nuclecu.unam.mx>
+
+	* gdnd.c: New file that handles all the DnD stuff.  Mainly used to
+	clean up gdesktop.c.
+
+	* gscreen.c (panel_icon_list_drag_data_received): Use
+	gdnd_drop_on_directory().
+	(CLIST_FROM_SW): Added this macro to fetch the clist from the
+	scrolled window in panel->list.
+	(panel_create_file_list): Create a scrolled window and put the
+	clist inside it.  This is required per the new clist API.
+	(panel_configure_file_list): Use the scrolled window's adjustment.
+	(panel_file_list_size_allocate_hook): Use the scrolled window
+	instead of the clist.
+	(panel_file_list_compute_lines): Use the scrolled window instead
+	of the clist.
+	(panel_file_list_configure_contents): Use the scrolled window
+	instead of the clist.
+	(panel_create_file_list): Do the DnD setup here, not in the
+	realization callback.
+	(x_create_panel): Do not realize the panel explicitly.
+	(panel_create_pixmaps): Create the pixmaps using imlib instead of
+	Gdk.
+
 1998-11-06  Federico Mena Quintero  <federico@nuclecu.unam.mx>
 
 	* gdesktop.c (text_changed): Doh.  Set the new filename of the

+ 3 - 0
gnome/Makefile.in

@@ -16,6 +16,7 @@ INSTALL_DATA = @INSTALL_DATA@
 
 GNOMESRCS = 		\
 	gdesktop-icon.c	\
+	gdnd.c		\
 	gkey.c 		\
 	gmain.c 	\
 	gmetadata.c	\
@@ -40,6 +41,7 @@ GNOMESRCS = 		\
 
 GNOMEHDRS = 		\
 	gdesktop-icon.h	\
+	gdnd.h		\
 	gmain.h 	\
 	gmetadata.h	\
 	gscreen.h	\
@@ -84,6 +86,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \
 
 OBJS = $(LOBJS) $(OOBJS) \
 	gdesktop-icon.o	\
+	gdnd.o		\
 	gkey.o 		\
 	gmain.o 	\
 	gmetadata.o	\

+ 211 - 0
gnome/gdnd.c

@@ -0,0 +1,211 @@
+/* Drag and Drop functionality for the Midnight Commander
+ *
+ * Copyright (C) 1998 The Free Software Foundation
+ *
+ * Authors: Federico Mena <federico@nuclecu.unam.mx>
+ *          Miguel de Icaza <miguel@nuclecu.unam.mx>
+ */
+
+#include <config.h>
+#include <sys/stat.h>
+#include <gdk/gdkprivate.h>
+#include "gdnd.h"
+#include "file.h"
+#include "main.h"
+#include "panel.h"
+#include "gscreen.h"
+#include "../vfs/vfs.h"
+
+
+/* Pops up a menu of actions to perform on dropped files */
+static GdkDragAction
+get_action (void)
+{
+	/* FIXME */
+	printf ("Should query for the action!\n");
+	return GDK_ACTION_LINK;
+}
+
+/* Looks for a panel that has the specified window for its list display.  It is used to figure out
+ * if we are receiving a drop from a panel on this MC process.  If no panel is found, it returns
+ * NULL.
+ */
+static WPanel *
+find_panel_owning_window (GdkWindow *window)
+{
+	GList *list;
+	WPanel *panel;
+	GdkWindowPrivate *wp, *lwp;
+
+	wp = (GdkWindowPrivate *) window;
+
+	for (list = containers; list; list = list->next) {
+		panel = ((PanelContainer *) list->data)->panel;
+
+		if (panel->list_type == list_icons)
+			lwp = (GdkWindowPrivate *) GTK_WIDGET (panel->icons)->window;
+		else
+			lwp = (GdkWindowPrivate *) GTK_CLIST (panel->list)->clist_window;
+
+		if (lwp->xwindow == wp->xwindow)
+			return panel;
+	}
+
+	return NULL;
+}
+
+/* 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)
+{
+	switch (action) {
+	case GDK_ACTION_COPY:
+		panel_operate (source_panel, OP_COPY, destdir);
+		break;
+
+	case GDK_ACTION_MOVE:
+		panel_operate (source_panel, OP_MOVE, destdir);
+		break;
+
+	default:
+		g_assert_not_reached ();
+	}
+
+	/* Finish up */
+
+	update_one_panel_widget (source_panel, FALSE, UP_KEEPSEL);
+	panel_update_contents (source_panel);
+}
+
+/* Performs handling of symlinks via drag and drop.  This should go away when operation windows
+ * support links.
+ */
+static void
+perform_links (GList *names, char *destdir)
+{
+	char *name;
+	char *dest_name;
+
+	for (; names; names = names->next) {
+		name = names->data;
+		if (strncmp (name, "file:", 5) == 0)
+			name += 5;
+
+		dest_name = g_concat_dir_and_file (destdir, x_basename (name));
+		mc_symlink (name, dest_name);
+		g_free (dest_name);
+	}
+}
+
+/* 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)
+{
+	struct stat s;
+	char *name;
+	char *dest_name;
+	int result;
+
+	switch (action) {
+	case GDK_ACTION_COPY:
+		create_op_win (OP_COPY, FALSE);
+		break;
+
+	case GDK_ACTION_MOVE:
+		create_op_win (OP_MOVE, FALSE);
+		break;
+
+	default:
+		g_assert_not_reached ();
+	}
+
+	file_mask_defaults ();
+
+	for (; names; names = names->next) {
+		name = names->data;
+		if (strncmp (name, "file:", 5) == 0)
+			name += 5;
+
+		dest_name = g_concat_dir_and_file (destdir, x_basename (name));
+
+		do {
+			result = mc_stat (name, &s);
+
+			if (result != 0) {
+				/* FIXME: this error message sucks */
+				if (file_error (_("Could not stat %s\n%s"), dest_name) != FILE_RETRY)
+					result = 0;
+				else {
+					if (S_ISDIR (s.st_mode)) {
+						if (action == GDK_ACTION_COPY)
+							copy_dir_dir (name, dest_name, TRUE, FALSE, FALSE, FALSE);
+						else
+							move_dir_dir (name, dest_name);
+					} else {
+						if (action == GDK_ACTION_COPY)
+							copy_file_file (name, dest_name, TRUE);
+						else
+							move_file_file (name, dest_name);
+					}
+				}
+			}
+		} while (result != 0);
+
+		g_free (dest_name);
+		break;
+	}
+
+	destroy_op_win ();
+}
+
+/**
+ * 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)
+{
+	GdkDragAction action;
+	WPanel *source_panel;
+	GList *names;
+
+	if (context->suggested_action == GDK_ACTION_ASK) {
+		action = get_action ();
+
+		if (action == GDK_ACTION_ASK)
+			return FALSE;
+	} else
+		action = context->suggested_action;
+
+	/* If we are dragging from a file panel, we can display a nicer status display */
+	source_panel = find_panel_owning_window (context->source_window);
+
+	/* Symlinks do not use file.c */
+
+	if (source_panel && action != GDK_ACTION_LINK)
+		perform_action_on_panel (source_panel, action, destdir);
+	else {
+		names = gnome_uri_list_extract_uris (selection_data->data);
+
+		if (action == GDK_ACTION_LINK)
+			perform_links (names, destdir);
+		else
+			perform_action (names, action, destdir);
+
+		gnome_uri_list_free_strings (names);
+	}
+
+	return TRUE;
+}

+ 17 - 0
gnome/gdnd.h

@@ -0,0 +1,17 @@
+/* Drag and Drop functionality for the Midnight Commander
+ *
+ * Copyright (C) 1998 The Free Software Foundation
+ *
+ * Authors: Federico Mena <federico@nuclecu.unam.mx>
+ *          Miguel de Icaza <miguel@nuclecu.unam.mx>
+ */
+
+#ifndef GDND_H
+#define GDND_H
+
+#include <gtk/gtk.h>
+
+/* 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);
+
+#endif

+ 169 - 208
gnome/gscreen.c

@@ -17,8 +17,6 @@
 #include "dir.h"
 #include "panel.h"
 #include "command.h"
-#include "panel.h"		/* current_panel */
-#include "command.h"		/* cmdline */
 #include "main.h"
 #include "color.h"
 #include "mouse.h"
@@ -29,6 +27,7 @@
 #include "dir.h"
 #include "dialog.h"
 #include "gdesktop.h"
+#include "gdnd.h"
 #include "gpageprop.h"
 #include "gcliplabel.h"
 #include "gblist.h"
@@ -96,7 +95,10 @@ typedef void (*context_menu_callback)(GtkWidget *, void *);
 #define F_DICON      32		/* Only applies to desktop_icon_t */
 #define F_PANEL      64         /* Only applies to WPanel */
 
-static void panel_file_list_configure_contents (GtkWidget *file_list, WPanel *panel, int main_width, int height);
+static void panel_file_list_configure_contents (GtkWidget *sw, WPanel *panel, int main_width, int height);
+
+#define CLIST_FROM_SW(panel_list) GTK_CLIST (GTK_SCROLLED_WINDOW (panel_list)->viewport)
+
 
 void
 repaint_file (WPanel *panel, int file_index, int move, int attr, int isstatus)
@@ -170,7 +172,7 @@ panel_fill_panel_list (WPanel *panel)
 	const int top       = panel->count;
 	const int items     = panel->format->items;
 	const int selected  = panel->selected;
-	GtkCList *cl        = GTK_CLIST (panel->list);
+	GtkCList *cl        = CLIST_FROM_SW (panel->list);
 	int i, col, type_col, color;
 	char  **texts;
 
@@ -318,7 +320,7 @@ x_panel_select_item (WPanel *panel, int index, int value)
 	int color;
 
 	color = file_compute_color (value ? MARKED : NORMAL, &panel->dir.list[index]);
-	panel_file_list_set_row_colors (GTK_CLIST (panel->list), index, color);
+	panel_file_list_set_row_colors (CLIST_FROM_SW (panel->list), index, color);
 }
 
 void
@@ -337,7 +339,7 @@ x_select_item (WPanel *panel)
 		}
 		gnome_canvas_update_now (GNOME_CANVAS (list));
 	} else {
-		GtkCList *clist = GTK_CLIST (panel->list);
+		GtkCList *clist = CLIST_FROM_SW (panel->list);
 		int color, marked;
 		
 		if (panel->dir.list [panel->selected].f.marked)
@@ -346,7 +348,7 @@ x_select_item (WPanel *panel)
 			marked = 0;
 		
 		color = file_compute_color (marked ? MARKED_SELECTED : SELECTED, &panel->dir.list [panel->selected]);
-		panel_file_list_set_row_colors (GTK_CLIST (panel->list), panel->selected, color);
+		panel_file_list_set_row_colors (CLIST_FROM_SW (panel->list), panel->selected, color);
 		
 		/* Make it visible */
 		if (gtk_clist_row_is_visible (clist, panel->selected) != GTK_VISIBILITY_FULL)
@@ -369,7 +371,7 @@ x_unselect_item (WPanel *panel)
 
 		val = panel->dir.list [panel->selected].f.marked ? MARKED : NORMAL;
 		color = file_compute_color (val, &panel->dir.list [panel->selected]);
-		panel_file_list_set_row_colors (GTK_CLIST (panel->list), panel->selected, color);
+		panel_file_list_set_row_colors (CLIST_FROM_SW (panel->list), panel->selected, color);
 	}
 }
 
@@ -397,25 +399,26 @@ x_adjust_top_file (WPanel *panel)
  * Configures the columns title sizes for the panel->list CList widget
  */
 static void
-panel_file_list_configure_contents (GtkWidget *file_list, WPanel *panel, int main_width, int height)
+panel_file_list_configure_contents (GtkWidget *sw, WPanel *panel, int main_width, int height)
 {
+	GtkCList *clist;
 	format_e *format = panel->format;
 	int i, used_columns, expandables, items;
 	int char_width, usable_pixels, extra_pixels, width;
 	int total_columns, extra_columns;
 	int expand_space, extra_space, shrink_space;
 	int lost_pixels, display_the_mini_info;
-	
+
 	/* Pass 1: Count minimum columns,
 	 * set field_len to default to the requested_field_len
 	 * and compute how much space we lost to the column decorations
 	 */
 	lost_pixels = used_columns = expandables = items = 0;
-	for (format = panel->format; format; format = format->next){
+	for (format = panel->format; format; format = format->next) {
 		format->field_len = format->requested_field_len;
 		if (!format->use_in_gui)
 			continue;
-		
+
 		used_columns += format->field_len;
 		items++;
 		if (format->expand)
@@ -424,19 +427,20 @@ panel_file_list_configure_contents (GtkWidget *file_list, WPanel *panel, int mai
 	}
 
 	/* The left scrollbar might take some space from us, use this information */
-	if (GTK_WIDGET_VISIBLE (GTK_CLIST (file_list)->vscrollbar)){
-		int scrollbar_width = GTK_WIDGET (GTK_CLIST (file_list)->vscrollbar)->requisition.width;
-		int scrollbar_space = GTK_CLIST_CLASS (GTK_OBJECT (file_list)->klass)->scrollbar_spacing;
+	if (GTK_WIDGET_VISIBLE (GTK_SCROLLED_WINDOW (sw)->vscrollbar)) {
+		int scrollbar_width = GTK_WIDGET (GTK_SCROLLED_WINDOW (sw)->vscrollbar)->requisition.width;
+		int scrollbar_space = GTK_SCROLLED_WINDOW_CLASS (GTK_OBJECT (sw)->klass)->scrollbar_spacing;
 
 		lost_pixels += scrollbar_space + scrollbar_width;
 	}
-	char_width = gdk_string_width (file_list->style->font, "xW") / 2;
+
+	char_width = gdk_string_width (sw->style->font, "xW") / 2;
 	width = main_width - lost_pixels;
 	extra_pixels  = width % char_width;
 	usable_pixels = width - extra_pixels;
 	total_columns = usable_pixels / char_width;
 	extra_columns = total_columns - used_columns;
-	if (extra_columns > 0){
+	if (extra_columns > 0) {
 		expand_space  = extra_columns / expandables;
 		extra_space   = extra_columns % expandables;
 	} else
@@ -446,30 +450,34 @@ panel_file_list_configure_contents (GtkWidget *file_list, WPanel *panel, int mai
 	 * if panel->estimated_total is not zero, ie, if this has been
 	 * initialized for the first time.
 	 */
-	
+
 	display_the_mini_info = (panel->estimated_total == 0);
 	panel->estimated_total = total_columns;
 
 	if (display_the_mini_info)
 		display_mini_info (panel);
-	
+
 	/* If we dont have enough space, shorten the fields */
-	if (used_columns > total_columns){
+	if (used_columns > total_columns) {
 		expand_space = 0;
 		shrink_space = (used_columns - total_columns) / items;
 	} else
 		shrink_space = 0;
-	
-	gtk_clist_freeze (GTK_CLIST (file_list));
-	for (i = 0, format = panel->format; format; format = format->next){
+
+	clist = GTK_CLIST (GTK_SCROLLED_WINDOW (sw)->viewport);
+
+	gtk_clist_freeze (clist);
+
+	for (i = 0, format = panel->format; format; format = format->next) {
 		if (!format->use_in_gui)
 			continue;
 
 		format->field_len += (format->expand ? expand_space : 0) - shrink_space;
-		gtk_clist_set_column_width (GTK_CLIST (file_list), i, format->field_len * char_width);
+		gtk_clist_set_column_width (clist, i, format->field_len * char_width);
 		i++;
 	}
-	gtk_clist_thaw (GTK_CLIST (file_list));
+
+	gtk_clist_thaw (clist);
 }
 
 static void
@@ -516,10 +524,10 @@ panel_action_properties (GtkWidget *widget, WPanel *panel)
 {
 	file_entry *fe = &panel->dir.list [panel->selected];
 	char *full_name = concat_dir_and_file (panel->cwd, fe->fname);
-	
-	if (item_properties (GTK_WIDGET (panel->list), full_name, NULL) != 0){
+
+	if (item_properties (GTK_WIDGET (CLIST_FROM_SW (panel->list)), full_name, NULL) != 0)
 		reread_cmd ();
-	}
+
 	free (full_name);
 }
 
@@ -806,7 +814,7 @@ panel_file_list_select_row (GtkWidget *file_list, int row, int column, GdkEvent
 	switch (event->type) {
 	case GDK_BUTTON_RELEASE:
 		printf ("1\n");
-		gtk_clist_unselect_row (GTK_CLIST (panel->list), row, 0);
+		gtk_clist_unselect_row (CLIST_FROM_SW (panel->list), row, 0);
 		internal_select_item (file_list, panel, row);
 
 		switch (event->button.button) {
@@ -830,7 +838,7 @@ panel_file_list_select_row (GtkWidget *file_list, int row, int column, GdkEvent
 
 	case GDK_2BUTTON_PRESS:
 		printf ("2\n");
-		gtk_clist_unselect_row (GTK_CLIST (panel->list), row, 0);
+		gtk_clist_unselect_row (CLIST_FROM_SW (panel->list), row, 0);
 		if (event->button.button == 1)
 			do_enter (panel);
 		break;
@@ -842,28 +850,28 @@ panel_file_list_select_row (GtkWidget *file_list, int row, int column, GdkEvent
 
 /* Figure out the number of visible lines in the panel */
 static void
-panel_file_list_compute_lines (GtkCList *file_list, WPanel *panel, int height)
+panel_file_list_compute_lines (GtkScrolledWindow *sw, WPanel *panel, int height)
 {
 	int lost_pixels = 0;
 	
-	if (GTK_WIDGET_VISIBLE (file_list->hscrollbar)){
-		int scrollbar_width = GTK_WIDGET (file_list->hscrollbar)->requisition.width;
-		int scrollbar_space = GTK_CLIST_CLASS (GTK_OBJECT (file_list)->klass)->scrollbar_spacing;
+	if (GTK_WIDGET_VISIBLE (sw->hscrollbar)) {
+		int scrollbar_width = GTK_WIDGET (sw->hscrollbar)->requisition.width;
+		int scrollbar_space = GTK_SCROLLED_WINDOW_CLASS (GTK_OBJECT (sw)->klass)->scrollbar_spacing;
 
 		lost_pixels = scrollbar_space + scrollbar_width;
 	}
-	panel->widget.lines = (height-lost_pixels) /
-		(GTK_CLIST (file_list)->row_height + CELL_SPACING);
+
+	panel->widget.lines = (height-lost_pixels) / (GTK_CLIST (sw->viewport)->row_height + CELL_SPACING);
 }
 
 static void
-panel_file_list_size_allocate_hook (GtkWidget *file_list, GtkAllocation *allocation, WPanel *panel)
+panel_file_list_size_allocate_hook (GtkWidget *sw, GtkAllocation *allocation, WPanel *panel)
 {
-	gtk_signal_handler_block_by_data (GTK_OBJECT (file_list), panel);
-	panel_file_list_configure_contents (file_list, panel, allocation->width, allocation->height);
-	gtk_signal_handler_unblock_by_data (GTK_OBJECT (file_list), panel);
+	gtk_signal_handler_block_by_data (GTK_OBJECT (sw), panel);
+	panel_file_list_configure_contents (sw, panel, allocation->width, allocation->height);
+	gtk_signal_handler_unblock_by_data (GTK_OBJECT (sw), panel);
 	
-	panel_file_list_compute_lines (GTK_CLIST (file_list), panel, allocation->height);
+	panel_file_list_compute_lines (GTK_SCROLLED_WINDOW (sw), panel, allocation->height);
 }
 
 static void
@@ -893,15 +901,27 @@ panel_file_list_column_callback (GtkWidget *widget, int col, WPanel *panel)
 	}
 }
 
+/* Convenience function to load a pixmap and mask from xpm data */
 static void
-panel_create_pixmaps (GtkWidget *parent)
+create_pixmap (char **data, GdkPixmap **pixmap, GdkBitmap **mask)
 {
-	GdkColor color = gtk_widget_get_style (parent)->bg [GTK_STATE_NORMAL];
+	GdkImlibImage *im;
 
-	pixmaps_ready = 1;
-	icon_directory_pixmap = gdk_pixmap_create_from_xpm_d (parent->window, &icon_directory_mask, &color, directory_xpm);
-	icon_link_pixmap      = gdk_pixmap_create_from_xpm_d (parent->window, &icon_link_mask,      &color, link_xpm);
-	icon_dev_pixmap       = gdk_pixmap_create_from_xpm_d (parent->window, &icon_dev_mask,       &color, dev_xpm);
+	im = gdk_imlib_create_image_from_xpm_data (data);
+	gdk_imlib_render (im, im->rgb_width, im->rgb_height);
+	*pixmap = gdk_imlib_copy_image (im);
+	*mask = gdk_imlib_copy_mask (im);
+	gdk_imlib_destroy_image (im);
+}
+
+static void
+panel_create_pixmaps (void)
+{
+	pixmaps_ready = TRUE;
+
+	create_pixmap (directory_xpm, &icon_directory_pixmap, &icon_directory_mask);
+	create_pixmap (link_xpm, &icon_link_pixmap, &icon_link_mask);
+	create_pixmap (dev_xpm, &icon_dev_pixmap, &icon_dev_mask);
 }
 
 static void
@@ -914,10 +934,9 @@ panel_file_list_scrolled (GtkAdjustment *adj, WPanel *panel)
 }
 
 static void
-panel_configure_file_list (WPanel *panel, GtkWidget *file_list)
+panel_configure_file_list (WPanel *panel, GtkWidget *sw, GtkWidget *file_list)
 {
 	format_e *format = panel->format;
-	GtkCList *cl = GTK_CLIST (file_list);
 	GtkObject *adjustment;
 	int i;
 
@@ -927,10 +946,9 @@ panel_configure_file_list (WPanel *panel, GtkWidget *file_list)
 
 	/* Configure the CList */
 
-	gtk_clist_set_selection_mode (cl, GTK_SELECTION_SINGLE);
-	gtk_clist_set_policy (cl, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_clist_set_selection_mode (GTK_CLIST (file_list), GTK_SELECTION_SINGLE);
 	
-	for (i = 0, format = panel->format; format; format = format->next){
+	for (i = 0, format = panel->format; format; format = format->next) {
 		GtkJustification just;
 
 		if (!format->use_in_gui)
@@ -942,13 +960,13 @@ panel_configure_file_list (WPanel *panel, GtkWidget *file_list)
 		else
 			just = GTK_JUSTIFY_RIGHT;
 		
-		gtk_clist_set_column_justification (cl, i, just);
+		gtk_clist_set_column_justification (GTK_CLIST (file_list), i, just);
 		i++;
 	}
 
 	/* Configure the scrolbars */
-	adjustment = GTK_OBJECT (gtk_range_get_adjustment (GTK_RANGE (cl->vscrollbar)));
-	gtk_signal_connect_after (GTK_OBJECT(adjustment), "value_changed", 
+	adjustment = GTK_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw)));
+	gtk_signal_connect_after (adjustment, "value_changed", 
 				  GTK_SIGNAL_FUNC (panel_file_list_scrolled), panel);
 }
 
@@ -1071,9 +1089,8 @@ panel_icon_list_drag_data_received (GtkWidget          *widget,
 		else
 			dir = g_strdup (panel->cwd);
 	}
-#if 0
-	drop_on_directory (selection_data, context, context->suggested_action, dir, 0);
-#endif
+
+	gdnd_drop_on_directory (context, selection_data, dir);
 	free (dir);
 
 	update_one_panel_widget (panel, 0, UP_KEEPSEL);
@@ -1098,7 +1115,6 @@ panel_clist_drag_data_received (GtkWidget          *widget,
 {
 	GtkCList *clist = GTK_CLIST (widget);
 	char *dir;
-	int idx;
 	int row;
 	
 	if (gtk_clist_get_selection_info (clist, x, y, &row, NULL) == 0)
@@ -1112,9 +1128,8 @@ panel_clist_drag_data_received (GtkWidget          *widget,
 		else 
 			dir = g_strdup (panel->cwd);
 	}
-#if 0
-	drop_on_directory (selection_data, context, context->suggested_action, dir, 0);
-#endif
+
+	gdnd_drop_on_directory (context, selection_data, dir);
 	free (dir);
 
 	update_one_panel_widget (panel, 0, UP_KEEPSEL);
@@ -1308,33 +1323,22 @@ load_transparent_image (char *base)
 static void
 load_dnd_icons (void)
 {
-	GdkPoint hotspot = { 5, 5 };
-
 	if (!drag_directory)
 		drag_directory = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_NOT, NULL);
-	
+
 	if (!drag_directory_ok)
 		drag_directory_ok = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_NEW, NULL);
-	
+
 	if (!drag_multiple)
 		drag_multiple = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_NOT, NULL);
-	
+
 	if (!drag_multiple_ok)
 		drag_multiple_ok = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_MULTIPLE, NULL);
-
-#if OLD_DND
-	if (drag_directory && drag_directory_ok)
-		gdk_dnd_set_drag_shape (drag_directory->window, &hotspot,
-					drag_directory_ok->window, &hotspot);
-#endif
 }
 
 static int
 panel_clist_button_press (GtkWidget *widget, GdkEventButton *event, WPanel *panel)
 {
-	GtkCList *clist = GTK_CLIST (widget);
-	int icon;
-
 	panel->maybe_start_drag = event->button;
 	
 	panel->click_x = event->x;
@@ -1346,8 +1350,6 @@ panel_clist_button_press (GtkWidget *widget, GdkEventButton *event, WPanel *pane
 static int
 panel_clist_button_release (GtkWidget *widget, GdkEventButton *event, WPanel *panel)
 {
-	GtkCList *clist = GTK_CLIST (widget);
-
 	panel->maybe_start_drag = 0;
 	return FALSE;
 }
@@ -1387,45 +1389,6 @@ panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel)
 	return FALSE;
 }
 
-/*
- * Pixmaps can only be loaded once the window has been realized, so
- * this is why this hook is here
- *
- * FIXME: We no longer need to configure DnD on the realize handler 
- */
-static void
-panel_clist_realized (GtkWidget *file_list, WPanel *panel)
-{
-	GtkObject *obj = GTK_OBJECT (file_list);
-
-	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_clist_drag_data_received), panel);
-
-	/*
-	 * These implement our drag-start activation code.  We need to manually
-	 * activate the drag as the DnD code in Gtk+ will make the scrollbars 
-	 * in the CList activate drags when they are moved. 
-	 */
-	gtk_signal_connect (obj, "button_press_event",
-			    GTK_SIGNAL_FUNC (panel_clist_button_press), panel);
-
-	gtk_signal_connect (obj, "button_release_event",
-			    GTK_SIGNAL_FUNC (panel_clist_button_release), panel);
-
-	gtk_signal_connect (obj, "motion_notify_event",
-			    GTK_SIGNAL_FUNC (panel_widget_motion), panel);
-}
-
 /*
  * Create, setup the file listing display.
  */
@@ -1435,7 +1398,7 @@ panel_create_file_list (WPanel *panel)
 	const int items = panel->format->items;
 	format_e  *format = panel->format;
 	GtkWidget *file_list;
-	GtkCList  *clist;
+	GtkWidget *sw;
 	gchar     **titles;
 	int       i;
 
@@ -1444,21 +1407,52 @@ panel_create_file_list (WPanel *panel)
 		if (format->use_in_gui)
 			titles [i++] = format->title;
 
+	sw = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
 	file_list = gtk_blist_new_with_titles (items, titles);
-	clist = GTK_CLIST (file_list);
-	panel_configure_file_list (panel, file_list);
+	gtk_container_add (GTK_CONTAINER (sw), file_list);
+	gtk_widget_show (file_list);
+
+	panel_configure_file_list (panel, sw, file_list);
 	g_free (titles);
 
-	gtk_signal_connect_after (GTK_OBJECT (file_list), "size_allocate",
+	gtk_signal_connect_after (GTK_OBJECT (sw), "size_allocate",
 				  GTK_SIGNAL_FUNC (panel_file_list_size_allocate_hook),
 				  panel);
-	gtk_signal_connect (GTK_OBJECT (file_list), "realize",
-			    GTK_SIGNAL_FUNC (panel_clist_realized),
-			    panel);
 
 	gtk_signal_connect (GTK_OBJECT (file_list), "select_row",
 			    GTK_SIGNAL_FUNC (panel_file_list_select_row),
 			    panel);
+
+	/* Set up drag and drop */
+
+	load_dnd_icons ();
+
+	gtk_drag_dest_set (GTK_WIDGET (file_list), GTK_DEST_DEFAULT_ALL,
+			   drop_types, ELEMENTS (drop_types),
+			   GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
+
+	gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_get",
+			    GTK_SIGNAL_FUNC (panel_drag_data_get), panel);
+	gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_delete",
+			    GTK_SIGNAL_FUNC (panel_drag_data_delete), panel);
+	gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_received",
+			    GTK_SIGNAL_FUNC (panel_clist_drag_data_received), panel);
+
+	/* These implement our drag-start activation code.  We need to manually activate the drag as
+	 * the DnD code in Gtk+ will make the scrollbars in the CList activate drags when they are
+	 * moved.
+	 */
+	gtk_signal_connect (GTK_OBJECT (file_list), "button_press_event",
+			    GTK_SIGNAL_FUNC (panel_clist_button_press), panel);
+
+	gtk_signal_connect (GTK_OBJECT (file_list), "button_release_event",
+			    GTK_SIGNAL_FUNC (panel_clist_button_release), panel);
+
+	gtk_signal_connect (GTK_OBJECT (file_list), "motion_notify_event",
+			    GTK_SIGNAL_FUNC (panel_widget_motion), panel);
+
 	return file_list;
 }
 
@@ -1640,99 +1634,69 @@ panel_icon_list_button_press (GtkWidget *widget, GdkEventButton *event, WPanel *
 static int
 panel_icon_list_button_release (GtkWidget *widget, GdkEventButton *event, WPanel *panel)
 {
-	GnomeIconList *gil = GNOME_ICON_LIST (widget);
-
 	panel->maybe_start_drag = 0;
 	return FALSE;
 }
 
-/*
- * Setup for the icon view
- */
-static void
-panel_icon_list_realized (GtkObject *obj, WPanel *panel)
+/* Create and setup the icon field display */
+static GtkWidget *
+panel_create_icon_display (WPanel *panel)
 {
-	GnomeIconList *icon = GNOME_ICON_LIST (obj);
-	
-	load_imlib_icons ();
-	load_dnd_icons ();
+	GnomeIconList *ilist;
 
-	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);
+	ilist = GNOME_ICON_LIST (gnome_icon_list_new (90, NULL, TRUE));
+	gnome_icon_list_set_separators (ilist, " /-_.");
+	gnome_icon_list_set_row_spacing (ilist, 2);
+	gnome_icon_list_set_col_spacing (ilist, 2);
+	gnome_icon_list_set_icon_border (ilist, 2);
+	gnome_icon_list_set_text_spacing (ilist, 2);
 
-	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);
+	gnome_icon_list_set_selection_mode (ilist, GTK_SELECTION_MULTIPLE);
+	GTK_WIDGET_SET_FLAGS (ilist, GTK_CAN_FOCUS);
 
-	/*
-	 * These implement our drag-start activation code, as we have a pretty
-	 * oveloaded widget
-	 */
-	gtk_signal_connect (obj, "button_press_event",
-			    GTK_SIGNAL_FUNC (panel_icon_list_button_press), panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "select_icon",
+			    GTK_SIGNAL_FUNC (panel_icon_list_select_icon),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "unselect_icon",
+			    GTK_SIGNAL_FUNC (panel_icon_list_unselect_icon),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "text_changed",
+			    GTK_SIGNAL_FUNC (panel_icon_renamed),
+			    panel);
 
-	gtk_signal_connect (obj, "button_release_event",
-			    GTK_SIGNAL_FUNC (panel_icon_list_button_release), panel);
+	/* Setup the icons and DnD */
 
-	gtk_signal_connect (obj, "motion_notify_event",
-			    GTK_SIGNAL_FUNC (panel_widget_motion), panel);
+	load_imlib_icons ();
+	load_dnd_icons ();
 
-#ifdef OLD_DND
-	/* DND: Drag setup */
-	gtk_signal_connect (obj, "drag_request_event", GTK_SIGNAL_FUNC (panel_icon_list_drag_request), panel);
-	gtk_signal_connect (obj, "drag_begin_event", GTK_SIGNAL_FUNC (panel_icon_list_drag_begin), panel);
-	gdk_window_dnd_drag_set (GTK_WIDGET (icon)->window,
-				 TRUE, drag_types, ELEMENTS (drag_types));
-	
-	/* DND: Drop setup */
-	gtk_signal_connect (obj, "drop_data_available_event",
-			    GTK_SIGNAL_FUNC (panel_icon_list_drop_data_available), panel);
-	
-	gtk_signal_connect (obj, "motion_notify_event",
-			    GTK_SIGNAL_FUNC (panel_icon_list_artificial_drag_start), panel);
-	gdk_window_dnd_drop_set (GTK_WIDGET (icon)->window, TRUE, drop_types, ELEMENTS (drop_types), FALSE);
-#endif
-}
+	gtk_drag_dest_set (GTK_WIDGET (ilist), GTK_DEST_DEFAULT_ALL,
+			   drop_types, ELEMENTS (drop_types),
+			   GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
 
-/*
- * Create and setup the icon field display
- */
-static GtkWidget *
-panel_create_icon_display (WPanel *panel)
-{
-	GnomeIconList *icon_field;
+	gtk_signal_connect (GTK_OBJECT (ilist), "drag_data_get",
+			    GTK_SIGNAL_FUNC (panel_drag_data_get),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "drag_data_delete",
+			    GTK_SIGNAL_FUNC (panel_drag_data_delete),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "drag_data_received",
+			    GTK_SIGNAL_FUNC (panel_icon_list_drag_data_received),
+			    panel);
 
-	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);
-	gnome_icon_list_set_icon_border (icon_field, 2);
-	gnome_icon_list_set_text_spacing (icon_field, 2);
-	
-	gnome_icon_list_set_selection_mode (icon_field, GTK_SELECTION_MULTIPLE);
-	GTK_WIDGET_SET_FLAGS (icon_field, GTK_CAN_FOCUS);
-	
-	gtk_signal_connect (
-		GTK_OBJECT (icon_field), "select_icon",
-		GTK_SIGNAL_FUNC (panel_icon_list_select_icon), panel);
-	gtk_signal_connect (
-		GTK_OBJECT (icon_field), "unselect_icon",
-		GTK_SIGNAL_FUNC (panel_icon_list_unselect_icon), panel);
-	gtk_signal_connect (
-		GTK_OBJECT (icon_field), "text_changed",
-		GTK_SIGNAL_FUNC (panel_icon_renamed), panel);
-	
-	gtk_signal_connect (
-		GTK_OBJECT (icon_field), "realize",
-		GTK_SIGNAL_FUNC (panel_icon_list_realized), panel);
+	/* These implement our drag-start activation code, as we have a pretty oveloaded widget */
 
-	gnome_icon_list_thaw (icon_field);
-	
-	return GTK_WIDGET (icon_field);
+	gtk_signal_connect (GTK_OBJECT (ilist), "button_press_event",
+			    GTK_SIGNAL_FUNC (panel_icon_list_button_press),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "button_release_event",
+			    GTK_SIGNAL_FUNC (panel_icon_list_button_release),
+			    panel);
+	gtk_signal_connect (GTK_OBJECT (ilist), "motion_notify_event",
+			    GTK_SIGNAL_FUNC (panel_widget_motion),
+			    panel);
+
+	gnome_icon_list_thaw (ilist);
+	return GTK_WIDGET (ilist);
 }
 
 void
@@ -2217,11 +2181,8 @@ x_create_panel (Dlg_head *h, widget_data parent, WPanel *panel)
 	if (!(panel->widget.options & W_PANEL_HIDDEN))
 		gtk_widget_show (gtk_widget_get_toplevel (panel->table));
 
-	if (!pixmaps_ready){
-		if (!GTK_WIDGET_REALIZED (panel->list))
-			gtk_widget_realize (panel->list);
-		panel_create_pixmaps (panel->list);
-	}
+	if (!pixmaps_ready)
+		panel_create_pixmaps ();
 
 	/* In GNOME the panel wants to have the cursor, to avoid "auto" focusing the
 	 * filter input line