Filewatcher File Search
FTP Search
  
Directory (beta)
  
Content Search (beta)
   
pkg://xcdroast-debuginfo-0.98a15-14.fc7.ppc.rpm:614443/usr/src/debug/xcdroast-0.98alpha15/src/menus.c  info  downloads

/*
	menus.c
	27.3.99 tn
*/

#ifdef HAVE_CONFIG_H
 #include <config.h>
#endif

#define GTK_ENABLE_BROKEN

#include <gtk/gtk.h>
#if GTK_MAJOR_VERSION < 2
 #include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
#endif

#include "largefile.h"

#if HAVE_LOCALE_H
#include <locale.h>
#else
# define setlocale(Category, Locale) 
#endif
#include "gettext.h"

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <ctype.h>

#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif

#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"
#include "../xpms/treefolderopen.xpm"
#include "../xpms/treefolderclosed.xpm"
#include "../xpms/filesmall.xpm"
#include "../xpms/minidata.xpm"
#include "../xpms/miniaudio.xpm"
#include "../xpms/mininodata.xpm"

extern gint debug;
extern GtkWidget *toplevel;
extern GtkWidget *splitspace;
extern GtkWidget *sidespace;
extern GtkWidget *workspace;
extern GtkWidget *actionspace;
extern scsi_devices_t **scsidevices;
extern writer_driver_t **blankmodes;
extern setup_data_t setupdata;
extern master_param_t masterparam;
extern cd_info_t cdinfo;
extern track_info_t **trackinfo;
extern GList *imagelist;
extern current_set_t curset;
extern track_read_set_t trackreadset;
extern gint read_done;
extern GList *tocfiles;
extern gint read_abort_mark;
extern gchar sharedir[MAXLINE];
extern GtkWidget *cdlist_l1, *imglist_l2;
extern GtkCList *cdlist, *imglist2;
extern gchar configdir[MAXLINE];
extern GtkWidget *isoopts[24];
extern master_param_t masterparam;
extern GtkWidget *mkisofs_calc_timeout_dialog;
extern GdkFont *fixedfont;

GtkWidget *ctree_okbutton;
GtkWidget *cddb_info_label;
GtkCList *cddb_clist;
GtkWidget *viewmode_dialog;
GtkWidget *readtrack_info_label, *readtrack_textview;
GtkWidget *readtrack_pbar1, *readtrack_pbar2;
GtkWidget *readtrack_pbar3, *readtrack_pbar4, *readtrack_spd;
GtkWidget *readtrack_small_info, *readtrack_small_info2, *readtrack_info_tbl;
gint dialog_done, dialog_done2, dialog_done3;

static GtkWidget *ctree_window;
static GtkWidget *ctree_entry;
static gint ctree_showfiles, ctree_showhidden;
static GtkCTreeNode *parent_node, *lastactive_node;
static GtkCTree *ctree_base;
static gchar *ctree_basedir;
static GtkWidget *cddb_info_okbutton;
static GtkWidget *cddb_window;
static GtkWidget *readtrack_button, *readtrack_savebutton;
static GtkWidget *readtrack_info_frame;
static GdkPixmap *pixmap1, *pixmap2, *pixmap3;
static GdkBitmap *mask1, *mask2, *mask3;
static GtkWidget *viewmode_scrolled;
static GtkWidget *blank_infolabel;
static GtkWidget *blank_text_window;
static GtkWidget *redir_entry;
static gint misc_timer;
static GtkWidget *cdtext_entry1[MAXTRACKS+1];
static GtkWidget *cdtext_entry2[MAXTRACKS+1];
static GtkWidget *varirec_label, *varirec_scale;
static GtkWidget *isolevel_label, *isolevel_scale;

extern void writeoptions_selected(GtkWidget *item, gpointer nr);
extern void isooptions_selected(GtkWidget *item, gpointer nr);



static gint dialog_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {

	dialog_done = -1;
        return(TRUE);
}

static gint dialog_delete_event2(GtkWidget *widget, GdkEvent *event, gpointer data) {

	dialog_done2 = -1;
        return(TRUE);
}

static gint dialog_delete_event3(GtkWidget *widget, GdkEvent *event, gpointer data) {

	dialog_done3 = -1;
        return(TRUE);
}

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

	dialog_done = GPOINTER_TO_INT(data);
}

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

	dialog_done2 = GPOINTER_TO_INT(data);
}


/* popup a modal window, set cursor to watch, return button pressed
   or -1 when delete_event found.
   Up to three buttons. Set unused buttons to NULL 
   Centers automatically above the toplevel-widow 
   if no toplevel window available center on display

   specialcase: when defbutton -1, then dont set the window cursor 

*/

gint show_dialog(gchar *icon_file, gchar *ttext, gchar *btn1, gchar *btn2, gchar *btn3, gint defbutton) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *button3;
GtkWidget *box1,*box2;
GtkWidget *b1_t,*b1_sep,*pix,*lab;
gint xpos, ypos;
gint xsize, ysize;
GdkCursor *cursor;
/* GtkStyle *style; */
GtkRequisition rq;
#if GTK_MAJOR_VERSION < 2
GdkPixbuf *im;
GdkPixmap *pixmap;
GdkBitmap *mask;
gchar tmp[MAXLINE];
#else
gchar *ico;
#endif
	/* if another dialog is running, ignore */
	if (dialog_done == 999) {
		return -1;
	}

	dodebug(8, "displaying show_dialog: %s\n", ttext);

	/* mark our dialog as running */
	dialog_done = 999;

	/* create new window and position it relative to the main window */
	dialog = my_gtk_dialog_new();
	set_xcdr_title(dialog, NULL, -1);
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
                GTK_SIGNAL_FUNC (dialog_delete_event), (gpointer) dialog);


	/* create layout for dialog */
        box1 = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(dialog),box1);

        b1_t = gtk_table_new(1,10, TRUE);
	gtk_container_border_width(GTK_CONTAINER(b1_t),10);

        gtk_box_pack_start(GTK_BOX(box1),b1_t,FALSE,TRUE,10);

	/* realize table to be able to put a pixmap in it */
        gtk_widget_realize(b1_t);

/*        style = gtk_widget_get_style(b1_t);
        pixmap = gdk_pixmap_create_from_xpm_d(b1_t->window, &mask,
                 &style->bg[GTK_STATE_NORMAL],(gchar **)icon_xpm);
*/
#if GTK_MAJOR_VERSION < 2
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir,icon_file);
	dodebug(9, "dialog: trying to load %s\n", tmp);

	im=gdk_pixbuf_new_from_file(tmp);
	if (im) {
		gdk_pixbuf_render_pixmap_and_mask(im, &pixmap, &mask, 128);
        	pix = gtk_pixmap_new(pixmap,mask);
        	gtk_table_attach_defaults(GTK_TABLE(b1_t), pix, 0,2,0,1);
        	gtk_widget_show(pix);
		gdk_pixbuf_unref(im);
	}
