/* Bluefish HTML Editor
 * interface.c - this file contains the UI code and some init code
 *
 * Copyright (C) 1998-1999 Olivier Sessink and Chris Mazuc
 * Copyright (C) 1999-2001 Olivier Sessink 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/* Changes by Antti-Juhani Kaijanaho <gaia@iki.fi> on 1999-10-20  */
#include "default_include.h"

#include <string.h>
#include <stdlib.h>
#include <sys/types.h>  /* opendir() */
#include <dirent.h>  /* opendir() */
#include <sys/stat.h> /* stat() */
#include <unistd.h>  /* stat() */
#include <stdio.h> /* rename() */
#include <errno.h>			/* errno */
#include <time.h> /* ctime() */
#include <pwd.h> /* getpwuid() */
#include <grp.h> /* getgrgid() */

#include "bluefish.h" /* identify_by_filename() */
#include "bf_lib.h"
#include "cap.h"  /* cap() */
#include "interface.h"
#include "highlight.h"  /* make syntax struct list */
#include "init.h"
#ifdef UNDO2
#include "undo2.h"
#else
#include "undo.h"
#endif /* UNDO2 */
#include "toolbars.h"
#include "images.h" /*preview_image_by_filename */
#include "callbacks.h"
#include "rpopup.h"
#include "document.h"
#include "menu.h"				/* add_to_recent_list */
#include "gtk_easy.h"
#include "network.h"
#include "stringlist.h" 	/* free_stringlist() */

#include "../pixmaps/bluefish_icon.xpm"
#include "../pixmaps/bluefish.xpm"

#ifdef WIN32
#define DIRSTR "\\"
#define DIRCHR 92
#else
#define DIRSTR "/"
#define DIRCHR '/'
#endif

typedef struct {
	GtkWidget *cust_handle_box;
	GtkWidget *handle_box;
	GtkWidget *html_handle_box;
	GtkWidget *filebrowse_box;
} Thidegui;

typedef enum {
TARGET_URI_LIST,
TARGET_STRING
} Tdnd_types;

static const GtkTargetEntry drag_source_types[] = {
	{ "text/uri-list", 0, TARGET_URI_LIST }
};
#define DRAG_SOURCE_NUM_TARGETS (sizeof(drag_source_types)/sizeof(GtkTargetEntry))

static const GtkTargetEntry drag_dest_types[] = {
	{ "text/uri-list", 0, TARGET_URI_LIST },
	{"STRING", 0, TARGET_STRING},
};
#define DRAG_DEST_NUM_TARGETS (sizeof(drag_dest_types)/sizeof(GtkTargetEntry))

/* local "global" variables */
static gint context_id = 0;
static Thidegui hidewidgets;

static char str[11];

/********************************************************************/

static void hide_gui(gint *configvar, GtkWidget *widget) {
	*configvar = 0;
	gtk_widget_hide(widget);
}

static void show_gui(gint *configvar, GtkWidget **widget, void func()) {
	*configvar = 1;
	if (g_list_length(gtk_container_children(GTK_CONTAINER(*widget))) == 0) {
		func(*widget);
	}
	gtk_widget_show(*widget);
}

void toggle_filebrowser_cb(GtkWidget * w, gpointer data) {
	if (main_v->filebrowser.hpane) {
		filebrowser_hide(0);
		main_v->props.v_filebrowser = 0;
	} else {
		filebrowser_show(0);
		main_v->props.v_filebrowser = 1;
	}
}

void toggle_cust_menubar_cb(GtkWidget * w, gpointer data) {
	if (GTK_WIDGET_VISIBLE(hidewidgets.cust_handle_box)) {
		hide_gui(&main_v->props.v_custom_tb, hidewidgets.cust_handle_box);
	} else {
		show_gui(&main_v->props.v_custom_tb, &hidewidgets.cust_handle_box, make_cust_menubar);
	}
}

void toggle_html_toolbar_cb(GtkWidget * w, gpointer data) {
	if (GTK_WIDGET_VISIBLE(hidewidgets.html_handle_box)) {
		hide_gui(&main_v->props.v_html_tb, hidewidgets.html_handle_box);
	} else {
		show_gui(&main_v->props.v_html_tb, &hidewidgets.html_handle_box, make_html_toolbar);
	}
}

void toggle_main_toolbar_cb(GtkWidget * w, gpointer data) {
	if (GTK_WIDGET_VISIBLE(hidewidgets.handle_box)) {
		hide_gui(&main_v->props.v_main_tb, hidewidgets.handle_box);
	} else {
		show_gui(&main_v->props.v_main_tb, &hidewidgets.handle_box, make_main_toolbar);
	}
}

/********************************************************************/




/* 
 * start of the functions
 * 
 */
/* I need the declaration over here */
static void add_to_dir_history(gchar *dirname);

void file_and_dir_history_add(gchar *filename) {
	gchar *dirname;

	add_to_recent_list(filename, 0); /* the recent menu */
	dirname = g_dirname(filename);
	add_to_dir_history(dirname);
	g_free(dirname);
}

void file_and_dir_history_remove(gchar *filename) {
	/* this function is not used yet */
}

gint statusbar_remove(gpointer message_id)
{
	gtk_statusbar_remove(GTK_STATUSBAR(main_v->statusbar), context_id, GPOINTER_TO_INT(message_id));
	return 0;
}


void statusbar_message(gpointer message, gint time)
{
	if (main_v->statusbar) {
		gint count;

		count = gtk_statusbar_push(GTK_STATUSBAR(main_v->statusbar), context_id, (gchar *) message);
		gtk_timeout_add(time, statusbar_remove, GINT_TO_POINTER(count));
		flush_queue();
	}
#ifdef DEVELOPMENT
	else {
		g_print("statusbar_message: %s\n", (gchar *)message);
	}
#endif
}

gint bf_statusbar_message(gpointer message)
{

	gint count;
	count = gtk_statusbar_push(GTK_STATUSBAR(main_v->statusbar), context_id, (gchar *) message);
	return count;
}

gboolean switch_to_document_by_index(gint index) {
	if (index >= 0) {
		DEBUG_MSG("switch_to_document_by_index, index=%d\n", index);
		gtk_notebook_set_page(GTK_NOTEBOOK(main_v->notebook), (index));
		notebook_changed();
		return TRUE;
	}
	return FALSE;
}

gboolean switch_to_document_by_pointer(Tdocument *document) {
	gint index;

	index = g_list_index(main_v->documentlist, document);
	return switch_to_document_by_index(index);
}

gboolean switch_to_document_by_filename(gchar *filename) {
	gint index;

	index = find_filename_in_documentlist(filename);
	return switch_to_document_by_index(index);
}

void notebook_next_document_cb(GtkWidget *widget, gpointer data) {
	gtk_notebook_next_page(GTK_NOTEBOOK(main_v->notebook));
	notebook_changed();
}

void notebook_prev_document_cb(GtkWidget *widget, gpointer data) {
	gtk_notebook_prev_page(GTK_NOTEBOOK(main_v->notebook));
	notebook_changed();
}

void notebook_changed(void)
{
	gint cur;

	/* This one is called when you click on the notebook
	   it _should_ be called also when you use the keys to change the page */
	cur = (gint) gtk_notebook_current_page(GTK_NOTEBOOK(main_v->notebook));
	if ((main_v->last_notebook_page == cur) 
		&& (main_v->current_document != NULL)
		&& (main_v->current_document == g_list_nth_data(main_v->documentlist, cur))) {
		DEBUG_MSG("notebook_changed, it didn't change to a new document (cur=%d, current_document=%p)\n", cur, main_v->current_document);
		return;
	} else {
		if (cur == -1) {
			doc_new();
			main_v->last_notebook_page = 0;
		} else {
			DEBUG_MSG("notebook_changed, it did really change to a new document, cur=%d\n", cur);
			main_v->last_notebook_page = cur;
			main_v->current_document = g_list_nth_data(main_v->documentlist, cur);
#ifdef DEVELOPMENT
			DEBUG_MSG("notebook_changed, finished, main_v->current_document=%p\n", main_v->current_document);			
			g_assert(main_v->current_document);
#endif
			notebook_switched_to_doc(main_v->current_document);
			DEBUG_MSG("notebook_changed, setting up toggle item\n");
			setup_toggle_item(gtk_item_factory_from_widget(main_v->menubar), N_("/View/Highlight syntax"),
							  main_v->current_document->highlightstate);
		}
	}
}


void notebook_set_tab_pos(gchar * position)
{
	if (position) {
		if (strcmp(position, "left") == 0) {
			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_v->notebook), GTK_POS_LEFT);
		} else if (strcmp(position, "right") == 0) {
			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_v->notebook), GTK_POS_RIGHT);
		} else if (strcmp(position, "top") == 0) {
			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_v->notebook), GTK_POS_TOP);
		} else {
			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_v->notebook), GTK_POS_BOTTOM);
		}
	}
}


/* 
   Passes drag-data to file_open or open_web if action== GDK_ACTION_COPY,
   else it inserts an <a href=""> or <img src=""> according to the filename
   extension.
 */


static void on_drag_data_cb(GtkWidget * widget, GdkDragContext * context
			, gint x, gint y, GtkSelectionData * data
			, guint info, guint time, void *client)
{
	gchar *tmp=NULL;
	gchar *filename, *url, *rel_filename=NULL;
	int mode = 0;
	gint type, action_is_open, url_is_local;

	if ((data->length == 0) || (data->format != 8) || ((info != TARGET_STRING) && (info != TARGET_URI_LIST))) {
		DEBUG_MSG("on_drag_data_cb, currently unknown DnD object, need to do string comparision\n");
		gtk_drag_finish(context, FALSE, TRUE, time);
		return;
	}

	/* netscape sends URL's labelled as string */
	if (info == TARGET_STRING) {
		gchar *stringdata = g_strndup(data->data, data->length);
		if (strchr(stringdata, ':')) {
			DEBUG_MSG("on_drag_data_cb, TARGET_STRING contains :, so it's probably an URL\n");
			info = TARGET_URI_LIST;
		}
		g_free(stringdata);
	}

	/* construct both filename and url from the given data */
	if (info == TARGET_STRING) {
		DEBUG_MSG("on_drag_data_cb, TARGET_STRING\n");
		filename = g_strndup(data->data, data->length);
		filename = trunc_on_char(trunc_on_char(filename, '\n'), '\r');
		url = g_strconcat("file:", filename, NULL);
		url_is_local = 1;
	} else { /* TARGET_UTI_LIST*/
		gchar *tmp2;
		gint len;

		DEBUG_MSG("on_drag_data_cb, TARGET_URI_LIST\n");
		url = g_strndup(data->data, data->length);
		url = trunc_on_char(trunc_on_char(url, '\n'), '\r');
		if (strncmp(url, "file:", 5) == 0) {
			gchar *tmp1;

			tmp1 = strchr(url, ':');
			tmp1++;
			len = strlen(tmp1);
			tmp2 = strrchr(url, '#');
			if (tmp2) {
				len -= strlen(tmp2);
			}
			filename = g_strndup(tmp1, len);
			url_is_local = 1;
		} else {
			len = strlen(url);
			tmp2 = strrchr(url, '#');
			if (tmp2) {
				len -= strlen(tmp2);
			}
			filename = g_strndup(url, len);
			url_is_local = 0;
		}
	}

	if (url_is_local && main_v->current_document->filename) {
		rel_filename = create_relative_link_to(main_v->current_document->filename
				, filename);
	}

	DEBUG_MSG("on_drag_data_cb, filename='%s', url='%s'\n", filename, url);

#ifdef DEBUG
	if (context->action == GDK_ACTION_MOVE) {
		g_print("GDK_ACTION_MOVE = %d\n", GDK_ACTION_MOVE);
	}
	if (context->action == GDK_ACTION_DEFAULT) {
		g_print("GDK_ACTION_DEFAULT = %d\n", GDK_ACTION_DEFAULT);
	}
	if (context->action == GDK_ACTION_COPY) {
		g_print("GDK_ACTION_COPY = %d\n", GDK_ACTION_COPY);
	}
	if (context->action == GDK_ACTION_LINK) {
		g_print("GDK_ACTION_LINK = %d\n", GDK_ACTION_LINK);
	}
	if (context->action == GDK_ACTION_PRIVATE) {
		g_print("GDK_ACTION_PRIVATE = %d\n", GDK_ACTION_PRIVATE);
	}
	if (context->action == GDK_ACTION_ASK) {
		g_print("GDK_ACTION_ASK = %d\n", GDK_ACTION_ASK);
	}
#endif
	
	type = identify_by_filename(filename);
	DEBUG_MSG("on_drag_data_cb, type=%d\n", type);
	/* this has to be extended for TYPE_JSCRIPT and TYPE_CSS */
	action_is_open =0;
	
	if ((context->action != GDK_ACTION_LINK) && (type==TYPE_HTML || type==TYPE_PHP || type==TYPE_JSCRIPT || type==TYPE_CSS) ) {
		action_is_open =1;
		if (url_is_local) {
			DEBUG_MSG("on_drag_data_cb, not LINK and text type --> opening local file");
			doc_new_with_file(filename);
		} else {
			DEBUG_MSG("on_drag_data_cb, not LINK and text type --> opening remote file");
			open_web(filename);
		}
	} else if (type == TYPE_HTML || type == TYPE_PHP || type== TYPE_UNKNOWN) {
		if (rel_filename) {
			tmp = g_strconcat("<a href=\"", rel_filename, "\"></a>", NULL);
		} else {
			tmp = g_strconcat("<a href=\"", url, "\"></a>", NULL);
		}
	} else if (type == TYPE_IMAGE) {
		DEBUG_MSG("on_drag_data_cb, ends in .gif,.jpg,.jpeg,.png\n");
		if (rel_filename) {
			tmp = g_strconcat("<img src=\"", rel_filename, "\" border=\"0\" alt=\"\"", main_v->props.xhtml == 1 ? " />" : ">", NULL);
		} else {
			tmp = g_strconcat("<img src=\"", url, "\" border=\"0\" alt=\"\"", main_v->props.xhtml == 1 ? " />" : ">", NULL);
		}
	} else if (type == TYPE_CSS) {
		DEBUG_MSG("on_drag_data_cb, type is TYPE_CSS\n");
		if (rel_filename) {
			tmp = g_strconcat("<link rel=\"stylesheet\" href=\"", rel_filename, "\" type=\"text/css\"", main_v->props.xhtml == 1 ? " />" : ">", NULL);
		} else {
			tmp = g_strconcat("<link rel=\"stylesheet\" href=\"", url, "\" type=\"text/css\"", main_v->props.xhtml == 1 ? " />" : ">", NULL);
		}
		DEBUG_MSG("on_drag_data_cb, string=%s\n", tmp);
	} else if (type == TYPE_JSCRIPT) {
		if (rel_filename) {
			tmp = g_strconcat("<script language=\"javascript\" type=\"text/javascript\" src=\"", rel_filename, "\"></script>", NULL);
		} else {
			tmp = g_strconcat("<script language=\"javascript\" type=\"text/javascript\" src=\"", url, "\"></script>", NULL);
		}
	} else {
		DEBUG_MSG("on_drag_data_cb, unknown file format\n");
		tmp = g_strdup(filename);
	}
	if (tmp) {
		DEBUG_MSG("on_drag_data_cb, editable pos=%d\n", gtk_editable_get_position(GTK_EDITABLE(main_v->current_document->textbox)));
		if (main_v->props.drop_at_drop_pos) {
			/* it seems like x and y are relative to the top window
			and not to the widget....... how to solve this? */
			gint pos = doc_xy_to_cursor_pos(main_v->current_document, x, y);
			DEBUG_MSG("on_drag_data_cb, x=%d, y=%d, pos=%d, length=%d\n", x, y, pos, gtk_text_get_length(GTK_TEXT(main_v->current_document->textbox)));
			gtk_text_set_point(GTK_TEXT(main_v->current_document->textbox), pos);
			gtk_editable_set_position(GTK_EDITABLE(main_v->current_document->textbox), pos);
		} else {
			gtk_text_set_point(GTK_TEXT(main_v->current_document->textbox),
					   gtk_editable_get_position(GTK_EDITABLE(main_v->current_document->textbox)));
		}
		insert_dbl_text(tmp, NULL);
		g_free(tmp);
	}
	gtk_drag_finish(context, TRUE, (mode == GDK_ACTION_COPY), time);
	g_free(filename);
	if (rel_filename) {
		g_free(rel_filename);
	}
	g_free(url);

}

typedef struct {
	GtkWidget *win;
	GtkWidget *entry;
	gint is_file;
} Tcfod;

/* declaration needed here */
static void browse_to_dir(gchar *dirname);
static void file_list_rpopup_refresh(GtkWidget *widget, gpointer data);

static void create_file_or_dir_destroy_lcb(GtkWidget *widget, GdkEvent *event,Tcfod *ws) {
	window_destroy(ws->win);
	g_free(ws);
}

static void create_file_or_dir_cancel_clicked_lcb(GtkWidget *widget, Tcfod *ws) {
	create_file_or_dir_destroy_lcb(NULL, NULL, ws);
}