#else
	ico = lookup_stock_icon(icon_file);
	if (ico) {
		pix = gtk_image_new_from_stock(ico, GTK_ICON_SIZE_DIALOG);
        	gtk_table_attach_defaults(GTK_TABLE(b1_t), pix, 0,2,0,1);
        	gtk_widget_show(pix);
	}
#endif

        lab = gtk_label_new(ttext);
        gtk_table_attach_defaults(GTK_TABLE(b1_t), lab, 2,10,0,1);

        b1_sep = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(box1),b1_sep,FALSE,TRUE,0);

        box2 = gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,10);

	if (btn1 != NULL) {
        	button1 = gtk_button_new_with_label (btn1);
		gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
		gtk_widget_show(button1);
		gtk_signal_connect(GTK_OBJECT(button1),"clicked",
			GTK_SIGNAL_FUNC(dialog_btn_press), GINT_TO_POINTER(0));
		GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
		if (defbutton == 0) gtk_widget_grab_default (button1);
	}
	if (btn2 != NULL) {
        	button2 = gtk_button_new_with_label (btn2);
		gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
		gtk_widget_show(button2);
		gtk_signal_connect(GTK_OBJECT(button2),"clicked",
			GTK_SIGNAL_FUNC(dialog_btn_press), GINT_TO_POINTER(1));
		GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
		if (defbutton == 1) gtk_widget_grab_default (button2);
	}
	if (btn3 != NULL) {
        	button3 = gtk_button_new_with_label (btn3);
		gtk_box_pack_start(GTK_BOX(box2),button3,TRUE,TRUE,10);
		gtk_widget_show(button3);
		gtk_signal_connect(GTK_OBJECT(button3),"clicked",
			GTK_SIGNAL_FUNC(dialog_btn_press), GINT_TO_POINTER(2));
		GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
		if (defbutton == 2) gtk_widget_grab_default (button3);
	}

        gtk_widget_show(box2);
        gtk_widget_show(b1_sep);
        gtk_widget_show(lab);
        gtk_widget_show(b1_t);
        gtk_widget_show(box1);


	cursor = NULL;
	/* grab cursor and change to watch */
	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_add(dialog);

		if (defbutton != -1) {
      	 	 	cursor = gdk_cursor_new(GDK_WATCH);
    	   	 	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);
			dodebug(9, "showdialog: set cursor\n");
		}
	}

	/* only center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
        	gdk_window_get_origin(GTK_WIDGET(toplevel)->window,&xpos,&ypos);
        	gdk_window_get_size(GTK_WIDGET(toplevel)->window,&xsize,&ysize);
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xpos+xsize/2-rq.width/2,ypos+ysize/2-rq.height/2);
	} else {
		/* otherwise center in screen */
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
		xsize = gdk_screen_width();
		ysize = gdk_screen_height();
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xsize/2-rq.width/2,ysize/2-rq.height/2);
		
	}

	gtk_widget_show(dialog);

	/* if this is a warning sound bell (if requested in setup) */
	if (strcmp(icon_file, ICO_WARN) == 0) {
		dobeep(2);
	}

	/* now wait until button is pressed */
	while (dialog_done == 999) {
		wait_and_process_events();
	}

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_remove(GTK_WIDGET(dialog));
		if (defbutton != -1) {
        		gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
			if (cursor) gdk_cursor_destroy (cursor);
			dodebug(9, "showdialog: restored cursor\n");
		}
	}

	/* remove dialog window */
        gtk_widget_destroy(dialog);

	return dialog_done; 
}


/* another version of the dialog -> with nice xcdroast logo on top */

gint show_fancy_dialog(gchar *htext, gchar *ttext, gchar *btn1) {
GtkWidget *dialog, *xcdroast_logo, *vbox;
GdkPixbuf *im, *im2;
GdkPixmap *p;
GdkBitmap *m;
GtkWidget *button1;
GtkWidget *box1,*box2, *f1, *l1, *lab;
gint xpos, ypos;
gint xsize, ysize;
GdkCursor *cursor;
GtkRequisition rq;
gchar tmp[MAXLINE];

	/* if another dialog is running, ignore */
	if (dialog_done == 999) {
		return -1;
	}

	dodebug(8, "displaying show_fancy_dialog: %s\n", ttext);

	/* mark our dialog as running */
	dialog_done = 999;

	/* create new window and position it relative to the main window */
	dialog = my_gtk_dialog_new();
	set_xcdr_title(dialog, NULL, -1);
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
                GTK_SIGNAL_FUNC (dialog_delete_event), (gpointer) dialog);


	/* create layout for dialog */
        box1 = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(dialog),box1);
        gtk_widget_show(box1);

        /* load the half scaled logo */
        g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, XCDRLOGO);
#if GTK_MAJOR_VERSION < 2
	im=gdk_pixbuf_new_from_file(tmp);
#else
	im=gdk_pixbuf_new_from_file(tmp,NULL);
#endif
        if (im) {
                im2 = gdk_pixbuf_scale_simple(im,
                        gdk_pixbuf_get_width(im)/2,
                        gdk_pixbuf_get_height(im)/2,
                        GDK_INTERP_TILES);
                gdk_pixbuf_render_pixmap_and_mask(im2, &p, &m, 128);
                xcdroast_logo = gtk_pixmap_new(p,m);
                gdk_pixbuf_unref(im);
                gdk_pixbuf_unref(im2);
        } else {
                xcdroast_logo = gtk_label_new("[LOGO]");
        }
        gtk_box_pack_start(GTK_BOX(box1),xcdroast_logo,FALSE,FALSE,0);
        gtk_widget_show(xcdroast_logo);

        g_snprintf(tmp,MAXLINE,_("Version %s"),XCDROAST_VERSION);
        l1 = gtk_label_new(tmp);
        gtk_label_set_justify(GTK_LABEL(l1),GTK_JUSTIFY_CENTER);
        set_font_and_color(l1,NULL,"red");
        gtk_box_pack_start(GTK_BOX(box1),l1,FALSE,FALSE,0);
        gtk_widget_show(l1);

        f1 = gtk_frame_new(NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
        gtk_container_set_border_width(GTK_CONTAINER (f1),5);
	gtk_widget_show(f1);

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_set_border_width(GTK_CONTAINER (vbox),10);
        gtk_container_add(GTK_CONTAINER(f1),vbox);
        gtk_widget_show(vbox);

	/* print header text? */
	if (htext) {
  	      	lab = gtk_label_new(htext);
		set_font_and_color(lab,BOLDFONT,NULL);
		gtk_label_set_justify(GTK_LABEL(lab),GTK_JUSTIFY_CENTER);
   		gtk_box_pack_start(GTK_BOX(vbox),lab,FALSE,FALSE,0);
       		gtk_widget_show(lab);
	}

        lab = gtk_label_new(ttext);
	gtk_label_set_justify(GTK_LABEL(lab),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(vbox),lab,FALSE,FALSE, 5);
        gtk_widget_show(lab);

        box2 = gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,10);
        gtk_widget_show(box2);

	if (btn1 != NULL) {
        	button1 = gtk_button_new_with_label (btn1);
		gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
		gtk_widget_show(button1);
		gtk_signal_connect(GTK_OBJECT(button1),"clicked",
			GTK_SIGNAL_FUNC(dialog_btn_press), GINT_TO_POINTER(0));
		GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
		gtk_widget_grab_default (button1);
	}


	cursor = NULL;
	/* grab cursor and change to watch */
	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_add(dialog);

      	 	cursor = gdk_cursor_new(GDK_WATCH);
    	 	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);
		dodebug(9, "showdialog: set cursor\n");
	}

	/* only center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
        	gdk_window_get_origin(GTK_WIDGET(toplevel)->window,&xpos,&ypos);
        	gdk_window_get_size(GTK_WIDGET(toplevel)->window,&xsize,&ysize);
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xpos+xsize/2-rq.width/2,ypos+ysize/2-rq.height/2);
	} else {
		/* otherwise center in screen */
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
		xsize = gdk_screen_width();
		ysize = gdk_screen_height();
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xsize/2-rq.width/2,ysize/2-rq.height/2);
		
	}

	gtk_widget_show(dialog);

	/* now wait until button is pressed */
	while (dialog_done == 999) {
		wait_and_process_events();
	}

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_remove(GTK_WIDGET(dialog));
        	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
		if (cursor) gdk_cursor_destroy (cursor);
		dodebug(9, "showdialog: restored cursor\n");
	}

	/* remove dialog window */
        gtk_widget_destroy(dialog);

	return dialog_done; 
}