static void create_file_or_dir_ok_clicked_lcb(GtkWidget *widget, Tcfod *ws) {
	gchar *newname, *name;

	name = gtk_editable_get_chars(GTK_EDITABLE(ws->entry), 0, -1);	
	if (name) {
		if (strlen(name)) {
			newname = g_strconcat(main_v->filebrowser.curdir,DIRSTR,name, NULL);
			DEBUG_MSG("create_file_or_dir_ok_clicked_lcb, newname=%s\n", newname);
			if (file_exists_and_readable(newname)) {
				error_dialog(_("Error creating path"),_("Path exists already"));
			} else {
				if (ws->is_file) {
					doc_new_with_new_file(newname);
				} else {
					if(mkdir(newname, 0755)== -1) {
						error_dialog(_("Error creating directory"),strerror(errno));
					}
				}
			}
			g_free(newname);
			file_list_rpopup_refresh(NULL, NULL);
		}
		g_free(name);
	}
	create_file_or_dir_destroy_lcb(NULL, NULL, ws);
}

static void create_file_or_dir_win(gint is_file) {
	Tcfod *ws;
	gchar *title;
	GtkWidget *vbox, *but, *hbox;

	ws = g_malloc(sizeof(Tcfod));
	if (is_file) {
		title = _("File name");
	} else {
		title = _("Directory name");
	}
	ws->is_file = is_file;
	
	ws->win = window_full(title, GTK_WIN_POS_MOUSE, GTK_WINDOW_DIALOG
	, 5,create_file_or_dir_destroy_lcb , ws);
	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(ws->win), vbox);
	ws->entry = boxed_entry_with_text(NULL, 250, vbox);
	
	hbox = gtk_hbutton_box_new();
	gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_END);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 1);
	
	but = bf_stock_ok_button(create_file_or_dir_ok_clicked_lcb, ws);
	gtk_box_pack_start(GTK_BOX(hbox),but , FALSE, FALSE, 0);
	
	but = bf_stock_cancel_button(create_file_or_dir_cancel_clicked_lcb, ws);
	gtk_box_pack_start(GTK_BOX(hbox),but , FALSE, FALSE, 0);
	
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
	
	gtk_widget_grab_focus(ws->entry);
	gtk_widget_show_all(GTK_WIDGET(ws->win));
}

static void create_file_lcb(GtkWidget *widget, gpointer data) {
	create_file_or_dir_win(1);
}

static void create_directory_lcb(GtkWidget *widget, gpointer data) {
	create_file_or_dir_win(0);
}

static void dir_history_activate_lcb(GtkWidget *widget, gpointer data) {

	DEBUG_MSG("dir_history_activate_lcb, widget=%p, data=%p\n", widget, data);
	if (data) {
		browse_to_dir((gchar *)data);
	}
}

static void add_string_to_menu(GtkWidget *menu, gchar *string) {
	gchar *dir;
	GtkWidget *menuitem;
	
	dir = g_strdup(string);
	menuitem = gtk_menu_item_new_with_label(dir);
	gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
			      (GtkSignalFunc) dir_history_activate_lcb,
			      (gpointer) dir);
	gtk_menu_append(GTK_MENU(menu), menuitem);
	main_v->filebrowser.dir_history_menu = g_list_append(main_v->filebrowser.dir_history_menu, dir);
	gtk_widget_show(menuitem);
}

static void dir_history_open() {
	gchar *filename = g_strconcat(g_get_home_dir(), "/.bluefish/dir_history", NULL);
	main_v->filebrowser.directory_history = get_stringlist(filename, NULL);
	g_free(filename);
}

static void dir_history_save() {
	gchar *filename = g_strconcat(g_get_home_dir(), "/.bluefish/dir_history", NULL);
	put_stringlist(filename, main_v->filebrowser.directory_history);
	g_free(filename);
}

static void add_to_dir_history(gchar *dirname) {
	gchar *tmpstr;
	if (!dirname) {
		return;
	}
	DEBUG_MSG("add_to_dir_history, checking in %s\n", dirname);	
	if (dirname[strlen(dirname)] != DIRCHR) {
		tmpstr = g_strconcat(dirname, DIRSTR, NULL);
	} else {
		tmpstr = g_strdup(dirname);
	}

	main_v->filebrowser.directory_history = add_to_stringlist(main_v->filebrowser.directory_history, tmpstr);
	g_free(tmpstr);

	if (g_list_length(main_v->filebrowser.directory_history) > main_v->props.max_dir_history) {
		GList *link = g_list_first(main_v->filebrowser.directory_history);
		DEBUG_MSG("add_to_dir_history, too long, removing!\n");
		main_v->filebrowser.directory_history = g_list_remove_link(main_v->filebrowser.directory_history, link);
	}
	dir_history_save();
}


void populate_dir_history() {
	GtkWidget *menu;
	gchar *tmpchar, *tmpdir;
	GList *tmplist;
	GList *new_history_list=NULL;
	DEBUG_MSG("populate_dir_history, empty\n");

	gtk_option_menu_remove_menu(GTK_OPTION_MENU(main_v->filebrowser.dir_history));
	free_stringlist(main_v->filebrowser.dir_history_menu);
	main_v->filebrowser.dir_history_menu = NULL;
	
	menu = gtk_menu_new();
	gtk_option_menu_set_menu(GTK_OPTION_MENU(main_v->filebrowser.dir_history), menu);
	gtk_widget_show(menu);

	if (!main_v->filebrowser.curdir) {
		main_v->filebrowser.curdir = g_strdup(g_get_current_dir());
	}

	tmpdir = g_strconcat(main_v->filebrowser.curdir, DIRSTR, NULL);
	new_history_list = add_to_stringlist(new_history_list, tmpdir);
	while ((tmpchar = strrchr(tmpdir, DIRCHR))) {
		tmpchar++;
		*tmpchar = '\0';
		DEBUG_MSG("populate_dir_history, adding %s\n", tmpdir);
		new_history_list = add_to_stringlist(new_history_list, tmpdir);
		tmpchar--;
		*tmpchar = '\0';
	}
	g_free(tmpdir);
	
	tmpdir = g_strconcat(g_get_current_dir(), DIRSTR, NULL);
	new_history_list = add_to_stringlist(new_history_list, tmpdir);
	g_free(tmpdir);

	tmpdir = g_strconcat(g_get_home_dir(), DIRSTR, NULL);
	new_history_list = add_to_stringlist(new_history_list, tmpdir);
	g_free(tmpdir);

	tmplist = g_list_last(main_v->filebrowser.directory_history);
	while (tmplist) {
		new_history_list = add_to_stringlist(new_history_list, (gchar *)tmplist->data);
		tmplist = g_list_previous(tmplist);
	} 

	/* make the actual option menu */
	tmplist = g_list_first(new_history_list);
	while (tmplist) {
		DEBUG_MSG("populate_dir_history, adding %s to menu\n", (gchar *)tmplist->data);
		add_string_to_menu(menu, (gchar *)tmplist->data);
		g_free(tmplist->data);
		tmplist = g_list_next(tmplist);
	} 
	g_list_free(new_history_list);

	gtk_option_menu_set_history(GTK_OPTION_MENU(main_v->filebrowser.dir_history), 0);
}

#include "../pixmaps/open_small.xpm"
#include "../pixmaps/image_file.xpm"
#include "../pixmaps/html_file.xpm"
#include "../pixmaps/unknown_file.xpm"
#include "../pixmaps/php_file.xpm"
#include "../pixmaps/jscript_file.xpm"
#include "../pixmaps/css_file.xpm"