/* clears the left sidebar */

void clear_sidespace() {

	gtk_widget_destroy(sidespace);
	sidespace = gtk_vbox_new(FALSE,0);
	gtk_paned_add1(GTK_PANED(splitspace), sidespace);
	set_sidebar_width();
}


/* clears the right workspace */

void clear_workspace() {

	gtk_widget_destroy(workspace);
	workspace = gtk_vbox_new(FALSE,0);
	gtk_paned_add2(GTK_PANED(splitspace), workspace);
}


/* clears the actionspace subwindow */

void clear_actionspace() {

	gtk_widget_destroy(actionspace);
	actionspace = gtk_vbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(workspace), actionspace,TRUE,TRUE,0);

	/* strange, why we need that...*/
	while (gtk_events_pending())
		gtk_main_iteration();

}


/* add subdirectory nodes to an existing ctree */

static void ctree_add_dir_nodes(gchar *path, GtkCTree *ctree, GtkCTreeNode *parent, gint showfiles, gint showhidden) {
struct dirent *ent;
DIR *dir;         
gchar *text[1];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
GtkCTreeNode *sibling;
gchar *textdata;
GList *dir_list;
GList *file_list;

	dir_list = NULL;
	file_list = NULL;
	dir = opendir(path);

	/* invalid directory */
	if (dir == NULL) 
		return;

	/* read entries */
	while ( (ent = readdir(dir)) ) {

		if (strcmp(ent->d_name,".") == 0 || 
		    strcmp(ent->d_name,"..") == 0) 
			continue;

		if (!showhidden) {
			/* skip files starting with a dot */
			if (ent->d_name[0] == '.') 
				continue;
		}

		strcpy(tmp,path);
		/* add slash when not there */
		if (tmp[strlen(tmp)-1] != '/')  
			strcat(tmp,"/");
		strcat(tmp,ent->d_name);

		/* add only directories */
		if (is_directory(tmp) == 1) {

			dir_list = g_list_append(dir_list, g_strdup(ent->d_name));
		} else {
			if (showfiles) 
				file_list = g_list_append(file_list, g_strdup(ent->d_name));
		}
	}
	closedir(dir);

	/* sort the directory-list */
	if (dir_list == NULL && showfiles == 0)
		return;

	sort_glist(dir_list);

	/* sort the file-list */
	if (file_list != NULL && showfiles) {
		sort_glist(file_list);
	}

	/* draw entries */
	while (dir_list) {
		/* allocate directory names */
		strncpy(tmp2, dir_list->data, MAXLINE);
		convert_for_gtk2(tmp2);
		text[0] = tmp2;

		strcpy(tmp,path);
		/* add slash when not there */
		if (tmp[strlen(tmp)-1] != '/')  
			strcat(tmp,"/");
		if ((strlen(tmp) + strlen(dir_list->data)) > MAXLINE-1) {
			/* getting to long..writing dummy*/
			strcat(tmp,"+");
		} else {	
			strcat(tmp,dir_list->data);
		}
		textdata = g_strdup(tmp);


		/* now check if there are subdirs in that dir */
		if (is_subdirs(tmp)) {
			sibling = gtk_ctree_insert_node (ctree,parent,
				NULL,text,3,pixmap1,mask1,
				pixmap2,mask2,FALSE,FALSE);

			/* create dummy node */
			gtk_ctree_insert_node (ctree,sibling,
				NULL,text,3,NULL,NULL,NULL,NULL,TRUE,FALSE);
		} else {
			/* no subdirs */
			if (!showfiles || !is_subfiles(tmp)) {
				/* if do not show files, dont allow
				   changing into empty directory */
				sibling = gtk_ctree_insert_node (ctree,parent,
					NULL,text,3,pixmap1,mask1,
					pixmap2,mask2,TRUE,FALSE);
			} else {
				/* let user browse directory */
				sibling = gtk_ctree_insert_node (ctree,parent,
					NULL,text,3,pixmap1,mask1,
					pixmap2,mask2,FALSE,FALSE);
				gtk_ctree_insert_node (ctree,sibling,
				NULL,text,3,NULL,NULL,NULL,NULL,TRUE,FALSE);
			}	
		}

		/* save the full path name in the node-data */
		gtk_ctree_node_set_row_data(ctree,sibling,textdata); 

		dir_list = dir_list->next;
	}

	/* add files */
	while (file_list) {
		strncpy(tmp2, file_list->data, MAXLINE);
		convert_for_gtk2(tmp2);
		text[0] = tmp2;

		strcpy(tmp,path);
		/* add slash when not there */
		if (tmp[strlen(tmp)-1] != '/')  
			strcat(tmp,"/");
		if ((strlen(tmp) + strlen(file_list->data)) > MAXLINE-1) {
			/* getting to long..writing dummy*/
			strcat(tmp,"+");
		} else {	
			strcat(tmp,file_list->data);
		}
		textdata = g_strdup(tmp);

		sibling = gtk_ctree_insert_node (ctree,parent,
				NULL,text,3,pixmap3,mask3,
				pixmap3,mask3,TRUE,FALSE);

		/* save the full path name in the node-data */
		gtk_ctree_node_set_row_data(ctree,sibling,textdata); 

		file_list = file_list->next;
	}

	/* free list */
	free_glist(&dir_list);
	free_glist(&file_list);
}

	
/* recursively remove all children of a node in a ctree */

static void ctree_remove_children(GtkCTree * tree, GtkCTreeNode * node) {
GtkCTreeNode *child;
GList *sibling_list;
gchar *strpnt;

	/* Get the child node and make sure it's not NULL. */
	child = GTK_CTREE_ROW (node)->children;
	if (child == NULL)
		return;

	/* Get the list of siblings. */
	sibling_list = NULL;
	for (; child; child = GTK_CTREE_ROW (child)->sibling)
		sibling_list = g_list_append (sibling_list, child);

	/* break out from recusion */
	if (sibling_list == NULL) 
		return;

  	/* Remove all of the sibling nodes. */
	gtk_clist_freeze (GTK_CLIST (tree));
	for (; sibling_list; sibling_list = sibling_list->next) {
	
		/* go recursive */
		ctree_remove_children(tree, GTK_CTREE_NODE(sibling_list->data));

		/* free allocated node-data */
		strpnt = gtk_ctree_node_get_row_data (tree, 
			GTK_CTREE_NODE (sibling_list->data));
		g_free(strpnt);

		gtk_ctree_remove_node (tree, 
			GTK_CTREE_NODE (sibling_list->data));
		
	}
	gtk_clist_thaw (GTK_CLIST (tree));

	/* Free up memory. */
	g_list_free (g_list_first(sibling_list));

}


/* called when the users expands a directory in the ctree */

static gint ctree_expand (GtkCTree *tree, GtkCTreeNode *node, gpointer data) {
gchar *newdir;
GdkCursor *clock_cursor;

	/* fetch full path the node stands for */
	newdir = gtk_ctree_node_get_row_data (tree, node);

	/* save clicked node */
	lastactive_node = node;

	/* skip root-dir */
	if (newdir == NULL) return TRUE;

	clock_cursor = gdk_cursor_new (GDK_WATCH);
	gdk_window_set_cursor (GTK_WIDGET (ctree_window)->window, clock_cursor);

	/* gives gtk a break and time to update REALLY the cursor */
	/* I dont think this slowes things down */
	gtk_main_iteration_do(FALSE);

	gtk_clist_freeze (GTK_CLIST (tree));

	/* remove first everything and then add new nodes */
	ctree_remove_children(tree,node);
	ctree_add_dir_nodes(newdir,tree,node,ctree_showfiles,ctree_showhidden);

	/* now scroll to position (OPTIONAL) */
	/* gtk_ctree_node_moveto(tree,node,0,0.1,0); */

	/* unfreeze and change cursor back */
	gtk_clist_thaw (GTK_CLIST (tree));
	gdk_window_set_cursor (GTK_WIDGET (ctree_window)->window, NULL);
	gdk_cursor_destroy (clock_cursor);

	return TRUE;
}


/* just save the last clicked node */

static gint ctree_collapse (GtkCTree *tree, GtkCTreeNode *node, gpointer data) {

	/* save clicked node */
	lastactive_node = node;

	/* process default callback now */
	return FALSE;
}

/* returns a list of the selected paths */
/* you have to free that list afterwards */

void ctree_get_selected(GList **retsel) {
GList *sel;
GtkCList *clist;
GtkCTreeNode *lnode;
gchar *p;

	clist = GTK_CLIST(ctree_base);
        sel = clist->selection;
        while (sel) {
		lnode = sel->data;
		p = gtk_ctree_node_get_row_data (ctree_base, lnode);
		if (p) {
			*retsel = g_list_append(*retsel, g_strdup(p));
		}	
		sel = sel->next;
	}
}


/* called when the user selects a row in a ctree */

static gint ctree_select_row (GtkCTree *tree, GtkCTreeNode *node, gpointer data) {
gchar *pnt;
GList *sel;
GtkCList *clist;
gint selcount;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

	/* how many paths selected right now? */
	clist = GTK_CLIST(tree);
        sel = clist->selection;
	selcount = g_list_length(sel);

	pnt = gtk_ctree_node_get_row_data (tree, node);
	if (selcount <= 1) {
		if (pnt == NULL) {
			/* no path set */
			gtk_entry_set_text(GTK_ENTRY(ctree_entry),"");
			if (ctree_okbutton) 
				gtk_widget_set_sensitive(ctree_okbutton,FALSE);
		} else {
			strncpy(tmp2, pnt, MAXLINE);
			convert_for_gtk2(tmp2);
			gtk_entry_set_text(GTK_ENTRY(ctree_entry),tmp2);
			if (ctree_okbutton) 
				gtk_widget_set_sensitive(ctree_okbutton,TRUE);
		}
	} else {
		/* more than one path selected */
		g_snprintf(tmp,MAXLINE,_("(%d paths selected)"), selcount);
		gtk_entry_set_text(GTK_ENTRY(ctree_entry),tmp);
		if (ctree_okbutton) 
			gtk_widget_set_sensitive(ctree_okbutton,TRUE);
	}

	return TRUE;
}


/* called when the user unselects a row in a ctree */

static gint ctree_unselect_row (GtkCTree *tree, GtkCTreeNode *node, gpointer data) {
gchar *pnt;
GList *sel;
GtkCList *clist;
gint selcount;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

	/* how many paths selected right now? */
	clist = GTK_CLIST(tree);
        sel = clist->selection;
	selcount = g_list_length(sel);

	if (selcount == 0) {
		/* no path set */
		gtk_entry_set_text(GTK_ENTRY(ctree_entry),"");
		if (ctree_okbutton) 
			gtk_widget_set_sensitive(ctree_okbutton,FALSE);
	} else 
	if (selcount == 1) {
		pnt = gtk_ctree_node_get_row_data (tree, sel->data);
		if (pnt) {
			strncpy(tmp2, pnt, MAXLINE);
			convert_for_gtk2(tmp2);
			gtk_entry_set_text(GTK_ENTRY(ctree_entry),tmp2);
			if (ctree_okbutton) 
				gtk_widget_set_sensitive(ctree_okbutton,TRUE);
		}
	} else {
		/* more than one path selected */
		g_snprintf(tmp,MAXLINE,_("(%d paths selected)"), selcount);
		gtk_entry_set_text(GTK_ENTRY(ctree_entry),tmp);
		if (ctree_okbutton) 
			gtk_widget_set_sensitive(ctree_okbutton,TRUE);
	}

	return TRUE;
}


/* unselect all in ctree */

void ctree_unselect_all() {

	gtk_clist_unselect_all(GTK_CLIST(ctree_base));
	gtk_entry_set_text(GTK_ENTRY(ctree_entry),"");
}


/* frees the ctree from memory */

static void ctree_cleanup() {

	ctree_remove_children(ctree_base,parent_node);
	gtk_ctree_collapse_recursive(ctree_base, parent_node);
}


/* can be used to change the view mode (dirs only or with files) */
/* will collaps the tree to its base mode */