void populate_dir_file_list() {
	DIR *dp;
	struct dirent *ep;
	struct stat statbuf;
	gchar *text[1];
	gint valid_types[TYPES_COUNT] = {0,0,0,0,0,0,0,0};

	DEBUG_MSG("populate_dir_file_list, started\n");

	switch (main_v->filebrowser.filter_type) {
		case FILTER_ALL:
		valid_types[TYPE_UNKNOWN] = 1;
		valid_types[TYPE_IMAGE] = 1;
		valid_types[TYPE_PHP] = 1;
		valid_types[TYPE_HTML] = 1;
		valid_types[TYPE_JSCRIPT] = 1;
		valid_types[TYPE_CSS] = 1;
		valid_types[TYPE_OTHER] = 1;
		break;
		case FILTER_WEB:
		valid_types[TYPE_IMAGE] = 1;
		valid_types[TYPE_PHP] = 1;
		valid_types[TYPE_HTML] = 1;	
		valid_types[TYPE_JSCRIPT] = 1;
		valid_types[TYPE_CSS] = 1;
		valid_types[TYPE_OTHER] = 1;
		break;
		case FILTER_IMAGES:
		valid_types[TYPE_IMAGE] = 1;
		break;
		case FILTER_DOCUMENTS:
		valid_types[TYPE_PHP] = 1;
		valid_types[TYPE_HTML] = 1;
		break;
	}
	
	gtk_clist_freeze(GTK_CLIST(main_v->filebrowser.dir_list));
	gtk_clist_freeze(GTK_CLIST(main_v->filebrowser.file_list));

	dp = opendir("./");
	if (dp != NULL) {
		GdkPixmap *pixm[TYPES_COUNT];
		GdkBitmap *mask[TYPES_COUNT];
		gint i;

		pixm[TYPE_UNKNOWN] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_UNKNOWN], NULL, unknown_file_xpm);
		pixm[TYPE_IMAGE] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_IMAGE], NULL, image_file_xpm);
		pixm[TYPE_PHP] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_PHP], NULL, php_file_xpm);
		pixm[TYPE_HTML] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_HTML], NULL, html_file_xpm);
		pixm[TYPE_DIR] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_DIR], NULL, open_small_xpm);
		pixm[TYPE_JSCRIPT] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_JSCRIPT], NULL, jscript_file_xpm);
		pixm[TYPE_CSS] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_CSS], NULL, css_file_xpm);
		pixm[TYPE_OTHER] = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &mask[TYPE_OTHER], NULL, unknown_file_xpm);

		if (main_v->filebrowser.curdir) {
			g_free(main_v->filebrowser.curdir);
		}
		main_v->filebrowser.curdir = g_strdup(g_get_current_dir());

		gtk_clist_clear(GTK_CLIST(main_v->filebrowser.dir_list));
		gtk_clist_clear(GTK_CLIST(main_v->filebrowser.file_list));
		while ((ep = readdir(dp))) {
			gint row;

			stat(ep->d_name, &statbuf);
			if (S_ISDIR(statbuf.st_mode)) {
				gchar *tmpstr;

				tmpstr = g_strconcat(ep->d_name, DIRSTR, NULL);
				text[0] = tmpstr;
				row = gtk_clist_append(GTK_CLIST(main_v->filebrowser.dir_list), text);
				gtk_clist_set_pixtext(GTK_CLIST(main_v->filebrowser.dir_list)
						, row, 0, tmpstr, 2, pixm[TYPE_DIR], mask[TYPE_DIR]);
				g_free(tmpstr);
			} else {
				gint type;

				type = identify_by_filename(ep->d_name);
				if (valid_types[type] == 1) {
					text[0] = ep->d_name;
					row = gtk_clist_append(GTK_CLIST(main_v->filebrowser.file_list), text);
					gtk_clist_set_pixtext(GTK_CLIST(main_v->filebrowser.file_list)
						, row, 0, ep->d_name, 2, pixm[type], mask[type]);
				}
			}
		}
		closedir(dp);
		
		for (i= 0; i< TYPES_COUNT ; i++) {
			gdk_pixmap_unref(pixm[i]);
			gdk_bitmap_unref(mask[i]);
		}
	}
	gtk_clist_sort(GTK_CLIST(main_v->filebrowser.dir_list));
	gtk_clist_sort(GTK_CLIST(main_v->filebrowser.file_list));

	main_v->filebrowser.file_list_selectedrow = -1;
	gtk_clist_select_row(GTK_CLIST (main_v->filebrowser.dir_list), 0,0);

	gtk_clist_thaw(GTK_CLIST(main_v->filebrowser.dir_list));
	gtk_clist_thaw(GTK_CLIST(main_v->filebrowser.file_list));
}

static void file_list_rpopup_refresh(GtkWidget *widget, gpointer data) {
	populate_dir_file_list();
}

static void dir_list_activate_row(gint row) {
	gchar *temp=NULL;
	guint8 spacing;
	GdkPixmap *pixmap;
	GdkBitmap *bitmap;

	gtk_clist_get_pixtext (GTK_CLIST (main_v->filebrowser.dir_list), row, 0, &temp, &spacing, &pixmap, &bitmap);
	if (temp) {
		gchar *dirname = g_strconcat(main_v->filebrowser.curdir, DIRSTR, temp, NULL);
		DEBUG_MSG("dir_list_activate_row, change to %s\n", dirname);
		browse_to_dir(dirname);
		g_free (dirname);
	}
}

static void dir_list_select_lcb(GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,gpointer user_data) {

	DEBUG_MSG("dir_list_clicked_lcb, started on row %d\n", row);
	main_v->filebrowser.dir_list_lastrow = row;
	if (bevent && (bevent->type == GDK_2BUTTON_PRESS)) {
		dir_list_activate_row(row);
	}
}

static gchar *filebrowser_get_filename_from_row(gint row) {
	if (row != -1) {
		gchar *temp=NULL;
		guint8 spacing;
		GdkPixmap *pixmap;
		GdkBitmap *bitmap;

		gtk_clist_get_pixtext (GTK_CLIST (main_v->filebrowser.file_list), row, 0, &temp, &spacing, &pixmap, &bitmap);
		if (temp && strlen(temp)) {
			DEBUG_MSG("filebrowser_get_filename_from_row, found filename %s\n", temp);
			return g_strconcat(main_v->filebrowser.curdir, DIRSTR, temp, NULL);
		}
#ifdef DEBUG
		else {
			g_print("filebrowser_get_filename_from_row, no temp, or no strlen(temp)\n");
		}
#endif
	}
#ifdef DEBUG
	else {
	g_print("filebrowser_get_filename_from_row, no row\n");	
	}
#endif
	return NULL;
}

static void filebrowser_file_open_lcb(GtkWidget *widget, gpointer data) {
	gchar *filename;
	
	filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (filename) {
		doc_new_with_file(filename);
		g_free(filename);
	}
}
#ifdef HAVE_IMAGE_LIBS
static void filebrowser_preview_image_lcb(GtkWidget *widget, gpointer data) {
	gchar *filename;
	
	filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (filename) {
		DEBUG_MSG("filebrowser_preview_image_lcb, previewing %s\n", filename);
		preview_image_by_filename (filename);
		g_free(filename);
	}
}
#endif /* HAVE_IMAGE_LIBS */
static void filebrowser_edit_image_lcb(GtkWidget *widget, gpointer data) {
	gchar *filename;
	
	filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (filename) {
		open_image_in_editor(filename);
		g_free(filename);
	}
}

static void filebrowser_file_delete_lcb(GtkWidget *widget, gpointer data) {
	gchar *filename;
	
	filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (filename) {
		gchar *buttons[] = {N_("Delete"), N_("Cancel"), NULL};
		gchar *label;
		gint retval;
		label = g_strdup_printf(_("Are you sure you want to\ndelete %s?"), filename);
		retval = multi_button_dialog(_("delete file?"), 1, label, buttons);
		g_free(label);
		if (retval == 0) {
			DEBUG_MSG("file_list_rpopup_file_delete %s\n", filename);
			unlink(filename);
			populate_dir_file_list();
		}
		g_free(filename);
	}
}

static void rwx (short unsigned int bits, char *chars)
{
  chars[0] = (bits & S_IRUSR) ? 'r' : '-';
  chars[1] = (bits & S_IWUSR) ? 'w' : '-';
  chars[2] = (bits & S_IXUSR) ? 'x' : '-';
}

static void setst (short unsigned int bits, char *chars)
{
#ifdef S_ISUID
  if (bits & S_ISUID)
    {
      if (chars[3] != 'x')
	/* Set-uid, but not executable by owner.  */
	chars[3] = 'S';
      else
	chars[3] = 's';
    }
#endif
#ifdef S_ISGID
  if (bits & S_ISGID)
    {
      if (chars[6] != 'x')
	/* Set-gid, but not executable by group.  */
	chars[6] = 'S';
      else
	chars[6] = 's';
    }
#endif
#ifdef S_ISVTX
  if (bits & S_ISVTX)
    {
      if (chars[9] != 'x')
	/* Sticky, but not executable by others.  */
	chars[9] = 'T';
      else
	chars[9] = 't';
    }
#endif
}

static void filemode_to_string(mode_t statmode) {
 	/* following code "adapted" from GNU filemode.c program */

str[0]='?';
#ifdef S_ISBLK
  if (S_ISBLK (statmode))
    str[0]='b';
#endif
  if (S_ISCHR (statmode))
    str[0]='c';
  if (S_ISDIR (statmode))
    str[0]='d';
  if (S_ISREG (statmode))
    str[0]='-';
#ifdef S_ISFIFO
  if (S_ISFIFO (statmode))
    str[0]='p';
#endif
#ifdef S_ISLNK
  if (S_ISLNK (statmode))
    str[0]='l';
#endif
#ifdef S_ISSOCK
  if (S_ISSOCK (statmode))
    str[0]='s';
#endif
#ifdef S_ISMPC
  if (S_ISMPC (statmode))
    str[0]='m';
#endif
#ifdef S_ISNWK
  if (S_ISNWK (statmode))
    str[0]='n';
#endif
rwx ((statmode & 0700) << 0, &str[1]);
rwx ((statmode & 0070) << 3, &str[4]);
rwx ((statmode & 0007) << 6, &str[7]);
setst (statmode, str);
}


static void filebrowser_properties_lcb(GtkWidget *widget, gpointer data) {
	gchar *filename;
	struct stat fileinfo;
	struct passwd *uinfo;
	struct group *ginfo;
	filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (filename) {
		gchar *label, *head;
    
    DEBUG_MSG("stat(2) start\n");
    
    if (stat(filename,&fileinfo) == 0) {
      uinfo = getpwuid(fileinfo.st_uid);
#ifndef WIN32
      ginfo = getgrgid(fileinfo.st_gid);
#endif
	  filemode_to_string(fileinfo.st_mode);
#ifndef WIN32
	  label = g_strdup_printf(_("Size: %lu\nLast Modification: %sLast access: %sUser: %s\nGroup: %s\nMode: %s\n"),(long)fileinfo.st_size, 
        ctime(&(fileinfo.st_mtime)), ctime(&(fileinfo.st_atime)),uinfo->pw_name, ginfo->gr_name,str);
			head = g_strdup_printf(_("Properties of %s"),filename);
#else
	  label = g_strdup_printf(_("Size: %lu\nLast Modification: %sLast access: %sUser: %s\nMode: %s\n"),(long)fileinfo.st_size, 
        ctime(&(fileinfo.st_mtime)), ctime(&(fileinfo.st_atime)),uinfo->pw_name, str);
			head = g_strdup_printf(_("Properties of %s"),filename);

#endif
			error_dialog(head, label);
			g_free(label);
			g_free(head);
    } else {
      error_dialog(_("Error!"),_("Could not stat(2) file."));
    }
		g_free(filename);
	}
}

static void file_list_rpopup_filter(GtkWidget *widget, gpointer filter_type) {
	main_v->filebrowser.filter_type = (Tfilebrowser_filter) GPOINTER_TO_INT(filter_type);
	populate_dir_file_list();
}

static void filebrowser_file_move_or_save_as(gint is_move) {
	gchar *oldfilename, *newfilename;
	oldfilename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
	if (oldfilename) {
		
		gboolean res;
		res = switch_to_document_by_filename(oldfilename);
		if (res) {
			flush_queue();
			doc_save(main_v->current_document, 1, is_move);
			populate_dir_file_list();
		} else { /* the document is not open */
			gchar *tmplabel;
			if (is_move) {
				tmplabel = _("Move file to");
			} else {
				tmplabel = _("Copy file to");
			}
			newfilename = return_file_w_title(oldfilename, tmplabel);
			if (newfilename) {
				if (is_move) {
					gint result;
					result = rename(oldfilename, newfilename);
					if (result != -1) {
						statusbar_message(_("Move file succeeded"), NORMAL_MESSAGE);
						if (main_v->props.link_management) {
							DEBUG_MSG("filebrowser_file_move_lcb, calling all_documents_update_links using old=%s and new=%s\n", oldfilename, newfilename);
							all_documents_update_links(NULL, oldfilename,newfilename);
							populate_dir_file_list();
						}
					} else {
						statusbar_message(_("Move file failed"), 6000);
					}
				} else {/* save as */
					gboolean result;
					result = file_copy(oldfilename, newfilename);
					if (result) {
						statusbar_message(_("Copying file succeeded"), NORMAL_MESSAGE);
					} else {
						statusbar_message(_("Copying file failed"), IMPORTANT_MESSAGE);
					}
				}
			}
		}
	}
}

static void filebrowser_file_move_lcb(GtkWidget *widget, gpointer data) {
	filebrowser_file_move_or_save_as(1);
}
static void filebrowser_file_save_as_lcb(GtkWidget *widget, gpointer data) {
	filebrowser_file_move_or_save_as(0);
}

static GtkWidget *file_list_rpopup_create_menu()
{
	GtkWidget *menu_item;
	GtkWidget *menu, *fmenu;
	GtkWidget *fmenu_item[4];
	GSList *group;

	menu = gtk_menu_new();
	
	menu_item = gtk_menu_item_new_with_label(_("File new"));
	gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(create_file_lcb), NULL);
	gtk_menu_append(GTK_MENU(menu), menu_item);
	if (main_v->filebrowser.file_list_selectedrow != -1) {
		/* a file is selected */
		menu_item = gtk_menu_item_new_with_label(_("File open"));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_file_open_lcb), NULL);
		gtk_menu_append(GTK_MENU(menu), menu_item);
		
		menu_item = gtk_menu_item_new_with_label(_("File move to"));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_file_move_lcb), NULL);
		gtk_menu_append(GTK_MENU(menu), menu_item);
		menu_item = gtk_menu_item_new_with_label(_("File save as"));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_file_save_as_lcb), NULL);
		gtk_menu_append(GTK_MENU(menu), menu_item);
		menu_item = gtk_menu_item_new_with_label(_("File delete"));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_file_delete_lcb), NULL);
		gtk_menu_append(GTK_MENU(menu), menu_item);
	}
	menu_item = gtk_menu_item_new_with_label(_("Create directory"));
	gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(create_directory_lcb), NULL);
	gtk_menu_append(GTK_MENU(menu), menu_item);
	if (main_v->filebrowser.file_list_selectedrow != -1) {
		gchar *filename;
		/* insert a separator */
		menu_item = gtk_menu_item_new();
		gtk_menu_append(GTK_MENU(menu), menu_item);
		menu_item = gtk_menu_item_new_with_label(_("Properties"));
		gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_properties_lcb), NULL);
		gtk_menu_append(GTK_MENU(menu), menu_item);
		
		filename = filebrowser_get_filename_from_row(main_v->filebrowser.file_list_selectedrow);
		if (identify_by_filename(filename) == TYPE_IMAGE) {
#ifdef HAVE_IMAGE_LIBS
			menu_item = gtk_menu_item_new_with_label(_("Preview image"));
			gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_preview_image_lcb), NULL);
			gtk_menu_append(GTK_MENU(menu), menu_item);
#endif
			menu_item = gtk_menu_item_new_with_label(_("Edit image"));
			gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(filebrowser_edit_image_lcb), NULL);
			gtk_menu_append(GTK_MENU(menu), menu_item);
		}
		g_free(filename);
	}
	/* insert a separator */
	menu_item = gtk_menu_item_new();
	gtk_menu_append(GTK_MENU(menu), menu_item);
	
	menu_item = gtk_menu_item_new_with_label(_("Refresh file browser"));
	gtk_signal_connect(GTK_OBJECT(menu_item), "activate", GTK_SIGNAL_FUNC(file_list_rpopup_refresh), NULL);
	gtk_menu_append(GTK_MENU(menu), menu_item);
	menu_item = gtk_menu_item_new_with_label(_("Filter file browser"));
	gtk_menu_append(GTK_MENU(menu), menu_item);
	fmenu = gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), fmenu);
	
	fmenu_item[0] = gtk_radio_menu_item_new_with_label(NULL, _("all files"));

	if (main_v->filebrowser.filter_type == FILTER_ALL) {
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (fmenu_item[0]), TRUE);
 	}
	gtk_menu_append(GTK_MENU(fmenu), fmenu_item[0]);

	group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(fmenu_item[0]));

	fmenu_item[1] = gtk_radio_menu_item_new_with_label(group, _("all web files"));
	if (main_v->filebrowser.filter_type == FILTER_WEB) {
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (fmenu_item[1]), TRUE);
 	}
	gtk_menu_append(GTK_MENU(fmenu), fmenu_item[1]);

	fmenu_item[2] = gtk_radio_menu_item_new_with_label(group, _("images"));
	if (main_v->filebrowser.filter_type == FILTER_IMAGES) {
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (fmenu_item[2]), TRUE);
 	}
	gtk_menu_append(GTK_MENU(fmenu), fmenu_item[2]);

	fmenu_item[3] = gtk_radio_menu_item_new_with_label(group, _("documents"));
	if (main_v->filebrowser.filter_type == FILTER_DOCUMENTS) {
		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (fmenu_item[3]), TRUE);
 	}
	gtk_menu_append(GTK_MENU(fmenu), fmenu_item[3]);

	gtk_signal_connect(GTK_OBJECT(fmenu_item[0]), "toggled", GTK_SIGNAL_FUNC(file_list_rpopup_filter), GINT_TO_POINTER((gint)FILTER_ALL));
	gtk_signal_connect(GTK_OBJECT(fmenu_item[1]), "toggled", GTK_SIGNAL_FUNC(file_list_rpopup_filter), GINT_TO_POINTER((gint)FILTER_WEB));
	gtk_signal_connect(GTK_OBJECT(fmenu_item[2]), "toggled", GTK_SIGNAL_FUNC(file_list_rpopup_filter), GINT_TO_POINTER((gint)FILTER_IMAGES));
	gtk_signal_connect(GTK_OBJECT(fmenu_item[3]), "toggled", GTK_SIGNAL_FUNC(file_list_rpopup_filter), GINT_TO_POINTER((gint)FILTER_DOCUMENTS));

	gtk_widget_show_all(menu);
	return menu;
}