void ctree_change_viewmode(gint showfiles, gint showhidden) {
gchar *text;
gchar tmp[MAXLINE];

	/* do nothing if the state is the same */
	if (showfiles == ctree_showfiles && showhidden == ctree_showhidden) 
		return;

	/* remember the last touched node */
	strcpy(tmp,"");
	if (lastactive_node) {
		text = gtk_ctree_node_get_row_data(ctree_base, lastactive_node);
		if (text) {
			strncpy(tmp,text,MAXLINE);
		}
	}

	gtk_clist_freeze(GTK_CLIST(ctree_base));

	ctree_showfiles = showfiles;
	ctree_showhidden = showhidden;

	/* collapse whole tree to ensure correct redraw */
	ctree_remove_children(ctree_base,parent_node);
	gtk_ctree_collapse_recursive(ctree_base, parent_node);

	/* now redraw with correct setting */
	ctree_add_dir_nodes(ctree_basedir,ctree_base,parent_node,
		ctree_showfiles, ctree_showhidden);
	gtk_ctree_expand(ctree_base,parent_node);

	/* jump to last clicked position */
	if (strcmp(tmp,"")) {
		ctree_expand_manualpath(NULL, tmp);
	}
	gtk_clist_thaw(GTK_CLIST(ctree_base));

}


/* search current branch of ctree for a certain string */

static GtkCTreeNode *ctree_search_nodes(GtkCTree *tree, GtkCTreeNode *node, 
		gchar *cmpstr) {
GtkCTreeNode *child;
GList *sibling_list;
gchar *strpnt;

        /* Get the child node and make sure it's not NULL. */
        child = GTK_CTREE_ROW (node)->children;
        if (child == NULL)
                return NULL;

        /* Get the list of siblings. */
        sibling_list = NULL;
        for (; child; child = GTK_CTREE_ROW (child)->sibling)
                sibling_list = g_list_append (sibling_list, child);

        for (; sibling_list; sibling_list = sibling_list->next) {
		/* get data entry */
		child = GTK_CTREE_NODE (sibling_list->data);
               	strpnt = gtk_ctree_node_get_row_data (tree, child);
		if (strpnt && (strcmp(strpnt,cmpstr) == 0)) {
			g_list_free (g_list_first(sibling_list));
			return child;
		} 
	}

	/* nothing found */
	g_list_free (g_list_first(sibling_list));
	return NULL;
}


/* interprets a manual entered path and adopts the tree-listing */

void ctree_expand_manualpath(GtkWidget* entry, gchar *altstring) {
gchar *p1;
gchar path[MAXLINE];
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
GtkCTreeNode *sibling, *node;

	if (entry) {
		strncpy(path,gtk_entry_get_text(GTK_ENTRY(entry)),MAXLINE);
		convert_for_gtk2_filename(path);
	} else {
		if (altstring) {
			strncpy(path, altstring, MAXLINE);
		} else 
			return;
	}

	/* must begin with a slash */
	if (path[0] != '/') 
		return;
	if (strlen(path) > MAXLINE) 
		return;
	
	/* walk through directory tree as if user clicked */
	sibling = parent_node;
	strcpy(tmp,path);
	strcpy(tmp2,"");
	p1 = strtok(tmp,"/");
	while (p1) {
		strcat(tmp2,"/");
		strcat(tmp2,p1);

		/* now look in current sibling for a matching string */
		node = ctree_search_nodes(ctree_base, sibling, tmp2);

		/* something found? */
		if (node) {
			/* now expand this node if possible */
			ctree_expand(ctree_base, node, NULL);
			gtk_ctree_expand(ctree_base,node);
			gtk_clist_unselect_all(GTK_CLIST(ctree_base));

			/* select only if data from entry */
			if (entry) 
				gtk_ctree_select(ctree_base,node);

			/* now scroll to position */
			gtk_ctree_node_moveto(ctree_base,node,0,0.1,0); 

			/* prepare next level */
			sibling = node;
		}

		p1 = strtok(NULL,"/");
	}

	/* restore entry string */
	if (entry) {
		convert_for_gtk2(path);
		gtk_entry_set_text(GTK_ENTRY(entry),path);
	}
}


/* return the current selected directories via drag & drop */

static void ctree_request_dnddata(GtkWidget *widget, GdkDragContext *dc,
	GtkSelectionData *selection_data, guint info, guint t, 
	gpointer data) {
gboolean data_sent = FALSE;
gint focusrow, bufcount;
GtkCTree *ctree;
GtkCList *clist;
GtkCTreeNode *focusnode, *lnode;
GList *sel;
gchar *text;
gint use_selection;
gchar tmp[MAXLINE];
gchar bigtmp[MAXLINE*10];

	use_selection = 0;
	ctree = GTK_CTREE(widget);

	/* Get the focused row on the clist (we clicked on it) */
	clist = GTK_CLIST(ctree);
	focusrow = clist->focus_row;
	focusnode = gtk_ctree_node_nth(ctree, focusrow);

	/* see if any other rows are selected */
	sel = clist->selection;
	while (sel) {
		lnode = sel->data;
		if (lnode == focusnode) {
			/* we focused a row that is selected, remember */
			use_selection = 1;
		}
		sel = sel->next;
	}

        /* Selected row in bounds? */
        if ((focusrow >= 0) && (focusrow < clist->rows)) {

		/* return single directory from focused line */
		if (use_selection == 0) {
			/* determine what node got focus */
			lnode = gtk_ctree_node_nth(ctree, focusrow);
			text = gtk_ctree_node_get_row_data(ctree, lnode);

			if (text) {
				g_snprintf(tmp,MAXLINE,"file:%s", text);
				gtk_selection_data_set(
					selection_data,
					GDK_SELECTION_TYPE_STRING, 8, 
					tmp, strlen(tmp));
				data_sent = TRUE;
			}
		} else {
			/* return not from focus but all selected */ 
			strcpy(bigtmp,"");
			bufcount = 0;
			sel = clist->selection;
			while (sel) {
				lnode = sel->data;
				if (lnode) {
					text = gtk_ctree_node_get_row_data(ctree, lnode);
					if (text) {
						g_snprintf(tmp,MAXLINE,"file:%s\r\n", text);

						bufcount+=strlen(tmp);
						if (bufcount < MAXLINE*10) {
							strcat(bigtmp,tmp);		
						}
					}
				}
				sel = sel->next;
			}
			if (bufcount > 0) {
				gtk_selection_data_set(
					selection_data,
					GDK_SELECTION_TYPE_STRING, 8, 
					bigtmp, strlen(bigtmp));
				data_sent = TRUE;
			}
		}
	}

	/* we have to send something even in an error case */
	if (!data_sent) {
		const gchar *cstrptr = "Error";

		gtk_selection_data_set(
			selection_data,
			GDK_SELECTION_TYPE_STRING, 8,
			cstrptr, strlen(cstrptr));
	}
}


/* we received a drag on the ctree */

static void ctree_drag_received(GtkWidget *widget, 
        GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data,
        guint info, guint t, gpointer data) {
gchar *text;
gchar newdir[MAXLINE];
gint mastermenu;
GList *input;

	input = NULL;
	mastermenu = GPOINTER_TO_INT(data);

        /* nothing received? ignore */
        if(selection_data == NULL)
                return;
        if(selection_data->length < 0)
                return;

        if ((info == DRAG_TAR_INFO_0) ||
           (info == DRAG_TAR_INFO_1) ||
           (info == DRAG_TAR_INFO_2)) {
                text = selection_data->data;

		/* this drag was received in the master menu file tree */
		if (mastermenu) {
			/* check if it was a remove operation */
			if (extract_glist_drag_filenames(text, selection_data->length, "xrmv:", &input)) {
				/* handle the remove from the master path list */
				remove_master_dir_by_drag(input);

				free_glist(&input);
				return;
			}
		}
                if (extract_single_drag_filename(text, selection_data->length, newdir)) {
                        /* extracted the plain filename from drag */
                        if (strcmp(newdir,"") != 0) {
                                dodebug(3,"Received from drag: %s\n", newdir);
				convert_for_gtk2(newdir);
				gtk_entry_set_text(GTK_ENTRY(ctree_entry), newdir);
				/* scroll to received path */
				ctree_expand_manualpath(ctree_entry, NULL);
			}
		}
	}
}


/* creates a ctree for directory browsing */
 
GtkCTree *create_directory_ctree(gchar *basedir,gchar *title, GtkWidget *win, GtkWidget *entry, gint showfiles, gint showhidden, gint mastermenu) {
gchar tmp[MAXLINE];
GtkCTree *ctree;
GtkCTreeNode *parent;
gchar *titles[1];
gchar *text[1];
GtkStyle *style;
GtkTargetEntry target_entry[3];

        target_entry[0].target = DRAG_TAR_NAME_0;
        target_entry[0].flags = 0;
        target_entry[0].info = DRAG_TAR_INFO_0;
        target_entry[1].target = DRAG_TAR_NAME_1;
        target_entry[1].flags = 0;
        target_entry[1].info = DRAG_TAR_INFO_1;
        target_entry[2].target = DRAG_TAR_NAME_2;
        target_entry[2].flags = 0;
        target_entry[2].info = DRAG_TAR_INFO_2;

	/* save the parent window for cursor handling */
	ctree_window = win;
	ctree_entry = entry;
	ctree_showfiles = showfiles;
	ctree_showhidden = showhidden;
	ctree_basedir = basedir;

	lastactive_node = NULL;

	/* do we want a title? */
	if (title == NULL) {
		ctree = GTK_CTREE (gtk_ctree_new (1, 0));
	} else {
		titles[0] = title;
		ctree = GTK_CTREE (gtk_ctree_new_with_titles (1, 0, titles));
	}	
	ctree_base = ctree;
	gtk_clist_set_row_height(GTK_CLIST(ctree),tbf(16));

	/* create folder pixmaps */
	style = gtk_widget_get_style(GTK_WIDGET(ctree));
	pixmap1 = gdk_pixmap_create_from_xpm_d(win->window,
		&mask1,&style->bg[GTK_STATE_NORMAL],
		(gchar **) treefolderclosed_xpm);
	pixmap2 = gdk_pixmap_create_from_xpm_d(win->window,
		&mask2,&style->bg[GTK_STATE_NORMAL],
		(gchar **) treefolderopen_xpm);
	pixmap3 = gdk_pixmap_create_from_xpm_d(win->window,
		&mask3,&style->bg[GTK_STATE_NORMAL],
		(gchar **) filesmall_xpm);

	/* connect our signal stuff */
	gtk_signal_connect(GTK_OBJECT(ctree),"tree_expand",
				GTK_SIGNAL_FUNC(ctree_expand),NULL);
	gtk_signal_connect(GTK_OBJECT(ctree),"tree_collapse",
				GTK_SIGNAL_FUNC(ctree_collapse),NULL);
	gtk_signal_connect(GTK_OBJECT(ctree),"tree_select_row",
				GTK_SIGNAL_FUNC(ctree_select_row),NULL);
	gtk_signal_connect(GTK_OBJECT(ctree),"tree_unselect_row",
				GTK_SIGNAL_FUNC(ctree_unselect_row),NULL);

	/* setup drag&drop */
	if (!GTK_WIDGET_NO_WINDOW(GTK_WIDGET(ctree))) {
		/* we can drag out of the tree */
		gtk_drag_source_set(
			GTK_WIDGET(ctree), 
			GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
			target_entry,
			sizeof(target_entry) / sizeof(GtkTargetEntry),
			GDK_ACTION_MOVE | GDK_ACTION_COPY);
                gtk_signal_connect(
                        GTK_OBJECT(ctree), "drag_data_get",
                        GTK_SIGNAL_FUNC(ctree_request_dnddata), NULL);

		/* and we can receive drags */
                gtk_drag_dest_set(GTK_WIDGET(ctree), GTK_DEST_DEFAULT_MOTION |
                  GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
                  target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry),
                  GDK_ACTION_COPY | GDK_ACTION_MOVE);
                gtk_signal_connect(GTK_OBJECT(ctree), "drag_data_received",
                  GTK_SIGNAL_FUNC(ctree_drag_received), GINT_TO_POINTER(mastermenu));
	}

	/* make root entry in clist */
	strcpy(tmp,basedir); 
	convert_for_gtk2(tmp);
	text[0]=tmp;
	parent = gtk_ctree_insert_node (ctree,NULL,
		NULL,text,3,pixmap1,mask1,pixmap2,mask2,FALSE,TRUE);
	gtk_ctree_node_set_row_data(ctree,parent,g_strdup(basedir)); 
	parent_node = parent;

	ctree_add_dir_nodes(basedir,ctree,parent,
		ctree_showfiles,ctree_showhidden);

	return ctree;
}


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

	dialog_done = GPOINTER_TO_INT(data);
}


/* popup a modal window, set cursor to watch, return path or NULL-string 
   when cancel or delete_event found.
   Centers automatically above the toplevel-widow 
*/