static void file_list_button_press_lcb(GtkWidget *widget
			, GdkEventButton *event, gpointer data) {
	gint row=-1, col=-1;

	gtk_clist_get_selection_info(GTK_CLIST(widget),event->x, event->y, &row, &col );

	if (row != -1) {
		main_v->filebrowser.file_list_lastrow = row;
	}
	if (event->button == 3) {
		GtkWidget *menu;
		DEBUG_MSG("file_list_button_press_lcb, right-click\n");
		menu = file_list_rpopup_create_menu();
		gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
	}
}

static void file_list_unselect_lcb(GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,gpointer user_data) {
	DEBUG_MSG("file_list_select_lcb, unselected row %d\n", row);
	main_v->filebrowser.file_list_selectedrow = -1;
}

static void file_list_select_lcb(GtkWidget *widget, gint row, gint column, GdkEventButton *bevent,gpointer user_data) {
	gchar *filename;
	
	main_v->filebrowser.file_list_lastrow = row;
	main_v->filebrowser.file_list_selectedrow = row;
	DEBUG_MSG("file_list_select_lcb, selected row %d\n", row);
	filename = filebrowser_get_filename_from_row(row);
	if (filename && bevent) {
		if (bevent->type == GDK_2BUTTON_PRESS) {
			gint type = identify_by_filename(filename);
			DEBUG_MSG("file_list_clicked_lcb, clicked %s\n", filename);			
			if (type == TYPE_IMAGE) {
				gchar *newstring;
				if (main_v->current_document && main_v->current_document->filename) {
					gchar *relpath = create_relative_link_to(main_v->current_document->filename, filename);
					newstring = g_strconcat(cap("<img src=\""), relpath, cap("\" border=\"0\">"), NULL);
					g_free(relpath);
				} else {
					newstring = g_strconcat(cap("<img src=\""), filename, cap("\" border=\"0\">"), NULL);
				}
				gtk_text_set_point(GTK_TEXT(main_v->current_document->textbox),
						   gtk_editable_get_position(GTK_EDITABLE(main_v->current_document->textbox)));
				insert_dbl_text(newstring, NULL);
			} else if (type == TYPE_PHP || type == TYPE_HTML || type == TYPE_JSCRIPT || type == TYPE_CSS || type == TYPE_UNKNOWN || type == TYPE_OTHER) {
				doc_new_with_file(filename);
			}
		}
	}
	g_free (filename);
}

static void browse_to_dir(gchar *dirname) {
	chdir(dirname);
	populate_dir_file_list();
	populate_dir_history();
}

void filelist_set_size() {
	gtk_widget_set_usize (main_v->filebrowser.dir_list, main_v->props.main_filelist_size,  main_v->props.main_filelist_size);
	gtk_widget_set_usize (main_v->filebrowser.file_list, main_v->props.main_filelist_size,  main_v->props.main_filelist_size);
}

static void file_list_drag_begin_lcb(GtkWidget *widget, GdkDragContext *context, gpointer data) {
	DEBUG_MSG("file_list_drag_begin_lcb, started\n");

	gtk_clist_select_row(GTK_CLIST(main_v->filebrowser.file_list), main_v->filebrowser.file_list_lastrow, 0);

}
static gboolean file_list_drag_motion_lcb(GtkWidget *widget, GdkDragContext *context
		, gint x, gint y, guint time,gpointer data) {
	GtkWidget *wid;
	GdkDragAction action;

	DEBUG_MSG("file_list_drag_motion_lcb, started\n");
	wid = gtk_drag_get_source_widget(context);
	if(wid && (context->suggested_action != GDK_ACTION_LINK)) {
		DEBUG_MSG("file_list_drag_motion_lcb, forced GDK_ACTION_LINK\n");
		action = GDK_ACTION_LINK; 
	} else {
		DEBUG_MSG("file_list_drag_motion_lcb, using suggested action\n");
		action = context->suggested_action;
	}

	gdk_drag_status(context, action, time);
	/* tell the handler we have not handled the event 100%, so pass it on */
	return FALSE;
}

static void file_list_drag_data_get_lcb( GtkWidget *widget, GdkDragContext *context,
					GtkSelectionData *selectionData, guint info,
					guint time, gpointer data) {

	gchar *temp=NULL, *filename=NULL;
	guint8 spacing;
	GdkPixmap *pixmap;
	GdkBitmap *bitmap;

	gtk_clist_get_pixtext (GTK_CLIST (main_v->filebrowser.file_list), main_v->filebrowser.file_list_lastrow, 0, &temp, &spacing, &pixmap, &bitmap);
	if (strlen(temp) < 1) {
		return;
	}
	switch( info ) {
		case TARGET_STRING:
			DEBUG_MSG("file_list_drag_data_get_lcb, TARGET_STRING wanted\n");
			filename = g_strconcat(main_v->filebrowser.curdir, DIRSTR, temp, NULL);
			break;
		case TARGET_URI_LIST:
			DEBUG_MSG("file_list_drag_data_get_lcb, TARGET_URI_LIST wanted\n");
			filename = g_strconcat("file:", main_v->filebrowser.curdir, DIRSTR, temp, "\r\n", NULL);
			break;
		default:
			filename = g_strconcat("file:", main_v->filebrowser.curdir, DIRSTR, temp, "\r\n", NULL);		
			break;
		}
	gtk_selection_data_set( selectionData, selectionData->target,8, filename, strlen(filename));
	g_free(filename);
}			

static gboolean dir_list_key_press_lcb(GtkWidget *widget, GdkEventKey *event, gpointer data) {
/* this value is just try-and-find, will it work on all OS-es? */
	if (event->keyval == 65293) {
		DEBUG_MSG("dir_list_key_press_lcb, ENTER pressed!!!\n");
		dir_list_activate_row(main_v->filebrowser.dir_list_lastrow);
	}
	return TRUE;
}