void show_dir_tree(gchar *retvalue) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *box1,*box2,*box3;
GtkWidget *entry1,*b1_sep;
GtkWidget *scrolled_win;
gchar base_tree[MAXLINE];
gchar *p;
GtkCTree *ctree;
gint xpos, ypos;
gint xsize, ysize;
GdkCursor *cursor;
GtkRequisition rq;

	/* if another dialog is running, ignore */
	if (dialog_done == 999) {
		return;
	}

	dodebug(8, "displaying show_dir_tree\n");

	/* mark our dialog as running */
	dialog_done = 999;

	/* create new window and position it relative to the main window */
	dialog = my_gtk_dialog_new();
	set_xcdr_title(dialog, NULL, -1);
	gtk_widget_set_usize(dialog,tbf(350),tbf(300)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
                GTK_SIGNAL_FUNC (dialog_delete_event), (gpointer) dialog);

	/* create layout for dialog */
        box1 = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(dialog),box1);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_box_pack_start(GTK_BOX(box1),scrolled_win,TRUE,TRUE,0);
	gtk_widget_realize(scrolled_win);
	gtk_widget_show(scrolled_win);
	
	box3 = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(box1),box3,FALSE,TRUE,10);
	entry1 = gtk_entry_new();
	gtk_entry_set_editable(GTK_ENTRY(entry1),FALSE);
	gtk_box_pack_start(GTK_BOX(box3),entry1,TRUE,TRUE,10);
	gtk_widget_show(entry1);

        /* special case, use homedir as filetree base? */
        if (strcmp(FILETREEBASE,"$HOME") == 0) {
                p = get_pw_home((gint)geteuid());
                if (p) {
                        strncpy(base_tree, p, MAXLINE);
                } else {
                        /* fallback in case user got no home dir? */
                        strncpy(base_tree, "/tmp", MAXLINE);
                }
        } else {
                strncpy(base_tree, FILETREEBASE, MAXLINE);
        }

	ctree = create_directory_ctree(base_tree,_("Select Directory"),dialog,entry1,0,1,0);
	gtk_clist_set_column_auto_resize(GTK_CLIST(ctree),0,TRUE);
	gtk_clist_set_selection_mode (GTK_CLIST(ctree), GTK_SELECTION_BROWSE);

	gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
	gtk_widget_show( GTK_WIDGET (ctree));

	gtk_widget_show(box3);
	gtk_widget_show(box1);

	b1_sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(box1),b1_sep,FALSE,TRUE,0);
	gtk_widget_show(b1_sep);

	box2 = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,10);
	gtk_widget_show(box2);

	button1 = gtk_button_new_with_label(T_OK);
	ctree_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_set_sensitive(button1,FALSE);
	gtk_signal_connect(GTK_OBJECT(button1),"clicked",
		GTK_SIGNAL_FUNC(show_dir_btn_press), GINT_TO_POINTER(0));

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button2);
	gtk_signal_connect(GTK_OBJECT(button2),"clicked",
		GTK_SIGNAL_FUNC(show_dir_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor and change to watch */
        gtk_grab_add(dialog);
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	/* only center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
        	gdk_window_get_origin(GTK_WIDGET(toplevel)->window,&xpos,&ypos);
        	gdk_window_get_size(GTK_WIDGET(toplevel)->window,&xsize,&ysize);
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xpos+xsize/2-rq.width/2,ypos+ysize/2-rq.height/2);
	}

	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	while (dialog_done == 999) {
		wait_and_process_events();
	}

        gtk_grab_remove(GTK_WIDGET(dialog));
       	gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);

	if (dialog_done != -1) {
		strcpy(retvalue,gtk_entry_get_text(GTK_ENTRY(entry1)));
		convert_for_gtk2_filename(retvalue);
	} else {
		/* cancel or delete_event */
		strcpy(retvalue,"");
	}	

	/* free ctree */
	ctree_cleanup();
	ctree_okbutton = NULL;

	/* remove dialog window */
        gtk_widget_destroy(dialog);
}


/* fileselector-box ok-button callback */

static void file_selector_ok(GtkWidget *widget, GtkFileSelection *fs) {

	dialog_done3 = 1;
}


/* display a file-selector box with defname preselected. Return "" 
   or filename in retvalue */

void show_file_selector(gchar *title, gchar *defname, gchar *retvalue) {
GtkWidget *dialog;
gint xpos, ypos;
gint xsize, ysize;
GdkCursor *cursor;
GtkRequisition rq;
GtkButton *b1;
#if GTK_MAJOR_VERSION < 2
GtkCList *dirs;
#else
/*
GtkTreeView *dirs;
GtkTreeViewColumn *col;
*/
#endif
	/* if another dialog is running, ignore */
	if (dialog_done3 == 999) {
		return;
	}

	dodebug(8, "displaying show_fileselector\n");

	/* mark our dialog as running */
	dialog_done3 = 999;

	/* create new window and position it relative to the main window */
	dialog = gtk_file_selection_new (title);
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

	gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(dialog));
	if (defname != NULL) {
		gtk_file_selection_set_filename(GTK_FILE_SELECTION(dialog),
			defname);
	}

	/* translate the default-texts on the selector */
	b1 = GTK_BUTTON(GTK_FILE_SELECTION(dialog)->ok_button);
#if GTK_MAJOR_VERSION < 2
	gtk_label_set_text(GTK_LABEL(b1->child),T_OK);
#else
	gtk_button_set_label(GTK_BUTTON(b1),T_OK);
#endif
	b1 = GTK_BUTTON(GTK_FILE_SELECTION(dialog)->cancel_button);
#if GTK_MAJOR_VERSION < 2
	gtk_label_set_text(GTK_LABEL(b1->child),T_CANCEL);
#else
	gtk_button_set_label(GTK_BUTTON(b1),T_CANCEL);
#endif

#if GTK_MAJOR_VERSION < 2
	dirs = GTK_CLIST(GTK_FILE_SELECTION(dialog)->dir_list);
	gtk_clist_set_column_title(dirs,0,_("Directories")); 
#else
/*
	dirs = GTK_TREE_VIEW(GTK_FILE_SELECTION(dialog)->dir_list);
	col = gtk_tree_view_get_column(dirs, 0);
	gtk_tree_view_column_set_title(col, _("Directories"));	
*/
#endif

#if GTK_MAJOR_VERSION < 2
	dirs = GTK_CLIST(GTK_FILE_SELECTION(dialog)->file_list);
	gtk_clist_set_column_title(dirs,0,_("Files")); 
#else
/*
	dirs = GTK_TREE_VIEW(GTK_FILE_SELECTION(dialog)->file_list);
	col = gtk_tree_view_get_column(dirs, 0);
	gtk_tree_view_column_set_title(col, _("Files"));	
*/	
#endif

        gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
                GTK_SIGNAL_FUNC (dialog_delete_event3), dialog);

        gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(dialog)->ok_button),
		"clicked", GTK_SIGNAL_FUNC(file_selector_ok), dialog);

        gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(dialog)->cancel_button),
		"clicked", GTK_SIGNAL_FUNC(dialog_delete_event3), dialog);
	

	/* grab cursor and change to watch */
        gtk_grab_add(dialog);
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	/* only center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
        	gdk_window_get_origin(GTK_WIDGET(toplevel)->window,&xpos,&ypos);
        	gdk_window_get_size(GTK_WIDGET(toplevel)->window,&xsize,&ysize);
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xpos+xsize/2-rq.width/2,ypos+ysize/2-rq.height/2);
	}

	/* center does not work with gtk-1.2.1, but ok with 1.2.3, well
	   what the heck... */

	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	while (dialog_done3 == 999) {
		wait_and_process_events();
	}

        gtk_grab_remove(GTK_WIDGET(dialog));
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,NULL);
	gdk_cursor_destroy (cursor);

	if (dialog_done3 != -1) {
		strcpy(retvalue,gtk_file_selection_get_filename (GTK_FILE_SELECTION (dialog)));
	} else {
		/* cancel or delete_event */
		strcpy(retvalue,"");
	}	

	/* remove dialog window */
        gtk_widget_destroy(dialog);
}