static GtkWidget *make_filelist() {
	gchar *title1[] = {_("Directories"), NULL};
	gchar *title2[] = {_("Files"), NULL};
	GtkWidget *scrolled_win, *noteb, *vbox2;

	if (strcmp(main_v->props.filelist_filter, _("all web files")) ==0) {
		main_v->filebrowser.filter_type = FILTER_WEB;	
	} else if (strcmp(main_v->props.filelist_filter, _("images")) ==0) {
		main_v->filebrowser.filter_type = FILTER_IMAGES;
	} else if (strcmp(main_v->props.filelist_filter, _("documents")) ==0) {
		main_v->filebrowser.filter_type = FILTER_DOCUMENTS;
	} else {
		main_v->filebrowser.filter_type = FILTER_ALL;
	}

	noteb = gtk_notebook_new();
	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(noteb), GTK_POS_BOTTOM);
	gtk_widget_show(noteb);

	vbox2 = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(vbox2);
	gtk_notebook_append_page(GTK_NOTEBOOK(noteb), vbox2, gtk_label_new(_("Files")));

	main_v->filebrowser.dir_history = gtk_option_menu_new();
	gtk_option_menu_set_menu(GTK_OPTION_MENU(main_v->filebrowser.dir_history), gtk_menu_new());
	main_v->filebrowser.dir_history_menu = NULL;

	populate_dir_history();
	gtk_box_pack_start(GTK_BOX(vbox2), main_v->filebrowser.dir_history, FALSE, FALSE, 0);
	gtk_widget_show(main_v->filebrowser.dir_history);
	main_v->filebrowser.dir_list = gtk_clist_new_with_titles(1, title1);
	gtk_clist_set_column_auto_resize(GTK_CLIST(main_v->filebrowser.dir_list), 0, TRUE);
	gtk_clist_column_titles_passive(GTK_CLIST (main_v->filebrowser.dir_list));
	gtk_clist_set_selection_mode(GTK_CLIST(main_v->filebrowser.dir_list), GTK_SELECTION_BROWSE);
	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_add(GTK_CONTAINER (scrolled_win), main_v->filebrowser.dir_list);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_set_border_width (GTK_CONTAINER(scrolled_win), 5);
	gtk_box_pack_start(GTK_BOX(vbox2),scrolled_win , FALSE, FALSE, 0);
	gtk_signal_connect(GTK_OBJECT (main_v->filebrowser.dir_list), "select_row",
		      (GtkSignalFunc) dir_list_select_lcb, (gpointer) NULL);
	gtk_signal_connect(GTK_OBJECT(main_v->filebrowser.dir_list), "key_press_event",
		      (GtkSignalFunc) dir_list_key_press_lcb, (gpointer) NULL);

	gtk_widget_show(main_v->filebrowser.dir_list);
	gtk_widget_show (scrolled_win);

	main_v->filebrowser.file_list = gtk_clist_new_with_titles(1, title2);
	gtk_clist_set_column_auto_resize(GTK_CLIST(main_v->filebrowser.file_list), 0, TRUE);
	gtk_clist_column_titles_passive (GTK_CLIST (main_v->filebrowser.file_list));
	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_add (GTK_CONTAINER (scrolled_win), main_v->filebrowser.file_list);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	gtk_box_pack_start(GTK_BOX(vbox2),scrolled_win , TRUE, TRUE, 0);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "select_row",
		      (GtkSignalFunc) file_list_select_lcb, 
		      (gpointer) NULL);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "unselect_row",
		      (GtkSignalFunc) file_list_unselect_lcb, 
		      (gpointer) NULL);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "button_press_event",
		      (GtkSignalFunc) file_list_button_press_lcb, 
		      (gpointer) NULL);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "drag_begin",
		      (GtkSignalFunc) file_list_drag_begin_lcb, 
		      (gpointer) NULL);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "drag_motion",
		      (GtkSignalFunc) file_list_drag_motion_lcb, 
		      (gpointer) NULL);
	gtk_signal_connect (GTK_OBJECT (main_v->filebrowser.file_list), "drag_data_get",
		      (GtkSignalFunc) file_list_drag_data_get_lcb, 
		      (gpointer) NULL);

	gtk_drag_source_set(main_v->filebrowser.file_list , ( GDK_BUTTON1_MASK | GDK_BUTTON2_MASK ),
				drag_source_types, DRAG_SOURCE_NUM_TARGETS,(GDK_ACTION_LINK) );
	gtk_drag_dest_set(main_v->filebrowser.file_list, (GTK_DEST_DEFAULT_ALL)
				,drag_dest_types, DRAG_DEST_NUM_TARGETS
				,(GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE |
				GDK_ACTION_LINK | GDK_ACTION_PRIVATE | GDK_ACTION_ASK));
/*
   GDK_ACTION_DEFAULT
   GDK_ACTION_COPY
   GDK_ACTION_MOVE
   GDK_ACTION_LINK
   GDK_ACTION_PRIVATE
   GDK_ACTION_ASK 
*/

	gtk_widget_show(main_v->filebrowser.file_list);
	gtk_widget_show (scrolled_win);

	filelist_set_size();

	populate_dir_file_list();

	vbox2 = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(vbox2);
	gtk_notebook_append_page(GTK_NOTEBOOK(noteb), vbox2, gtk_label_new(_("Project")));

#ifdef ATTRPAGE
	vbox2 = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(vbox2);
	gtk_notebook_append_page(GTK_NOTEBOOK(noteb), vbox2, gtk_label_new(_("Attrs.")));
	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_container_set_border_width (GTK_CONTAINER(scrolled_win), 5);
	gtk_box_pack_start(GTK_BOX(vbox2), scrolled_win , TRUE, TRUE, 0);
	gtk_widget_show (scrolled_win);
	main_v->attrpage_window = scrolled_win;
#endif

	return noteb;
}

static void make_main_window(void)
{
	GtkWidget *vbox;

	/* main window */
	DEBUG_MSG("make_main_window, started\n");
	main_v->main_window = window_full(CURRENT_VERSION_NAME, GTK_WIN_POS_CENTER, GTK_WINDOW_TOPLEVEL, 0, cya_later, NULL);
	DEBUG_MSG("make_main_window, main_v->main_window(%p)\n", main_v->main_window);

	DEBUG_MSG("make_main_window, gdk_screen_height()=%d, gdk_screen_width()=%d\n", gdk_screen_height(), gdk_screen_width());
	if ((main_v->props.main_window_h < gdk_screen_height()) && (main_v->props.main_window_w < gdk_screen_width())) {
		DEBUG_MSG("make_main_window, , set window height and width\n");
		gtk_window_set_policy(GTK_WINDOW(main_v->main_window), FALSE, FALSE, FALSE);
		gtk_widget_set_usize(GTK_WIDGET(main_v->main_window), main_v->props.main_window_w, main_v->props.main_window_h);
		gtk_window_set_policy(GTK_WINDOW(main_v->main_window), TRUE, TRUE, FALSE);
	}

	gtk_window_set_wmclass(GTK_WINDOW(main_v->main_window), "Bluefish", "bluefish");
	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(main_v->main_window), vbox);
	gtk_widget_show(vbox);
	/* menu bar */
	get_main_menu(main_v->main_window, &main_v->menubar);
	gtk_box_pack_start(GTK_BOX(vbox), main_v->menubar, FALSE, TRUE, 0);
	gtk_widget_show(main_v->menubar);

	/* the pixmaps can't be created without a realise on the window, the
	   error Gdk-WARNING **: Creating pixmap from xpm with NULL window and 
	   colormap is removed by adding this line */
	gtk_widget_realize(main_v->main_window);
	/* drag n drop support */
	gtk_drag_dest_set(main_v->main_window, (GTK_DEST_DEFAULT_ALL)
				,drag_dest_types, DRAG_DEST_NUM_TARGETS
				,(GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE |
				GDK_ACTION_LINK | GDK_ACTION_PRIVATE | GDK_ACTION_ASK));
	gtk_signal_connect(GTK_OBJECT(main_v->main_window), "drag_data_received", GTK_SIGNAL_FUNC(on_drag_data_cb), NULL);

	/* pack the main toolbar handle box on the right place */
	hidewidgets.handle_box = gtk_handle_box_new();
	gtk_box_pack_start(GTK_BOX(vbox), hidewidgets.handle_box, FALSE, FALSE, 0);
	if (main_v->props.v_main_tb)
		show_gui(&main_v->props.v_main_tb, &hidewidgets.handle_box, make_main_toolbar);

	/* pack the HTML toolbar handle box on the right place */
	hidewidgets.html_handle_box = gtk_handle_box_new();
	gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hidewidgets.html_handle_box), FALSE, FALSE, 0);
	if (main_v->props.v_html_tb)
		show_gui(&main_v->props.v_html_tb, &hidewidgets.html_handle_box, make_html_toolbar);

	/* pack the custom toolbar handle box on the right place */
	hidewidgets.cust_handle_box = gtk_handle_box_new();
	gtk_box_pack_start(GTK_BOX(vbox), hidewidgets.cust_handle_box, FALSE, FALSE, 0);
	if (main_v->props.v_custom_tb)
		show_gui(&main_v->props.v_custom_tb, &hidewidgets.cust_handle_box, make_cust_menubar);
		
	DEBUG_MSG("make_main_window, creating lower region\n");

	main_v->middlebox = gtk_hbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), main_v->middlebox, TRUE, TRUE, 0);
	gtk_widget_show(main_v->middlebox);

	/* notebook with the text widget in there */
	main_v->notebook = gtk_notebook_new();
	notebook_set_tab_pos(main_v->props.cfg_tab_pos);
	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_v->notebook), TRUE);
	gtk_notebook_set_show_border(GTK_NOTEBOOK(main_v->notebook), TRUE);
	gtk_notebook_set_tab_border(GTK_NOTEBOOK(main_v->notebook), 1);

	/* We have to know when the notebook changes */
	gtk_signal_connect(GTK_OBJECT(main_v->notebook), "button_release_event", notebook_changed, NULL);
	gtk_signal_connect_after(GTK_OBJECT(main_v->notebook), "key_press_event", notebook_changed, NULL);

	gtk_notebook_set_page(GTK_NOTEBOOK(main_v->notebook), 0);
	gtk_notebook_set_scrollable(GTK_NOTEBOOK(main_v->notebook), TRUE);
	gtk_widget_show(main_v->notebook);
	
	if (main_v->props.v_filebrowser) {
		filebrowser_show(1);
	} else {
		filebrowser_hide(1);
	}

	/* status bar */
	main_v->statusbar = gtk_statusbar_new();
	gtk_box_pack_start(GTK_BOX(vbox), main_v->statusbar, FALSE, TRUE, 0);
	gtk_widget_show(main_v->statusbar);

	DEBUG_MSG("make_main_window, end\n");
}

void filebrowser_hide(gint first_time) {
	if (!first_time) {
		gtk_widget_ref(main_v->notebook);
		gtk_container_remove(GTK_CONTAINER(main_v->filebrowser.hpane), main_v->notebook);
		gtk_widget_destroy(main_v->filebrowser.hpane);
	}
	main_v->filebrowser.hpane = NULL;
	DEBUG_MSG("filebrowser_hide, middlebox=%p, notebook=%p\n", main_v->middlebox, main_v->notebook);
	gtk_box_pack_start(GTK_BOX(main_v->middlebox), main_v->notebook, TRUE, TRUE, 0);
	if (!first_time) {
		gtk_widget_unref(main_v->notebook);
	}
}

void filebrowser_show(gint first_time) {
	GtkWidget *noteb;

	if (!first_time) {
		gtk_widget_ref(main_v->notebook);
		gtk_container_remove(GTK_CONTAINER(main_v->middlebox), main_v->notebook);
	}

	main_v->filebrowser.hpane = gtk_hpaned_new();
	gtk_paned_set_gutter_size(GTK_PANED(main_v->filebrowser.hpane), 8);
	
	noteb = make_filelist();
	
	gtk_paned_add1(GTK_PANED(main_v->filebrowser.hpane), noteb);
	gtk_paned_add2(GTK_PANED(main_v->filebrowser.hpane), main_v->notebook);
	gtk_box_pack_start(GTK_BOX(main_v->middlebox), main_v->filebrowser.hpane, TRUE, TRUE, 0);

	DEBUG_MSG("filebrowser_show, middlebox=%p, notebook=%p\n", main_v->middlebox, main_v->notebook);

	gtk_widget_show(main_v->filebrowser.hpane);

	if (!first_time) {
		gtk_widget_unref(main_v->notebook);
	}
}

void startup(void)
{
#ifndef NOSPLASH
	GtkWidget *vbox, *splash_window;
	GtkWidget *wpixmap;
	GdkPixmap *pixm;
#endif

	/* splash screen */
#ifndef NOSPLASH
	splash_window = window_with_title(CURRENT_VERSION_NAME, GTK_WIN_POS_CENTER, GTK_WINDOW_DIALOG, 0);
	gtk_widget_realize(splash_window);
	gdk_window_set_decorations(GTK_WIDGET(splash_window)->window, 0);
	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(splash_window), vbox);
	gtk_widget_show(vbox);
	gtk_widget_realize(splash_window);
	pixm = gdk_pixmap_create_from_xpm_d(splash_window->window, NULL, NULL, bluefish_xpm);
	wpixmap = gtk_pixmap_new(pixm, NULL);
	gdk_pixmap_unref(pixm);
	gtk_box_pack_start(GTK_BOX(vbox), wpixmap, FALSE, FALSE, 0);
	gtk_widget_show(wpixmap);
	gtk_widget_realize(wpixmap);
	gtk_widget_show(splash_window);
	flush_queue();
#endif
	/* get colormap from GdkRgb and set it */
	main_v->colormap = gdk_rgb_get_cmap();
	DEBUG_MSG("startup, colormap=%p\n", main_v->colormap);
	gtk_widget_push_colormap (main_v->colormap);
	gtk_widget_push_visual (gdk_rgb_get_visual());

	if (main_v->props.syntax_configstrings == NULL) {
		reset_syntax_highlighting_lcb(NULL, NULL);
	}
	make_syntax_struct_list();

/* initialise positionlist */
	positionlist = g_list_append(NULL, "top");
	positionlist = g_list_append(positionlist, "middle");
	positionlist = g_list_append(positionlist, "bottom");
	positionlist = g_list_append(positionlist, "right");
	positionlist = g_list_append(positionlist, "left");
	positionlist = g_list_append(positionlist, "texttop");
	positionlist = g_list_append(positionlist, "baseline");
	positionlist = g_list_append(positionlist, "absmiddle");
	positionlist = g_list_append(positionlist, "absbottom");

	load_identify_filters();
	dir_history_open();
	make_main_window();
	gtk_widget_realize(main_v->main_window);
	flush_queue();

	/* make external commands and filters ready */
	make_external_menu_entries(1);
	make_external_menu_entries(2);

	/* open recent list */
	open_recent_list();

	context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(main_v->statusbar), "Bluefish");
	DEBUG_MSG("startup, main_window is ready\n");
	/* add icon to the window when in minimized state */
	{
	GdkPixmap *icon = NULL;
	GdkBitmap *imask = NULL;
	icon = gdk_pixmap_create_from_xpm_d(main_v->main_window->window, &imask, NULL, (gchar **) bluefish_icon_xpm);
	gdk_window_set_icon(main_v->main_window->window, NULL, icon, imask);
	gdk_window_set_icon_name(main_v->main_window->window, CURRENT_VERSION_NAME);
	DEBUG_MSG("startup, icon is there\n");
	}
	load_menu_shortcuts();	
#ifndef NOSPLASH
	/* kill the splash window when the main window is going up */
	flush_queue();
#ifndef WIN32
	sleep(1);
#endif
	window_destroy(splash_window);
#endif
	gtk_widget_show(main_v->main_window);
	if (g_list_length(main_v->documentlist) < 1) {
		main_v->current_document = doc_new();
	}
	gtk_window_set_policy(GTK_WINDOW(main_v->main_window), TRUE, TRUE, FALSE);
}

void show_about_window_cb(GtkWidget * widget, gpointer data)
{
	GtkWidget *wpixmap, *window, *vbox, *button;
	GdkPixmap *pixm;
	GtkStyle *style;

	DEBUG_MSG("about, started\n");
	window = window_with_title(_("About Bluefish"), GTK_WIN_POS_MOUSE, GTK_WINDOW_DIALOG, 10);

	style = gtk_style_new();
	style->bg->red = 65535;
	style->bg->blue = 65535;
	style->bg->green = 65535;
	gtk_widget_push_style(style);
	gtk_widget_set_style(GTK_WIDGET(window), style);
	gtk_widget_pop_style();

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_widget_realize(window);
	pixm = gdk_pixmap_create_from_xpm_d(window->window, NULL, NULL, bluefish_xpm);
	wpixmap = gtk_pixmap_new(pixm, NULL);
	gdk_pixmap_unref(pixm);
	gtk_box_pack_start(GTK_BOX(vbox), wpixmap, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new(CURRENT_VERSION_NAME), FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox),
					   gtk_label_new(_
									 ("(C) Olivier Sessink\n\ndeveloped by the bluefish development team\nsee AUTHORS for more information\nhttp://bluefish.openoffice.nl/")),
					   FALSE, FALSE, 0);
	button = gtk_button_new_with_label(_("Dismiss"));
	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
	gtk_signal_connect_object(GTK_OBJECT(button), "clicked", gtk_widget_destroy, GTK_OBJECT(window));
	gtk_container_add(GTK_CONTAINER(window), vbox);
	gtk_widget_show_all(window);
	DEBUG_MSG("about, finished\n");
}


/*
 * dndwin_cb - displays the drag n drop window
 */
void
dndwin_cb (GtkWidget * widget, gpointer data)
{
     GtkWidget *dndwin;
     GtkWidget *dndpixmap;
     GdkPixmap *gdkpixmap;

     dndwin=gtk_window_new (GTK_WINDOW_DIALOG);
	  gtk_signal_connect(GTK_OBJECT(dndwin), "delete_event"
	   		, GTK_SIGNAL_FUNC(gtk_widget_destroy), dndwin);
     gtk_widget_set_usize (dndwin,50,50);

     gtk_widget_realize (dndwin);

     gdkpixmap=gdk_pixmap_create_from_xpm_d (dndwin->window,NULL,NULL,bluefish_icon_xpm);
     dndpixmap=gtk_pixmap_new (gdkpixmap, NULL);

     gtk_container_add (GTK_CONTAINER (dndwin),dndpixmap);
     
     gtk_drag_dest_set(dndpixmap, (GTK_DEST_DEFAULT_ALL)
				,drag_dest_types, DRAG_DEST_NUM_TARGETS
				,(GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE |
				GDK_ACTION_LINK | GDK_ACTION_PRIVATE | GDK_ACTION_ASK));
     gtk_signal_connect(GTK_OBJECT(dndpixmap), "drag_data_received", GTK_SIGNAL_FUNC(on_drag_data_cb), NULL);

     gtk_widget_show (dndpixmap);
     gtk_widget_show (dndwin);
}