/* what to do when user selects a CD from the database */

static void cddb_select_row(GtkWidget *clist, gint row, gint col,
		     GdkEventButton *event, gpointer data) {

	/* we selected something, unlook ok-button */
	gtk_widget_set_sensitive(cddb_info_okbutton,TRUE);

	/* got double-click? Simulate ok-button-press */
	if (event && event->type == GDK_2BUTTON_PRESS) {
		gtk_button_clicked(GTK_BUTTON(cddb_info_okbutton));
	}
}


/* called from cancel or ok button */
 
static void show_cddb_btn_press(GtkWidget *widget, gpointer data) {
GList *sel;
gint row;

	/* cancel event */
	if (GPOINTER_TO_INT(data) == -1) {
		if (read_done == 999) {
			/* abort our cddb-process */
			kill_readcdda();
		}
		dialog_done = -1;
		return;
	}

	/* ok button pressed - find out which entry was selected */
	sel = cddb_clist->selection;
	if (sel != NULL) {
		row = GPOINTER_TO_INT(sel->data);
		/* now go back to network code and fetch fitting CD */
		if (continue_cddb_lookup_action(row) != 0) {
			/* disable ok-button */
			gtk_widget_set_sensitive(cddb_info_okbutton,FALSE);
		} else {
			/* data ok received */
			dialog_done = 0;
		}
	}
}


/* called when somebody closes the cddb-window via window-manager */

static gint dialog_cddb_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {

	if (read_done == 999) {
		/* abort our cddb-process */
		kill_readcdda();
	}
	dialog_done = -1;
	return(TRUE);
}


/* popup a modal window, set cursor to watch, return 0 if correct
   data was received from cddb-server, -1 if not or 
   when cancel or delete_event found.
   Centers automatically above the toplevel-widow 
*/

gint show_cddb_query(GtkWidget *cdtext_parent, gint onthefly) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *box1,*box2,*hbox;
GtkWidget *f1, *cddb_logo;
GdkPixmap *p;
GdkBitmap *m;
GdkPixbuf *im;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win, *c_list;
GtkCList *clist;
gchar *titles[1];
gint xpos, ypos;
gint xsize, ysize;
GdkCursor *cursor;
GtkRequisition rq;
gchar tmp[MAXLINE];

	/* if another dialog is running, ignore */
	if (dialog_done == 999) {
		return -1;
	}

	dodebug(8, "displaying show_cddb_query\n");

	/* mark our dialog as running */
	dialog_done = 999;

	/* create new window and position it relative to the main window */
	dialog = my_gtk_dialog_new();
	set_xcdr_title(dialog, NULL, -1);
	gtk_widget_set_usize(dialog,tbf(450),tbf(260));
	/* make sure our window is always on top */
	if (cdtext_parent) {
		gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(cdtext_parent));
	} else {
		gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));
	}
	cddb_window = dialog;

        gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
                GTK_SIGNAL_FUNC (dialog_cddb_delete_event), (gpointer) dialog);

	/* create layout for dialog */
        box1 = gtk_vbox_new(FALSE,5);
	gtk_container_set_border_width (GTK_CONTAINER (box1), 5);
        gtk_container_add(GTK_CONTAINER(dialog),box1);

	hbox = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(box1),hbox,FALSE,TRUE,5);
	gtk_widget_show(hbox);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_box_pack_start(GTK_BOX(hbox),f1,TRUE,TRUE,5);
	gtk_widget_show(f1);

	lbl = gtk_label_new("");
	cddb_info_label = lbl;
	gtk_container_add(GTK_CONTAINER(f1), lbl);
	gtk_misc_set_alignment(GTK_MISC(lbl),0.0,0.5);
	gtk_misc_set_padding(GTK_MISC(lbl),10,0);
	gtk_widget_show(lbl);

	/* load a gif-image and put into a pixmap */
	g_snprintf(tmp,MAXLINE,"%s/%s", sharedir,CDDBLOGO);
#if GTK_MAJOR_VERSION < 2
	im=gdk_pixbuf_new_from_file(tmp);
#else
	im=gdk_pixbuf_new_from_file(tmp,NULL);
#endif
	if (im) {
		gdk_pixbuf_render_pixmap_and_mask(im, &p, &m, 128);
		cddb_logo = gtk_pixmap_new(p,m);
		gdk_pixbuf_unref(im);
	} else {
		cddb_logo = gtk_label_new("[CDDB]");
	}
	gtk_box_pack_start(GTK_BOX(hbox),cddb_logo,FALSE,FALSE,5);
	gtk_widget_show(cddb_logo);
	
	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_box_pack_start(GTK_BOX(box1),scrolled_win,TRUE,TRUE,0);
	gtk_widget_show(scrolled_win);
	
	titles[0] = _("Matching database entries");
	c_list = gtk_clist_new_with_titles(1,titles);
	clist = GTK_CLIST(c_list);
	cddb_clist = clist;
	gtk_clist_set_column_auto_resize(clist, 0, TRUE);
	gtk_container_add (GTK_CONTAINER (scrolled_win), c_list);
	gtk_widget_show(c_list);
	gtk_signal_connect(GTK_OBJECT(clist), "select_row",
		GTK_SIGNAL_FUNC(cddb_select_row), NULL); 

	gtk_widget_show(box1);

	b1_sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(box1),b1_sep,FALSE,TRUE,0);
	gtk_widget_show(b1_sep);

	box2 = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,TRUE,10);
	gtk_widget_show(box2);

	button1 = gtk_button_new_with_label(T_OK);
	cddb_info_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_set_sensitive(button1,FALSE);
	gtk_signal_connect(GTK_OBJECT(button1),"clicked",
		GTK_SIGNAL_FUNC(show_cddb_btn_press), GINT_TO_POINTER(0));

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button2);
	gtk_signal_connect(GTK_OBJECT(button2),"clicked",
		GTK_SIGNAL_FUNC(show_cddb_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor and change to watch */
        gtk_grab_add(dialog);
        cursor = gdk_cursor_new(GDK_WATCH);
        gdk_window_set_cursor(GTK_WIDGET(toplevel)->window,cursor);

	/* only center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
        	gtk_window_position(GTK_WINDOW(dialog),GTK_WIN_POS_NONE);
        	gdk_window_get_origin(GTK_WIDGET(toplevel)->window,&xpos,&ypos);
        	gdk_window_get_size(GTK_WIDGET(toplevel)->window,&xsize,&ysize);
		gtk_widget_size_request(dialog,&rq);
        	gtk_widget_set_uposition(GTK_WIDGET(dialog),xpos+xsize/2-rq.wid
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2008 IT MARUHN