/*
 *	menus.c
 *	27.3.99 tn
 *
 *
 *  Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
 *
 *  This file is part of xcdroast.
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

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

#define GTK_ENABLE_BROKEN

#include <gtk/gtk.h>

#include "largefile.h"

#include <locale.h>
#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 GtkWidget *mkisofs_calc_timeout_dialog;
extern img_logo_t img;


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;
gboolean show_dialog_running = FALSE;
gboolean dialog_disallow_delete = FALSE;
gboolean dialog_delete_pressed = FALSE;
gboolean cddb_gtk_main_running = FALSE;

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) {

	/* cancel close button */
	if (dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
        	return(TRUE);
	}

	if (gtk_main_level() > 0)
		gtk_main_quit();

	dialog_done = -1;
        return(TRUE);
}

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

	if (gtk_main_level() > 0)
		gtk_main_quit();

	dialog_done = GPOINTER_TO_INT(data);
}

static gint dialog_get_value() {

	return(dialog_done);
}

void set_dialog_disallow_delete() {

	dialog_delete_pressed = FALSE;
	dialog_disallow_delete = TRUE;
}

void set_dialog_allow_delete() {

	dialog_delete_pressed = FALSE;
	dialog_disallow_delete = FALSE;
}

gboolean get_dialog_delete_pressed() {

	return(dialog_delete_pressed);
}
	
void clear_dialog_delete_pressed() {

	dialog_delete_pressed = FALSE;
}

/*
 * center the given dialog over parent window, or in the middle of the screen
 */
void my_center_dialog(GtkWidget *dialog) {
gint xsize, ysize;
GtkRequisition rq;

	/* center window when toplevel visible */
	if ( GTK_WIDGET_VISIBLE(toplevel)) {
		gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
	} 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_window_move(GTK_WINDOW(dialog),xsize/2-rq.width/2,ysize/2-rq.height/2);
	}
}


/*
 * pop-up a modal window, return button pressed
 * or -1 when delete_event found.
 * Up to three buttons. Set unused buttons to NULL.
 * it centers automatically above the toplevel window 
 * if no toplevel window available center on display
 */
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;
gchar *ico;

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

	show_dialog_running = TRUE;

	/* 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));

        g_signal_connect (dialog, "delete_event",
                G_CALLBACK(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);

	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);
	}

        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);
		g_signal_connect(button1,"clicked",
			G_CALLBACK(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);
		g_signal_connect(button2,"clicked",
			G_CALLBACK(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);
		g_signal_connect(button3,"clicked",
			G_CALLBACK(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);


	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_add(dialog);
	}

	my_center_dialog(dialog);
	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 */
	gtk_main();

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_remove(GTK_WIDGET(dialog));
	}

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

	show_dialog_running = FALSE;

	return (dialog_get_value()); 
}

/*
 * force close the show_dialog() window
 */
void cancel_show_dialog() {

	if (show_dialog_running)
		dialog_btn_press(NULL, GINT_TO_POINTER(-1));
}

/*
 * another version of the dialog -> with nice xcdroast logo on top
 */
gint show_fancy_dialog(gchar *htext, gchar *ttext, gchar *btn1, gchar *btn2, gint defbutton) {
GtkWidget *dialog, *xcdroast_logo, *vbox;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2, *f1, *l1, *lab;
gchar tmp[MAXLINE];

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

	/* 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));

        g_signal_connect (dialog, "delete_event",
               	G_CALLBACK (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 */
        xcdroast_logo = display_logo(img.xcdrlogo_middle, "[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,PANGO_BOLD,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);
		g_signal_connect(button1,"clicked",
			G_CALLBACK(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);
		g_signal_connect(button2,"clicked",
			G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(1));
		GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
		if (defbutton == 1) gtk_widget_grab_default (button2);
	}


	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_add(dialog);
	}

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	gtk_main();

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_remove(GTK_WIDGET(dialog));
	}

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

	return (dialog_get_value()); 
}

/*
 * show about dialog
 */
void show_about_dialog() {
GtkWidget *dialog, *xcdroast_logo;
GtkWidget *button1;
GtkWidget *box1, *box2, *l1, *l2, *l3, *l4, *l5, *l6;
gchar tmp[MAXLINE];

	/* 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));

        g_signal_connect (dialog, "delete_event",
                G_CALLBACK (dialog_delete_event), (gpointer) dialog);

	gtk_widget_set_size_request(dialog, 500, -1);

	/* 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 */
        xcdroast_logo = display_logo(img.xcdrlogo_middle, "[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);
        gtk_box_pack_start(GTK_BOX(box1),l1,FALSE,FALSE,0);
        gtk_widget_show(l1);

        g_snprintf(tmp,MAXLINE,_("A flexible frontend for optical disc authoring."));
        l2 = gtk_label_new(tmp);
        gtk_label_set_justify(GTK_LABEL(l2),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(box1),l2,FALSE,FALSE,15);
        gtk_widget_show(l2);

        g_snprintf(tmp,MAXLINE,_("<a href=\"http://www.xcdroast.org\">Homepage</a>"));
        l3 = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(l3), tmp);	
        gtk_label_set_justify(GTK_LABEL(l3),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(box1),l3,FALSE,FALSE,5);
        gtk_widget_show(l3);

        g_snprintf(tmp,MAXLINE,_("<a href=\"http://www.xcdroast.org/faq.html\">Help / FAQ</a>"));
        l4 = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(l4), tmp);	
        gtk_label_set_justify(GTK_LABEL(l4),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(box1),l4,FALSE,FALSE,0);
        gtk_widget_show(l4);

        g_snprintf(tmp,MAXLINE,_("<a href=\"http://www.xcdroast.org/translations.html\">Translations</a>"));
        l5 = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(l5), tmp);	
        gtk_label_set_justify(GTK_LABEL(l5),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(box1),l5,FALSE,FALSE,5);
        gtk_widget_show(l5);

        g_snprintf(tmp,MAXLINE,_("Copyright &#xA9; 1996-2018 Thomas Niederreiter"));
        l6 = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(l6), tmp);	
        gtk_label_set_justify(GTK_LABEL(l6),GTK_JUSTIFY_CENTER);
        gtk_box_pack_start(GTK_BOX(box1),l6,FALSE,FALSE,10);
        gtk_widget_show(l6);

        box2 = gtk_hbox_new(FALSE,0);

        button1 = gtk_button_new_with_label (T_CLOSE);
	gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,FALSE,10);
	gtk_widget_show(button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), NULL);
        gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,10);
        gtk_widget_show(box2);

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_add(dialog);
	}

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	gtk_main();

	if (GTK_WIDGET_MAPPED(toplevel)) {
        	gtk_grab_remove(GTK_WIDGET(dialog));
	}

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

	return;
}


/*
 * 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 too 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, don't 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 too 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 don't 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, 
					(const unsigned char *) 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, 
					(const unsigned char *) 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,
			(const unsigned char *) 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 = (char *) 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 */
	g_signal_connect(ctree,"tree_expand",
				G_CALLBACK(ctree_expand),NULL);
	g_signal_connect(ctree,"tree_collapse",
				G_CALLBACK(ctree_collapse),NULL);
	g_signal_connect(ctree,"tree_select_row",
				G_CALLBACK(ctree_select_row),NULL);
	g_signal_connect(ctree,"tree_unselect_row",
				G_CALLBACK(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);
                g_signal_connect(
                        ctree, "drag_data_get",
                        G_CALLBACK(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);
                g_signal_connect(ctree, "drag_data_received",
                  G_CALLBACK(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;
}


/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
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;

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

	/* 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_size_request(dialog, tbf(350), tbf(300)); 

	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect (dialog, "delete_event",
                G_CALLBACK(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);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_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);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(-1));

        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	gtk_main();


	if (dialog_get_value() != -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;

        gtk_grab_remove(GTK_WIDGET(dialog));

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


/*
 * display a file-selector box with defname preselected. 
 * If mode=0 -> Load, Mode=1 -> Save, Return "" 
 * or filename in retvalue
 */
void show_file_selector(gchar *title, gint mode, gchar *defname, gchar *retvalue) {
GtkWidget *dialog;
gchar filename[MAXLINE];
gchar dirname[MAXLINE];
gchar notildename[MAXLINE];

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

	/* create new window and position it relative to the main window */
	if (mode == MODE_OPEN)
        	dialog = gtk_file_chooser_dialog_new (title,
				      GTK_WINDOW(toplevel),
				      GTK_FILE_CHOOSER_ACTION_OPEN,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
				      NULL);
	else
        	dialog = gtk_file_chooser_dialog_new (title,
				      GTK_WINDOW(toplevel),
				      GTK_FILE_CHOOSER_ACTION_SAVE,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
				      NULL);

        gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);

	if (defname != NULL) {
		get_purefile(defname, filename);
		strncpy(notildename,defname,MAXLINE);
		check_tilde(notildename);

		strncpy(dirname,notildename,MAXLINE);
		if (get_basedir(dirname) != NULL) {
			gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
		}
		if (mode == MODE_OPEN)
			gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (dialog), notildename);
		else
			gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
	}

	gtk_widget_show(dialog);
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));
	gtk_grab_add(dialog);

	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { 
		strncpy(retvalue, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)), MAXLINE);
	} else {
		/* cancel or delete_event */
		strcpy(retvalue,"");
	}	

	gtk_grab_remove(dialog);

	/* 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();
		}
		if (cddb_gtk_main_running)
			dialog_btn_press(widget, GINT_TO_POINTER(-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, autoclose window */
			if (cddb_gtk_main_running)
                        	dialog_btn_press(widget, GINT_TO_POINTER(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();
	}
	if (cddb_gtk_main_running)
		dialog_btn_press(widget, GINT_TO_POINTER(-1));

	return (TRUE);
}


/*
 * pop-up a modal window, return 0 if correct
 * data was received from cddb-server, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
gint show_cddb_query(GtkWidget *cdtext_parent, gint onthefly) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *box1,*box2,*hbox;
GtkWidget *f1, *cddb_logo;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win, *c_list;
GtkCList *clist;
gchar *titles[1];
gint lookup_result;

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

	/* 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_size_request(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;

        g_signal_connect (dialog, "delete_event",
                G_CALLBACK (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 */
        cddb_logo = display_logo(img.cddblogo, "[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);
	g_signal_connect(clist, "select_row",
		G_CALLBACK(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);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(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);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(show_cddb_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* lets do some work */
	if (cdtext_parent) {
		/* special case when on-the-fly */
		if (onthefly) {
			lookup_result = start_cddb_lookup_action(2);
		} else {
			lookup_result = start_cddb_lookup_action(1);
		}
	} else {
		lookup_result = start_cddb_lookup_action(0);
	}

	/* don't autoclose window if lookup_result == 0 (no track titles read) */
	if (lookup_result == 0) {
		cddb_gtk_main_running = TRUE;
		gtk_main();
		cddb_gtk_main_running = FALSE;
	} else {
		/* tracktitles read, finish here quickly */
		dialog_done = 0;
	}

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * start the read-processes according to the trackreadset-struct.
 * Update read-dialogbox and return 0 if ok, 1 on error - call
 * cdda2wav in bulk mode
 */
static gint start_read_action_bulk(gint read_devnr) {
GList *loop;
track_read_param_t *trackparam;
gfloat percent_done;
gint stat, count;
gint audiocount, datacount;

	if (strcmp(trackreadset.tocfile,"") == 0) {
		/* should not happen */
		return 1;
	}

	dolog(1, "Reading Disc with toc file %s (bulk)\n", trackreadset.tocfile);

	percent_done = 0.0;
	count = 0;
	audiocount = 0;
	datacount = 0;

	/* start reading tracks */
	loop = g_list_first(trackreadset.trackparams);
	while (loop) {
		trackparam = loop->data;
		count++;
		
		/* data-track */
		if (trackparam->tracktype == 0) {
			stat = read_data_track(read_devnr,
				trackparam->starttrack,
				trackparam->kbyte,
				trackparam->trackfile,
				trackparam->startoffset,	
				trackparam->endoffset,
				trackreadset.nrtracks,				
				trackparam->percent,
				percent_done, count);
			datacount++;
			percent_done += trackparam->percent;
		} else {
			/* audio-track */
			/* don't read them here - do them as bulk later */
			audiocount++;
			stat = 0;
		}
		if (stat == 0) {
			/* no error */
			/* write inf-file */
			write_inf_file(trackparam); 
		} else {
			/* error while reading */
			return 1;
		}
		loop = loop->next;
	}

	/* ok, we have read all data tracks - now check if there 
	   are audio tracks to do */
	if (audiocount > 0) {
		if (start_bulk_read_action(read_devnr, percent_done,
		    datacount+1) != 0) {
			/* error while reading? */
			return 1;
		}
	}

	/* save the toc file (not for read single tracks) */
	if (strcmp(trackreadset.tocfile,"") != 0) {
		write_copy_cd_toc_file(trackreadset.tocfile);
	}

	/* unset current active toc-file */
	g_free(curset.tocfile);
	curset.tocfile = g_strdup("");

	/* no error reading tracks */
	gtk_label_set_text(GTK_LABEL(readtrack_info_label), _("Tracks successfully read"));
	gtk_label_set_text(GTK_LABEL(readtrack_small_info), _("Successful:"));

	/* now set progressbars to 100% - elsewhere we may end up
	   with 99% due rounding errors */
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar1),1.0);
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar2),1.0);
	set_xcdr_title(toplevel,viewmode_dialog,100);

	return 0;
}


/*
 * start the read-processes according to the trackreadset-struct.
 * Update read-dialogbox and return 0 if ok, 1 on error
 */
static gint start_read_action(gint read_devnr) {
GList *loop;
track_read_param_t *trackparam;
gfloat percent_done;
gint stat, count;

	if (strcmp(trackreadset.tocfile,"") != 0) {
		dolog(1, "Reading Disc with toc file %s\n", trackreadset.tocfile);
	} else {
		dolog(1, "Reading single tracks\n");
	}
	percent_done = 0;
	count = 0;

	/* start reading tracks */
	loop = g_list_first(trackreadset.trackparams);
	while (loop) {
		trackparam = loop->data;
		count++;
		
		/* data-track */
		if (trackparam->tracktype == 0) {
			stat = read_data_track(read_devnr,
				trackparam->starttrack,
				trackparam->kbyte,
				trackparam->trackfile,
				trackparam->startoffset,	
				trackparam->endoffset,
				trackreadset.nrtracks,				
				trackparam->percent,
				percent_done, count);
		} else {
		/* audio-track */
			stat = read_audio_track(read_devnr,
				trackparam->starttrack,
				trackparam->endtrack,
				trackparam->kbyte,
				trackparam->trackfile,
				trackparam->startoffset,
				trackparam->endoffset,
				trackreadset.nrtracks,				
				trackparam->percent,
				percent_done, count);
		}
		if (stat == 0) {
			/* no error */
			percent_done += trackparam->percent;

			/* write inf-file */
			write_inf_file(trackparam); 
		} else {
			/* error while reading */
			return 1;
		}
		loop = loop->next;
	}

	/* save the toc file (not for read single tracks) */
	if (strcmp(trackreadset.tocfile,"") != 0) {
		write_copy_cd_toc_file(trackreadset.tocfile);
	}

	/* unset current active toc-file */
	g_free(curset.tocfile);
	curset.tocfile = g_strdup("");

	/* no error reading tracks */
	gtk_label_set_text(GTK_LABEL(readtrack_info_label), _("Tracks successfully read"));
	gtk_label_set_text(GTK_LABEL(readtrack_small_info), _("Successful:"));

	/* now set progressbars to 100% - elsewhere we may end up
	   with 99% due rounding errors */
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar1),1.0);
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar2),1.0);
	set_xcdr_title(toplevel,viewmode_dialog,100);

	return 0;
}


/*
 * called from cancel or ok button
 */
static void show_readtrack_btn_press(GtkWidget *widget, gpointer data) {

	/* read-process running? */
	if (read_done == 999) {
		read_abort_mark = 1;
		/* abort our read-process */
		kill_readcdda();
		return;
	}

	/* cancel event */
	if (GPOINTER_TO_INT(data) == -1) {
		dialog_btn_press(widget, data);
		return;
	}
}

static void show_readtrack_save_press(GtkWidget *widget, gpointer data) {
char tmp[MAXLINE];

	/* show fileselector */
	show_file_selector(_("Save Output"), MODE_SAVE, SAVEREADTRACKS,tmp);
	
	/* not cancel pressed? */
	if (strcmp(tmp,"") != 0) {
		if (save_text2file(tmp, readtrack_textview) == 0) {
			show_dialog(ICO_INFO,_("Saving output successful"), T_OK, NULL, NULL, 0);
		}
	}
}

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

	if (dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
		return (TRUE);
	}

	/* read-process running? */
	if (read_done == 999) {
		read_abort_mark = 1;
		/* abort our read-process */
		kill_readcdda();
		return(TRUE);
	}

	return (dialog_delete_event(widget, event, data));
}


/*
 * change the read-tracks menu according to view-setting
 */
static void viewmode_selected(GtkWidget *item, gpointer data) {
gint idx;	

	idx = gtk_combo_box_get_active(GTK_COMBO_BOX(item));

	curset.proc_view = idx;
	gtk_window_set_resizable(GTK_WINDOW(viewmode_dialog), FALSE);

	if (idx == 2) {
		/* extended view */
		gtk_widget_show(readtrack_info_frame);
		gtk_widget_show(readtrack_info_tbl);
		gtk_widget_show(viewmode_scrolled);
		gtk_widget_show(readtrack_savebutton);
		gtk_widget_hide(readtrack_small_info);
		gtk_widget_hide(readtrack_small_info2);
	} else if (idx == 1) {
		/* normal view */
		gtk_widget_show(readtrack_info_frame);
		gtk_widget_show(readtrack_info_tbl);
		gtk_widget_hide(viewmode_scrolled);
		gtk_widget_hide(readtrack_savebutton);
		gtk_widget_hide(readtrack_small_info);
		gtk_widget_hide(readtrack_small_info2);
	} else {
		/* small view */
		gtk_widget_hide(readtrack_info_frame);
		gtk_widget_hide(readtrack_info_tbl);
		gtk_widget_hide(viewmode_scrolled);
		gtk_widget_hide(readtrack_savebutton);
		gtk_widget_show(readtrack_small_info);
		gtk_widget_show(readtrack_small_info2);
	}

	while (gtk_events_pending())
		gtk_main_iteration();

	gtk_window_set_resizable(GTK_WINDOW(viewmode_dialog), TRUE);
}


/*
 * pop-up a modal window, trigger read tracks 
 * and return 0 if all ok, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
gint show_and_do_read_tracks(gint devnr, gint bulk) {
GtkWidget *omenu;
GtkWidget *dialog;
GtkWidget *l1;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1, *tbl;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win;
GtkAdjustment *adj1, *adj2;
GtkWidget *pbar1, *pbar2;
gint i, menuidx, menuhistory;
static const gchar *viewmodes[] = VIEW_MODES;
PangoFontDescription *font;

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

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

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (readtrack_dialog_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);

	f1 = gtk_frame_new(NULL);
	readtrack_info_frame = f1;
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_widget_set_size_request(f1, -1, 36);
	gtk_box_pack_start(GTK_BOX(box1),f1,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(f1);

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

	tbl = gtk_table_new(2, 10, TRUE);
	readtrack_info_tbl = tbl;
	gtk_table_set_col_spacing(GTK_TABLE(tbl),1,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Track:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	adj1 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar1 = gtk_progress_bar_new_with_adjustment(adj1);
	readtrack_pbar1 = pbar1;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar1),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar1),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar1,2,10,0,1);
	gtk_widget_show(pbar1);

	l1 = rightjust_gtk_label_new(_("Total:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
	gtk_widget_show(l1);

	adj2 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar2 = gtk_progress_bar_new_with_adjustment(adj2);
	readtrack_pbar2 = pbar2;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar2),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar2),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar2,2,10,1,2);
	gtk_widget_show(pbar2);

	tbl = gtk_table_new(1, 10, TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),6,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	lbl = gtk_label_new("");
	readtrack_small_info = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,3,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	lbl = gtk_label_new("");
	readtrack_small_info2 = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,3,5,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	l1 = rightjust_gtk_label_new(_("View:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,5,7,0,1);
	gtk_widget_show(l1);

	omenu = gtk_combo_box_text_new();
	menuidx = 0; menuhistory = -1;

	for (i=0; i<3; i++) {
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(omenu), _(viewmodes[i]));
		if (curset.proc_view == i) { menuhistory = menuidx; }
		menuidx++;
	}

	if (menuhistory != -1) {
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), menuhistory);
	} else {
		curset.proc_view = 1;
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), 1);
	}
	g_signal_connect(omenu, "changed", G_CALLBACK(viewmode_selected), NULL);

	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,7,10,0,1);
	gtk_widget_show(omenu);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	viewmode_scrolled = scrolled_win;
	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);

	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	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_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(show_readtrack_btn_press), GINT_TO_POINTER(-1));

	button2 = gtk_button_new_with_label(_("Save Output"));
	readtrack_savebutton = button2;
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(show_readtrack_save_press), GINT_TO_POINTER(-1));
	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(button2);


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	/* here is the action */
	if (bulk == 0) {
		/* read all selected tracks one at a time */
		start_read_action(devnr);
	} else {
		/* use bulk mode of cdda2wav */
		start_read_action_bulk(devnr);
	}

	/* update image-dir-lists */
	scan_imagedirs();

	/* when done with reading rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);
	
	dobeep(1);

	gtk_main();

	store_win_geometry(GTK_WIDGET(dialog));
	set_xcdr_title(dialog, toplevel, -1);

        gtk_grab_remove(GTK_WIDGET(dialog));

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


	return (dialog_get_value());
}

/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void show_device_detail(gint devnr) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1;
GtkWidget *scrolled_win;
PangoFontDescription *font;

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

	/* 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_size_request(dialog, tbf(550), tbf(300)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Detailed Device Information:"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	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_container_add(GTK_CONTAINER(f1),scrolled_win);
	gtk_widget_show(scrolled_win);
	
        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	gtk_widget_show(box1);

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

	button1 = gtk_button_new_with_label(T_OK);
	gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);

	/* now fill text-widget with infos */
	fill_device_info(devnr, txt);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void display_atip_info(gint devnr) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1;
GtkWidget *scrolled_win;
PangoFontDescription *font;

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

	/* 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_size_request(dialog, tbf(500), tbf(400)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("ATIP (absolute Time in Pregroove)-Information:"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	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_container_add(GTK_CONTAINER(f1),scrolled_win);
	gtk_widget_show(scrolled_win);
	
        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	gtk_widget_show(box1);

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

	button1 = gtk_button_new_with_label(T_OK);
	gtk_box_pack_start(GTK_BOX(box2),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);

	/* now fill text-widget with infos */
	get_atip_info(devnr, txt);

	gtk_widget_show(dialog);

	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


/*
 * callbacks for blank-menu
 */
static void blankmode_selected(GtkWidget *item, gpointer data) {

	curset.blankmode = gtk_combo_box_get_active(GTK_COMBO_BOX(item)); 
}

static void blankoptions_selected(GtkWidget *item, gpointer nr) {
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	switch(GPOINTER_TO_INT(nr)) {
		case 0:
			curset.blank_force = sel;
			break;
		case 1:
			curset.blank_eject = sel;
			break;
	}
}


/*
 * timer function for blanking
 */
static gint blank_timer(gpointer data) {
time_t start_time;
time_t curtime;
gint secs;
char tmp[MAXLINE];

	/* how many seconds have passed since first start? */
	start_time = (time_t)data;
	curtime = time((time_t *) 0);
	secs = (gint) curtime - start_time;

	/* set new label */
	g_snprintf(tmp,MAXLINE,_("Blanking in progress for %2d:%02d min."),secs/60,secs%60);
	gtk_label_set_text(GTK_LABEL(blank_infolabel),tmp);

	return(TRUE);
}


/*
 * called by ok-button in blank-window
 */
static void blank_start(GtkWidget *widget, gpointer data) {
time_t start_time;
time_t curtime;
gint secs;
gint stat;
char tmp[MAXLINE];
GtkTextBuffer *buffer;
GtkTextIter start, end;


	/* get current time */
	start_time = time((time_t *) 0); 
	misc_timer = g_timeout_add(1000, blank_timer, GINT_TO_POINTER(start_time));
		
	/* disable ok button */
	gtk_widget_set_sensitive(widget, FALSE);
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_CANCEL);

	/* clear text-window */
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(blank_text_window));
	gtk_text_buffer_get_bounds(buffer, &start, &end);
	gtk_text_buffer_delete(buffer, &start, &end);
	
	/* now this waits here until blanking is done */
	stat = start_blanking_process(curset.writer_devnr, blank_text_window);

	if (stat == 1) {
		/* error? */
		gtk_label_set_text(GTK_LABEL(blank_infolabel),_("Error while blanking."));
	} else
	if (stat == 0) {
		/* ok */
		curtime = time((time_t *) 0);
		secs = (gint) curtime - start_time;
		g_snprintf(tmp,MAXLINE,_("Blanking successful. Time: %2d:%02d min."),secs/60,secs%60);
		gtk_label_set_text(GTK_LABEL(blank_infolabel),tmp);
	} else {
		/* aborted */
		curtime = time((time_t *) 0);
		secs = (gint) curtime - start_time;
		g_snprintf(tmp,MAXLINE,_("Blanking aborted after %2d:%02d min."),secs/60,secs%60);
		gtk_label_set_text(GTK_LABEL(blank_infolabel),tmp);
	}
	
	if (misc_timer != 0) 
		g_source_remove(misc_timer);
	misc_timer = 0;

	/* enable ok button */
	gtk_widget_set_sensitive(widget, TRUE);
	
	/* restore close button */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_CLOSE);

	dobeep(1);
}


/*
 * called by cancel-button in blank-window
 */
static void blank_cancel(GtkWidget *widget, gpointer data) {

	/*
	 * no more to do here because the actual killing
	 * is handled in start_blanking_process()
	 */
	dialog_delete_event(widget, NULL, data);
}

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

	blank_cancel(widget,data);
        return(TRUE);
}


/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void display_blank_cdrw(gint devnr) {
GtkWidget *dialog, *tbl;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*box3,*txt;
GtkWidget *f1, *l1, *check, *sep;
GtkWidget *omenu;
GtkWidget *scrolled_win;
gint i,j, menuhistory, menuidx;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
static const gchar *blanktrans[] = BLANK_MODES;
PangoFontDescription *font;
 
	dodebug(8, "displaying display_blank_cdrw\n");

	misc_timer = 0;

	/* 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_size_request(dialog, tbf(500), tbf(300)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (blank_delete_event), (gpointer) dialog);

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

        if (!curset.isProDVD) {
		f1 = gtk_frame_new(_("Blank Disc"));
        } else {
		f1 = gtk_frame_new(_("Blank CD/DVD+-RW"));
        }
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	tbl = gtk_table_new(5, 8, FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),10);
	gtk_box_pack_start(GTK_BOX(box2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Blank-Mode:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,3,0,1);
	gtk_widget_show(l1);	
	
	omenu = gtk_combo_box_text_new();
	menuidx = 0; menuhistory = 0;

	i = 0; 
	while (blankmodes[i] != NULL) {
	
		strncpy(tmp, blankmodes[i]->desc, MAXLINE);

		/* get translation to blank mode if available */
		j = 0;
		while (blanktrans[j]) {
			if (strcmp(blankmodes[i]->desc,
			    blanktrans[j]) == 0) {
				strncpy(tmp, _(blanktrans[j]), MAXLINE);
			}
			j++;
		}
		
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(omenu), tmp);

		if (curset.blankmode == i) { menuhistory = menuidx; }
		menuidx++;
		i++;
	}

	gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), menuhistory);

	g_signal_connect(omenu, "changed", G_CALLBACK(blankmode_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,3,8,0,1);
	gtk_widget_show(omenu);	

	check = gtk_check_button_new_with_label(_("Force blanking"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(blankoptions_selected),GINT_TO_POINTER(0));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,3,8,1,2);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.blank_force);
	gtk_widget_show(check);

	check = gtk_check_button_new_with_label(_("Eject Disc after blanking"));
	g_signal_connect(check,"clicked",
		G_CALLBACK(blankoptions_selected),GINT_TO_POINTER(1));
	gtk_table_attach_defaults(GTK_TABLE(tbl),check,3,8,2,3);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
		curset.blank_eject);
	gtk_widget_show(check);

	sep = gtk_hseparator_new();
	gtk_table_attach_defaults(GTK_TABLE(tbl),sep,0,8,3,4);
	gtk_widget_show(sep);
	
	f1 = gtk_frame_new(NULL);

	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_set_border_width (GTK_CONTAINER (f1), 5);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,8,4,5);
	gtk_widget_show(f1);

	l1 = gtk_label_new("");
	blank_infolabel = l1;
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);	

	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_container_add(GTK_CONTAINER(box2),scrolled_win);
	gtk_widget_show(scrolled_win);
	
        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	blank_text_window = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	gtk_widget_show(box1);

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

        if (!curset.isProDVD) {
		button1 = gtk_button_new_with_label(_("Blank Disc"));
        } else {
		button1 = gtk_button_new_with_label(_("Blank CD/DVD+-RW"));
        }
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(blank_start), NULL);

	button2 = gtk_button_new_with_label(T_CLOSE);
	readtrack_button = button2;
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(blank_cancel), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);

	/* now fill text-widget with infos */
	strncpy(tmp2, _("Hint: Fully blanking an entire Disc takes about 21 min at 4x CD-RW media and about 15 min at 4x DVD-RW media. Minimally blanking is done in a minute."), MAXLINE);
	append_to_text_view(txt, tmp2);

	gtk_widget_show(dialog);

	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


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

	dialog_delete_event(widget, NULL, data);
}

static gint advoptions_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
        return (dialog_delete_event(widget, event, data));
}

static void advoptions_save(GtkWidget *widget, gpointer data) {
gchar tmp2[MAXLINE];

        dolog(2, "Save write-options as default\n");

        /* write file */
        if (save_writeoptions_file(configdir, WRITEOPTFILE) == 1) {
                /* save failed */
                g_snprintf(tmp2,MAXLINE,_("Failed to save write options file: %s"), ISOOPTFILE);
                show_dialog(ICO_WARN, tmp2, T_OK, NULL, NULL, 0);
        } else {
                /* save ok */
                show_dialog(ICO_INFO,_("Options saved"), T_OK, NULL, NULL, 0);
        }
}

static void varirec_selected(GtkWidget *item, gpointer data) {
gchar tmp[MAXLINE];
gint sel;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	if (!sel) {
		/* disable varirec */
		g_snprintf(tmp, MAXLINE,"%d", curset.writevarirec);
		if (curset.writevarirec < 50 && does_support_varirec(curset.writer_devnr))
			curset.writevarirec += 100;
		gtk_widget_set_sensitive(varirec_scale, FALSE);
		set_labelcolor(varirec_label, DISABLEDCOLOR);
	} else {
		if (curset.writevarirec > 50)
			curset.writevarirec -= 100;
		gtk_widget_set_sensitive(varirec_scale, TRUE);
		set_labelcolor(varirec_label, ENABLEDCOLOR);
		g_snprintf(tmp, MAXLINE,"%d", curset.writevarirec);
	}
	gtk_label_set_text(GTK_LABEL(varirec_label),tmp);
}

static void varirec_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];

	g_snprintf(tmp, MAXLINE,"%d",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);

	curset.writevarirec = (gint)adj->value;
}


/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void display_advwriteoptions(gint devnr) {
GtkWidget *dialog, *tbl;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1, *check, *l1, *scale;
GtkObject *adj1;
gfloat fval;
 
	dodebug(8, "displaying additional write options\n");

	/* mark our dialog as running */
	misc_timer = 0;

	/* 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_size_request(dialog, tbf(300), tbf(270)); 

	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (advoptions_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Advanced write parameters"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	tbl = gtk_table_new(8, 16, FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

        check = gtk_check_button_new_with_label(_("Swap Audio byte order"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(3));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeswap);
        gtk_widget_show(check);
        define_tooltip(check,_("Swaps the byte-order of audio-tracks. This is needed when you end up with an audio-CD which only contains static noise."));

        check = gtk_check_button_new_with_label(_("Allow overburning"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(7));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeoverburn);
        gtk_widget_show(check);
        define_tooltip(check,_("Allows to write more than the official size of a medium. Most Disc writers support it only in DAO mode. It may however do not work at all, you have to test it. (If X-CD-Roast still warns about non-fitting data, ignore this.)"));

        check = gtk_check_button_new_with_label(_("Ignore medium size"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(11));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,2,3);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeignsize);
        gtk_widget_show(check);
	define_tooltip(check,_("Ignore the known size of the medium. This option should be used with extreme care and is only required for debugging purposes.")); 

        check = gtk_check_button_new_with_label(_("Set SCSI IMMED flag"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(12));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                curset.writeimmed);
        gtk_widget_show(check);
	define_tooltip(check,_("If you have problems with a freezing system when blanking or fixating a Disc you can try to enable this option. It also might reduce stress on systems where the writer is on the same IDE bus as the hard drive. Use at own risk only."));

        check = gtk_check_button_new_with_label(_("Enable Yamaha Audio Master mode"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(9));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,4,5);
	if (does_support_audiomaster(curset.writer_devnr)) {
        	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                	curset.writeaudiomaster);
	}
        gtk_widget_show(check);
	define_tooltip(check,_("Turn on the Yahama Audio Master Q. R. feature which usually should result in high quality CDs that have less reading problems in HiFi players. This reduces the capacity of a 74 minute CD to 63 minutes and a 80 minute CD to 68 minutes. (Only works in DAO mode)"));

	if (!does_support_audiomaster(curset.writer_devnr)) 
		gtk_widget_set_sensitive(check,FALSE);

        check = gtk_check_button_new_with_label(_("Enable Forcespeed mode"));
        g_signal_connect(check,"clicked",
                G_CALLBACK(writeoptions_selected),GINT_TO_POINTER(10));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,5,6);
	if (does_support_forcespeed(curset.writer_devnr)) {
        	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                	curset.writeforcespeed);
	}
        gtk_widget_show(check);
	define_tooltip(check,_("This option forces a drive to ignore the medium quality (and a possible automatic write speed reduction) and to use the selected speed. Should only be used with extreme care."));

	if (!does_support_forcespeed(curset.writer_devnr)) 
		gtk_widget_set_sensitive(check,FALSE);

        check = gtk_check_button_new_with_label(_("Enable Plextor VariRec mode:"));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,1,16,6,7);
	if (curset.writevarirec < 50 && does_support_varirec(curset.writer_devnr)) {
        	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                	TRUE);
	}
        gtk_widget_show(check);
	define_tooltip(check,_("The VariRec option changes the laser power used to write CDs. This can increase compatibility with some playback devices. Values from -2 to 2 are valid and please note that the write speed will drop to 4x."));

	if (!does_support_varirec(curset.writer_devnr)) 
		gtk_widget_set_sensitive(check,FALSE);

        f1 = gtk_frame_new(NULL);
        gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
        gtk_container_border_width(GTK_CONTAINER(f1),3);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,4,7,7,8);
        gtk_widget_show(f1);

	l1 = gtk_label_new("");
	varirec_label = l1;
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);


        adj1 = gtk_adjustment_new(0.0,-2.0,3.0,1.0,1.0,1.0);
        g_signal_connect((adj1), "value_changed",
                G_CALLBACK(varirec_changed), l1);
        scale = gtk_hscale_new(GTK_ADJUSTMENT (adj1));
	varirec_scale = scale;
        gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
        gtk_scale_set_digits(GTK_SCALE(scale),0);
        gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),scale,7,15,7,8);
	if (curset.writevarirec < 50) {
		/* work around stupid slider bugs in GTK */
		if (curset.writevarirec < 0) {
			fval = (gfloat)curset.writevarirec-0.1;
		} else {
			fval = (gfloat)curset.writevarirec+0.1;
		}	
        	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj1),fval);
	} else {
		/* work around stupid slider bugs in GTK */
		if ((curset.writevarirec-100) < 0) {
			fval = (gfloat)(curset.writevarirec-100)-0.1;
		} else {
			fval = (gfloat)(curset.writevarirec-100)+0.1;
		}	
        	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj1),fval);
	}
        gtk_widget_show(scale);

        g_signal_connect(check,"clicked",
                G_CALLBACK(varirec_selected),NULL);
	varirec_selected(check, NULL);


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

	button1 = gtk_button_new_with_label(T_CLOSE);
	readtrack_button = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(advoptions_close), GINT_TO_POINTER(-1));
	gtk_widget_show(button1);

	button2 = gtk_button_new_with_label(_("Save"));
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(advoptions_save), NULL);
	gtk_widget_show(button2);
	define_tooltip(button2,_("Saves the current set of write parameters as default values for the next startup of X-CD-Roast."));

	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


static void isolevel_selected(GtkWidget *item, gpointer data) {
gchar tmp[MAXLINE];
gint sel;
GtkAdjustment *adj;
GtkRange *range;

	sel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	if (!sel) {
		g_snprintf(tmp, MAXLINE,"%d", masterparam.opt[23]);
		masterparam.opt[23] = 0;
		gtk_widget_set_sensitive(isolevel_scale, FALSE);
		set_labelcolor(isolevel_label, DISABLEDCOLOR);
	} else {
		gtk_widget_set_sensitive(isolevel_scale, TRUE);
		set_labelcolor(isolevel_label, ENABLEDCOLOR);

		/* get value from scale */
		range = GTK_RANGE(isolevel_scale);
		adj = range->adjustment;
		masterparam.opt[23] = (gint)adj->value;
		g_snprintf(tmp, MAXLINE,"%d", masterparam.opt[23]);

	}
	gtk_label_set_text(GTK_LABEL(isolevel_label),tmp);
}

static void isolevel_changed(GtkAdjustment *adj, GtkWidget *label) {
gchar tmp[MAXLINE];

	g_snprintf(tmp, MAXLINE,"%d",(gint)adj->value);
	gtk_label_set_text(GTK_LABEL(label),tmp);

	masterparam.opt[23] = (gint)adj->value;
}


/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void display_advisooptions() {
GtkWidget *dialog, *tbl;
GtkWidget *button1;
GtkWidget *box1,*box2,*box3;
GtkWidget *l1, *f1, *check, *scale;
GtkObject *adj1;

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

	misc_timer = 0;

	/* 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_size_request(dialog, tbf(350), tbf(390)); 

	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (advoptions_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Advanced ISO9660 options"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	tbl = gtk_table_new(13, 16, FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);


        /* -allow-lowercase */
        check = gtk_check_button_new_with_label(_("Allow lowercase ISO9660 filenames"));
        isoopts[17] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(17));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,0,1);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[17]);
        gtk_widget_show(check);
        define_tooltip(check, _("This options allows lower case characters to appear in ISO9660 filenames. This violates the ISO9660 standard, but happens to work on some systems. Use with caution."));

        /* -allow-multidot */
        check = gtk_check_button_new_with_label(_("Allow multiple dots in ISO9660 filenames"));
        isoopts[18] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(18));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,1,2);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[18]);
        gtk_widget_show(check);
        define_tooltip(check, _("This options allows more than one dot to appear in ISO9660 filenames. Leading dots are not affected by this option. This violates the ISO9660 standard, but happens to work on many systems. Use with caution."));

        /* -no-iso-translate */
        check = gtk_check_button_new_with_label(_("Do not translate the characters '~' and '#'"));
        isoopts[15] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(15));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,2,3);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[15]);
        gtk_widget_show(check);
        define_tooltip(check, _("Do not translate the characters '#' and '~' which are invalid for ISO9660 filenames but often used by Microsoft systems."));

        /* -max-iso9660-filenames */
        check = gtk_check_button_new_with_label(_("Allow 37 characters in ISO9660 filenames"));
        isoopts[19] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(19));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,3,4);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[19]);
        gtk_widget_show(check);
        define_tooltip(check, _("Allow 37 chars in ISO9660 filenames. This option will remove the ISO9660 version numbers to get the extra space. Use with extreme care."));

        /* -relaxed-filenames */
        check = gtk_check_button_new_with_label(_("Relaxed ISO9660 filenames"));
        isoopts[20] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(20));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,4,5);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[20]);
        gtk_widget_show(check);
        define_tooltip(check, _("Allow ISO9660 filenames to include digits, uppercase characters and all other 7 bit ASCII characters. This violates the ISO9660 standard, but it happens to work on many systems. Use with caution."));

        /* -dvd-video */
        check = gtk_check_button_new_with_label(_("Generate DVD-Video compliant UDF file system"));
        isoopts[21] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(21));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,5,6);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[21]);
        gtk_widget_show(check);
        define_tooltip(check, _("Generate DVD-Video compliant UDF file system. This is done by sorting the order of the content of the appropriate files and by adding padding between the files if needed."));

        /* -d omit trailing period */
        check = gtk_check_button_new_with_label(_("Omit trailing periods"));
        isoopts[8] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(8));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,6,7);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[8]);
        gtk_widget_show(check);
        define_tooltip(check, _("Omit trailing period from files that do not have a period. This violates the ISO9660 standard but has no effect on Rock Ridge or Joliet filenames."));

        /* -N omit version numbers */
        check = gtk_check_button_new_with_label(_("Omit ISO9660 version numbers"));
        isoopts[9] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(9));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,7,8);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[9]);
        gtk_widget_show(check);
        define_tooltip(check, _("Omit version numbers from ISO9660 file names. May be necessary on some exotic systems. Use with caution."));

        /* -hide-rr-moved */
        check = gtk_check_button_new_with_label(_("Hide the RR_MOVED directory"));
        isoopts[12] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(12));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,8,9);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[12]);
        gtk_widget_show(check);
        define_tooltip(check, _("Rename the automatically generated directory \"RR_MOVED\" to \".rr_moved\" in Rock Ridge images."));

        /* -no-rr */
        check = gtk_check_button_new_with_label(_("Do not use RR attributes from old sessions"));
        isoopts[14] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(14));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,9,10);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[14]);
        gtk_widget_show(check);
        define_tooltip(check, _("Do not use the Rock Ridge attributes from previous sessions. This may help to avoid getting into trouble when mkisofs finds illegal Rock Ridge signatures on an old session."));

	/* verbose executution */
        check = gtk_check_button_new_with_label(_("Verbose mkisofs execution"));
        isoopts[22] = check;
        g_signal_connect(check,"clicked",
                G_CALLBACK(isooptions_selected),GINT_TO_POINTER(22));
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,10,11);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[22]);
        gtk_widget_show(check);
        define_tooltip(check, _("Generate more output when generating the ISO9660 image. This is helpful to debug any problems that might occur."));

	/* allow to set iso-level */
        check = gtk_check_button_new_with_label(_("Set ISO9660 conformance level:"));
        isoopts[23] = check;
        gtk_table_attach_defaults(GTK_TABLE(tbl),check,0,16,11,12);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
                masterparam.opt[23]);
        gtk_widget_show(check);
        define_tooltip(check, _("Force the restrictions of the ISO9660 conformance levels. Only required for very special uses like CDs for MP3-Players."));

        f1 = gtk_frame_new(NULL);
        gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
        gtk_container_border_width(GTK_CONTAINER(f1),3);
        gtk_table_attach_defaults(GTK_TABLE(tbl),f1,4,7,12,13);
        gtk_widget_show(f1);

        l1 = gtk_label_new("");
        isolevel_label = l1;
        gtk_container_add(GTK_CONTAINER(f1),l1);
        gtk_widget_show(l1);

        adj1 = gtk_adjustment_new(0.0,1.0,4.0,1.0,1.0,1.0);
        g_signal_connect((adj1), "value_changed",
                G_CALLBACK(isolevel_changed), l1);
        scale = gtk_hscale_new(GTK_ADJUSTMENT (adj1));
        isolevel_scale = scale;
        gtk_scale_set_value_pos (GTK_SCALE(scale), GTK_POS_LEFT);
        gtk_scale_set_digits(GTK_SCALE(scale),0);
        gtk_scale_set_draw_value(GTK_SCALE(scale),FALSE);
        gtk_table_attach_defaults(GTK_TABLE(tbl),scale,7,15,12,13);
	gtk_adjustment_set_value(GTK_ADJUSTMENT(adj1),(gfloat)masterparam.opt[23]);
	gtk_widget_show(scale);	
        
        g_signal_connect(check,"clicked",
                G_CALLBACK(isolevel_selected),NULL);
	isolevel_selected(check, NULL);


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

	button1 = gtk_button_new_with_label(T_CLOSE);
	readtrack_button = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(advoptions_close), GINT_TO_POINTER(-1));
	gtk_widget_show(button1);

	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


/*
 * save output of write process
 */
static void show_writetrack_save_press(GtkWidget *widget, gpointer data) {
char tmp[MAXLINE];

	/* show fileselector */
	show_file_selector(_("Save Output"), MODE_SAVE, SAVEOUTCDRECORD,tmp);
	
	/* not cancel pressed? */
	if (strcmp(tmp,"") != 0) {
		if (save_text2file(tmp, readtrack_textview) == 0) {
			show_dialog(ICO_INFO,_("Saving output successful"), T_OK, NULL, NULL, 0);
		}
	}
}


/*
 * called by cancel-button in write-window
 */
static void write_cancel(GtkWidget *widget, gpointer data) {

	if (dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
		return;
	}

	/*
	 * no more to do here because the actual killing
	 * is handled in start_write_action()
	 */
	dialog_delete_event(widget, NULL, data);
}

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

	write_cancel(widget,data);
        return(TRUE);
}


/*
 * draw the write tracks pop-up window
 * if onthefly is set to 0 then call cdrecord to write some tracks
 * if onthefly is set to 1 then call cdrecord to write a disc on the fly
 * if onthefly is set to 2 then call cdrecord to fixate a disc
 * if onthefly is set to 3 then call cdrecord to write a master-image on the fly
 */
gint show_and_do_write_tracks(gint devnr, gint read_devnr, gint onthefly) {
GtkWidget *omenu;
GtkWidget *dialog;
GtkWidget *l1;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1, *tbl, *spdlabel;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win;
GtkAdjustment *adj1, *adj2, *adj3, *adj4;
GtkWidget *pbar1, *pbar2, *pbar3, *pbar4;
gint i, menuidx, menuhistory;
static const gchar *viewmodes[] = VIEW_MODES;
PangoFontDescription *font;

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

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

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (write_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);

	f1 = gtk_frame_new(NULL);
	readtrack_info_frame = f1;
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_widget_set_size_request(f1, -1, 36);
	gtk_box_pack_start(GTK_BOX(box1),f1,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(f1);

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

	tbl = gtk_table_new(4, 20, TRUE);
	readtrack_info_tbl = tbl;
	gtk_table_set_col_spacing(GTK_TABLE(tbl),4,5);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),16,5);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Track:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,5,0,1);
	gtk_widget_show(l1);

	adj1 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar1 = gtk_progress_bar_new_with_adjustment(adj1);
	readtrack_pbar1 = pbar1;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar1),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar1),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar1,5,20,0,1);
	gtk_widget_show(pbar1);

	l1 = rightjust_gtk_label_new(_("Total:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,5,1,2);
	gtk_widget_show(l1);

	adj2 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar2 = gtk_progress_bar_new_with_adjustment(adj2);
	readtrack_pbar2 = pbar2;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar2),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar2),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar2,5,20,1,2);
	gtk_widget_show(pbar2);

	l1 = rightjust_gtk_label_new(_("Fifo:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,5,2,3);
	gtk_widget_show(l1);

	adj3 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar3 = gtk_progress_bar_new_with_adjustment(adj3);
	readtrack_pbar3 = pbar3;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar3),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar3),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar3,5,20,2,3);
	gtk_widget_show(pbar3);

	l1 = rightjust_gtk_label_new(_("Writer-Buffer:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,5,3,4);
	gtk_widget_show(l1);

	adj4 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar4 = gtk_progress_bar_new_with_adjustment(adj4);
	readtrack_pbar4 = pbar4;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar4),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar4),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar4,5,11,3,4);
	gtk_widget_show(pbar4);

	l1 = rightjust_gtk_label_new(_("Speed:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,11,17,3,4);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_container_border_width(GTK_CONTAINER(f1),0);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,17,20,3,4);
	gtk_widget_show(f1);

	spdlabel = gtk_label_new("");
	readtrack_spd = spdlabel;
	gtk_container_add(GTK_CONTAINER(f1),spdlabel);
	gtk_widget_show(spdlabel);


	tbl = gtk_table_new(1, 10, TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),6,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	lbl = gtk_label_new("");
	readtrack_small_info = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,3,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	lbl = gtk_label_new("");
	readtrack_small_info2 = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,3,5,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	l1 = rightjust_gtk_label_new(_("View:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,5,7,0,1);
	gtk_widget_show(l1);

	omenu = gtk_combo_box_text_new();
	menuidx = 0; menuhistory = -1;

	for (i=0; i<3; i++) {
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(omenu), _(viewmodes[i]));
		if (curset.proc_view == i) { menuhistory = menuidx; }
		menuidx++;
	}

	if (menuhistory != -1) {
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), menuhistory);
	} else {
		curset.proc_view = 1;
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), 1);
	}

	g_signal_connect(omenu, "changed", G_CALLBACK(viewmode_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,7,10,0,1);
	gtk_widget_show(omenu);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	viewmode_scrolled = scrolled_win;
	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);

	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	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_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(write_cancel), GINT_TO_POINTER(-1));

	button2 = gtk_button_new_with_label(_("Save Output"));
	readtrack_savebutton = button2;
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(show_writetrack_save_press), GINT_TO_POINTER(-1));
	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(button2);


	/* grab cursor */
        gtk_grab_add(dialog);

	if (!set_win_geometry(GTK_WIDGET(dialog)))
		my_center_dialog(dialog);

	gtk_widget_show(dialog);

	/*
	 * Here is the action:
	 * Call cdrecord to:
	 */
	if (onthefly == 0) {
		start_write_action(devnr); 
	} else
	if (onthefly == 1) {
		start_write_onthefly_action(read_devnr, devnr);
	} else
	if (onthefly == 2) {
		start_write_fixate_only(devnr);
	} else {
		start_onthefly_master_action(devnr);
	}

	/* when done with reading rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);


	dobeep(1);
	
	/* now wait until button is pressed */
	gtk_main();

	store_win_geometry(GTK_WIDGET(dialog));
	set_xcdr_title(dialog, toplevel, -1);

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * called by cancel-button in delete-window
 */
static void delete_cancel(GtkWidget *widget, gpointer data) {

	if (dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
		return;
	}

	/* delete running? */
	if (read_done == 999) {
		/* abort */
		kill_readcdda();
	} else {
		dialog_delete_event(widget, NULL, data);
	}
}

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

	write_cancel(widget,data);
        return(TRUE);
}


/*
 * display a menu and do delete tracks
 */
gint show_and_do_delete(GList *delfiles) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *box1,*box2;
GtkWidget *f1;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win, *txt;
GtkAdjustment *adj1;
GtkWidget *pbar1;
PangoFontDescription *font;


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

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

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (delete_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);
	gtk_widget_show(box1);

	f1 = gtk_frame_new(NULL);
	readtrack_info_frame = f1;
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_widget_set_size_request(f1, -1, 36);
	gtk_box_pack_start(GTK_BOX(box1),f1,FALSE,TRUE,5);
	gtk_widget_show(f1);

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

	adj1 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar1 = gtk_progress_bar_new_with_adjustment(adj1);
	readtrack_pbar1 = pbar1;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar1),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar1),TRUE);
	gtk_box_pack_start(GTK_BOX(box1),pbar1,FALSE,TRUE,5);
	gtk_widget_show(pbar1);

	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_container_add(GTK_CONTAINER(box1),scrolled_win);
	gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);
	
	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_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(delete_cancel), GINT_TO_POINTER(-1));

	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	/* here is the action */
	start_delete_action(delfiles);

	/* when done with delete rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);
	
	/* now wait until button is pressed */
	gtk_main();

	set_xcdr_title(dialog, toplevel, -1);

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * start the read-processes according to the trackreadset-struct.
 * Update verify-dialogbox and return 0 if ok, 1 on error
 */
static gint start_verify_action(gint read_devnr) {
GList *loop;
track_read_param_t *trackparam;
gfloat percent_done;
gint stat, count;
gint errcount;

	if (strcmp(trackreadset.tocfile,"") != 0) {
		dolog(1, "Verify Disc with toc file %s\n", trackreadset.tocfile);
        } else {
                dolog(1, "Verifying single tracks\n");
        }
	percent_done = 0;
	count = 0;
	errcount = 0;

	/* start verifying all tracks */
	loop = g_list_first(trackreadset.trackparams);
	while (loop) {
		trackparam = loop->data;

		/* data-track */
		if (trackparam->tracktype == 0) {
			count++;	
			stat = verify_data_track(read_devnr,
				trackparam->starttrack,
				trackparam->kbyte,
				trackparam->trackfile,
				trackparam->startoffset,	
				trackparam->endoffset,
				trackreadset.nrtracks,				
				trackparam->percent,
				percent_done, count);
			percent_done += trackparam->percent;
		} else {
		/* audio-track */
			if (curset.noaudioverify == 0) {
				count++;	
				stat = verify_audio_track(read_devnr,
					trackparam->starttrack,
					trackparam->endtrack,
					trackparam->kbyte,
					trackparam->trackfile,
					trackparam->startoffset,
					trackparam->endoffset,
					trackreadset.nrtracks,	
					trackparam->percent,
					percent_done, count);
				percent_done += trackparam->percent;
			} else {
				/* we don't want to verify audio */
				stat = 0;
			}
		}
		if (stat == 2) {
			/* user abort */
			return 1;
		}
		if (stat != 0) {
			/* error while reading */
			if (curset.verifyfailabort == 1)
				return 1;
			errcount++;
		}
		loop = loop->next;
	}

	/* if we only got a single error we failed */
	if (errcount > 0) {
		return 1;
	}
	/* no error verifying tracks */
	gtk_label_set_text(GTK_LABEL(readtrack_info_label), _("Tracks successfully verified"));
	gtk_label_set_text(GTK_LABEL(readtrack_small_info), _("Successful:"));

	/* now set progressbars to 100% - elsewhere we may end up
	   with 99% due rounding errors */
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar1),1.0);
	gtk_progress_set_percentage(GTK_PROGRESS(readtrack_pbar2),1.0);
	set_xcdr_title(toplevel,viewmode_dialog,100);

	return 0;
}


/*
 * called from cancel or ok button
 */
static void show_verifytrack_btn_press(GtkWidget *widget, gpointer data) {

	if (GPOINTER_TO_INT(data) == -1 && dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
		return;
	}

	/* read-process running? */
	if (read_done == 999) {
		/* mark aborted */
		read_abort_mark = 1;
		/* abort our read-process */
		kill_readcdda();
		return;
	}

	/* cancel event */
	if (GPOINTER_TO_INT(data) == -1) {
		dialog_delete_event(widget, NULL, data);
		return;
	}
}


static void show_verifytrack_save_press(GtkWidget *widget, gpointer data) {
char tmp[MAXLINE];

	/* show fileselector */
	show_file_selector(_("Save Output"), MODE_SAVE, SAVEVERIFYTRACKS,tmp);
	
	/* not cancel pressed? */
	if (strcmp(tmp,"") != 0) {
		if (save_text2file(tmp, readtrack_textview) == 0) {
			show_dialog(ICO_INFO,_("Saving output successful"), T_OK, NULL, NULL, 0);
		}
	}
}

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

	if (dialog_disallow_delete) {
		dialog_delete_pressed = TRUE;
		return (TRUE);
	}

	/* read-process running? */
	if (read_done == 999) {
		/* mark aborted */
		read_abort_mark = 1;
		/* abort our read-process */
		kill_readcdda();
		return(TRUE);
	}

	dialog_delete_event(widget, event, data);
        return(TRUE);
}


/*
 * pop-up a modal window, trigger read tracks 
 * and return 0 if all ok, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
gint show_and_do_verify_tracks(gint devnr) {
GtkWidget *omenu;
GtkWidget *dialog;
GtkWidget *l1;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1, *tbl;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win;
GtkAdjustment *adj1, *adj2;
GtkWidget *pbar1, *pbar2;
gint i, menuidx, menuhistory;
static const gchar *viewmodes[] = VIEW_MODES;
PangoFontDescription *font;

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

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

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (verifytrack_dialog_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);

	f1 = gtk_frame_new(NULL);
	readtrack_info_frame = f1;
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_widget_set_size_request(f1, -1, 36);
	gtk_box_pack_start(GTK_BOX(box1),f1,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(f1);

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

	tbl = gtk_table_new(2, 10, TRUE);
	readtrack_info_tbl = tbl;
	gtk_table_set_col_spacing(GTK_TABLE(tbl),1,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Track:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	adj1 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar1 = gtk_progress_bar_new_with_adjustment(adj1);
	readtrack_pbar1 = pbar1;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar1),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar1),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar1,2,10,0,1);
	gtk_widget_show(pbar1);

	l1 = rightjust_gtk_label_new(_("Total:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,1,2);
	gtk_widget_show(l1);

	adj2 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar2 = gtk_progress_bar_new_with_adjustment(adj2);
	readtrack_pbar2 = pbar2;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar2),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar2),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar2,2,10,1,2);
	gtk_widget_show(pbar2);

	tbl = gtk_table_new(1, 10, TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),6,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	lbl = gtk_label_new("");
	readtrack_small_info = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,3,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	lbl = gtk_label_new("");
	readtrack_small_info2 = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,3,5,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	l1 = rightjust_gtk_label_new(_("View:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,5,7,0,1);
	gtk_widget_show(l1);

	omenu = gtk_combo_box_text_new();
	menuidx = 0; menuhistory = -1;

	for (i=0; i<3; i++) {
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(omenu), _(viewmodes[i]));
		if (curset.proc_view == i) { menuhistory = menuidx; }
		menuidx++;
	}

	if (menuhistory != -1) {
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), menuhistory);
	} else {
		curset.proc_view = 1;
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), 1);
	}

	g_signal_connect(omenu, "changed", G_CALLBACK(viewmode_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,7,10,0,1);
	gtk_widget_show(omenu);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	viewmode_scrolled = scrolled_win;
	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);

	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	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_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(show_verifytrack_btn_press), GINT_TO_POINTER(-1));

	button2 = gtk_button_new_with_label(_("Save Output"));
	readtrack_savebutton = button2;
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(show_verifytrack_save_press), GINT_TO_POINTER(-1));
	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(button2);


	/* grab cursor */
        gtk_grab_add(dialog);

	if (!set_win_geometry(GTK_WIDGET(dialog)))
		my_center_dialog(dialog);

	gtk_widget_show(dialog);

	/* here is the action */
	start_verify_action(devnr);

	/* when done with reading rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);

	dobeep(1);
	
	/* now wait until button is pressed */
	gtk_main();

	store_win_geometry(GTK_WIDGET(dialog));
	set_xcdr_title(dialog, toplevel, -1);

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * called by buttons in dsptest-window
 */
static void dsptest_start(GtkWidget *widget, gpointer data) {

	test_dspdevice_play();
}

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

	dialog_delete_event(widget, NULL, data);
}

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

	dsptest_cancel(widget,data);
        return(TRUE);
}

/*
 * pop-up a modal window, return 0 if correct
 * data was received from cddb-server, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void show_setup_dsptest() {
GtkWidget *dialog;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*box3,*txt;
GtkWidget *f1;
gchar tmp[MAXLINE];
PangoFontDescription *font;


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

	misc_timer = 0;

	/* 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_size_request(dialog, tbf(470), tbf(160)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dsptest_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Test Audio-Device"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);


        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	blank_text_window = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
	gtk_box_pack_start(GTK_BOX(box2),txt,TRUE,TRUE,0);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	gtk_widget_show(box1);

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

	button1 = gtk_button_new_with_label(_("Play demo sample"));
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dsptest_start), NULL);

	button2 = gtk_button_new_with_label(T_CLOSE);
	readtrack_button = button2;
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dsptest_cancel), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);

	/* now fill text-widget with infos */
	strncpy(tmp,_("Here you can test if X-CD-Roast is able to access your sound\nhardware to play audio tracks in CD quality.\nWhen you press the \"Play demo sample\" button, you should be\nable to hear a chime from your soundcard. Otherwise your\nAudio-Device is either not supported, or turned off or busy by\nanother program."),MAXLINE);

	append_to_text_view(txt, tmp);

	gtk_widget_show(dialog);

	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

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


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

	dialog_btn_press(widget, GINT_TO_POINTER(0));
}

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

	dialog_delete_event(widget, NULL, data);
}

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

	redirect_cancel(widget,data);
        return(TRUE);
}


/*
 * pop-up a modal window, return 0 if correct
 * data was entered, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
gint show_request_redirect_path(gchar *path, gchar *ret) {
GtkWidget *dialog;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1, *l1, *entry;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];

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

	/* 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_size_request(dialog, tbf(420), -1); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (redirect_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Redirect a master directory"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,5);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	l1 = gtk_label_new(_("Please specify where this path in the source data\nshould be redirected to on the destination Disc:"));
	gtk_box_pack_start(GTK_BOX(box2),l1,FALSE,FALSE,0);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);

	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_box_pack_start(GTK_BOX(box2),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	strncpy(tmp2, path, MAXLINE);
	convert_for_gtk2(tmp2);
	l1 = gtk_label_new(tmp2);
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);	

	l1 = gtk_label_new("=>");
	gtk_box_pack_start(GTK_BOX(box2),l1,FALSE,FALSE,0);
	gtk_widget_show(l1);	
	
	entry = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(entry), MAXENTRY);
	gtk_box_pack_start(GTK_BOX(box2),entry,FALSE,FALSE,5);
	gtk_widget_show(entry);

	strncpy(tmp2, ret, MAXLINE);
	convert_for_gtk2(tmp2);
	gtk_entry_set_text(GTK_ENTRY(entry), tmp2);

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

	button1 = gtk_button_new_with_label(T_OK);
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(redirect_ok), NULL);

	button2 = gtk_button_new_with_label(T_CANCEL);
	readtrack_button = button2;
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(redirect_cancel), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

	/* ok pressed? */
	if (dialog_get_value() == 0) {
		strncpy(tmp, gtk_entry_get_text(GTK_ENTRY(entry)), MAXLINE);
		strip_string(tmp);
		convert_for_gtk2_filename(tmp);

		/* if our master-path is a directory, add a slash to 
		   the redirection */
		if (is_directory(path) && strlen(tmp) > 0) {
			if (tmp[strlen(tmp)-1] != '/') {
				strcat(tmp,"/");
			}	
		}

		strcpy(ret, tmp);
	} else {
		/* aborted */
		strcpy(ret,"");
	}

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * pop-up a modal window, return 0 if correct
 * data was entered, -1 if not or 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
gint show_request_redirect_path_multiple(gchar *commonstr, gint nrpaths, gchar *ret) {
GtkWidget *dialog;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1, *l1, *entry;
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];


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

	/* 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_size_request(dialog, tbf(420), -1); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (redirect_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("Redirect several master directories"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,5);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	l1 = gtk_label_new(_("Please choose to which directory on the destination\nDisc the selected paths should be redirected to:"));
	gtk_box_pack_start(GTK_BOX(box2),l1,FALSE,FALSE,0);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);

	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_box_pack_start(GTK_BOX(box2),f1,FALSE,FALSE,5);
	gtk_widget_show(f1);

	strncpy(tmp2, commonstr, MAXLINE);
	convert_for_gtk2(tmp2);
	g_snprintf(tmp,MAXLINE,_("%s/... (%d paths)"), tmp2, nrpaths);
	l1 = gtk_label_new(tmp);
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_misc_set_alignment(GTK_MISC(l1),0.5,0.5);
	gtk_misc_set_padding(GTK_MISC(l1),5,5);
	gtk_widget_show(l1);	

	l1 = gtk_label_new("=>");
	gtk_box_pack_start(GTK_BOX(box2),l1,FALSE,FALSE,0);
	gtk_widget_show(l1);	
	
	entry = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(entry), MAXENTRY);
	gtk_box_pack_start(GTK_BOX(box2),entry,FALSE,FALSE,5);
	gtk_widget_show(entry);
	gtk_entry_set_text(GTK_ENTRY(entry), "/");

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

	button1 = gtk_button_new_with_label(T_OK);
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(redirect_ok), NULL);

	button2 = gtk_button_new_with_label(T_CANCEL);
	readtrack_button = button2;
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(redirect_cancel), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	gtk_main();

	/* ok pressed? */
	if (dialog_get_value() == 0) {
		strncpy(tmp, gtk_entry_get_text(GTK_ENTRY(entry)), MAXLINE);
		strip_string(tmp);
		convert_for_gtk2_filename(tmp);

		/* if our master-path is a directory, add a slash to 
		   the redirection */
		if (strlen(tmp) > 0) {
			if (tmp[strlen(tmp)-1] != '/') {
				strcat(tmp,"/");
			}	
		}

		strcpy(ret, tmp);
	} else {
		/* aborted */
		strcpy(ret,"");
	}

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}

static void show_mstrcalc_save_press(GtkWidget *widget, gpointer data) {
char tmp[MAXLINE];

	/* show fileselector */
	show_file_selector(_("Save Output"), MODE_SAVE, SAVEMASTERCALC,tmp);
	
	/* not cancel pressed? */
	if (strcmp(tmp,"") != 0) {
		if (save_text2file(tmp, readtrack_textview) == 0) {
			show_dialog(ICO_INFO,_("Saving output successful"), T_OK, NULL, NULL, 0);
		}
	}
}

/*
 * pop-up a modal window, return path or NULL-string 
 * when cancel or delete_event found.
 * it centers automatically above the toplevel window 
 */
void show_mkisofs_check_output(gint automode, gint *timeout) {
GtkWidget *dialog;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1;
GtkWidget *scrolled_win;
gchar tmp[MAXLINE];
PangoFontDescription *font;


	dodebug(8, "displaying show_mkisofs_check_output (automode = %d)\n", automode);


	/* 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_size_request(dialog, tbf(500), tbf(300)); 
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_delete_event), (gpointer) dialog);

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

	f1 = gtk_frame_new(_("ISO9660-filesystem build informations/warnings"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	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_container_add(GTK_CONTAINER(f1),scrolled_win);
	gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);
	
	gtk_widget_show(box1);

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

	button1 = gtk_button_new_with_label(T_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(readtrack_button,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));

        button2 = gtk_button_new_with_label(_("Save Output"));
        readtrack_savebutton = button2;
        gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
        GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
        g_signal_connect(button2,"clicked",
                G_CALLBACK(show_mstrcalc_save_press), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);

	/* show only when not in automatic mode */
	if (automode == 0) 
		gtk_widget_show(dialog);

	/* now fill text-widget with infos */
	fill_mkisofs_check_info(txt);

	/* when done with reading rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);

	/* getting size failed in auto mode */
	if (automode && masterparam.session_size == 0) {

		/* hide timeoutwindow if it was present */
		if (mkisofs_calc_timeout_dialog) {
			gtk_widget_hide(mkisofs_calc_timeout_dialog);
		}
                /* remove the timeout, if it did not kick in yet */
	        if (*timeout) {
                	g_source_remove(*timeout);
			*timeout = 0;
        	}

		/* display dialog now to show the problem */
		gtk_widget_show(dialog);

		/* scroll to last line */
		g_snprintf(tmp,MAXLINE,"\n%s\n", _("-> mkisofs reported an error while calculating the session size!"));

		append_to_text_view_color(txt, tmp, "red");
	}

	/* getting size successful in auto mode? */
	if (automode && masterparam.session_size > 0) {
		/* trigger not to wait for a button */
		;
	} else {
		/* or wait until button is pressed */
		gtk_main();
	}

        gtk_grab_remove(GTK_WIDGET(dialog));

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


static void show_master_save_press(GtkWidget *widget, gpointer data) {
char tmp[MAXLINE];

	/* show fileselector */
	show_file_selector(_("Save Output"), MODE_SAVE, SAVEMASTERTRACK,tmp);
	
	/* not cancel pressed? */
	if (strcmp(tmp,"") != 0) {
		if (save_text2file(tmp, readtrack_textview) == 0) {
			show_dialog(ICO_INFO,_("Saving output successful"), T_OK, NULL, NULL, 0);
		}
	}
}


/*
 * pop-up a modal window and start to master a image to the harddisk
 */
gint show_and_start_master() {
GtkWidget *omenu;
GtkWidget *dialog;
GtkWidget *l1;
GtkWidget *button1, *button2;
GtkWidget *box1,*box2,*txt;
GtkWidget *f1, *tbl;
GtkWidget *b1_sep, *lbl;
GtkWidget *scrolled_win;
GtkAdjustment *adj1;
GtkWidget *pbar1;
gint i, menuidx, menuhistory;
static const gchar *viewmodes[] = VIEW_MODES;
PangoFontDescription *font;

	dodebug(8, "displaying show_and_start_master\n");
	
	/* create new window and position it relative to the main window */
	dialog = my_gtk_dialog_new();
	viewmode_dialog = dialog;
	set_xcdr_title(dialog, toplevel, 0);
	gtk_widget_set_size_request(dialog, tbf(500), -1);
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (readtrack_dialog_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);

	f1 = gtk_frame_new(NULL);
	readtrack_info_frame = f1;
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_IN);
	gtk_widget_set_size_request(f1, -1, 36);
	gtk_box_pack_start(GTK_BOX(box1),f1,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(f1);

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

	tbl = gtk_table_new(1, 10, TRUE);
	readtrack_info_tbl = tbl;
	gtk_table_set_col_spacing(GTK_TABLE(tbl),1,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,5);
	if (curset.proc_view > 0) 
		gtk_widget_show(tbl);

	l1 = rightjust_gtk_label_new(_("Track:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,0,2,0,1);
	gtk_widget_show(l1);

	adj1 = (GtkAdjustment *)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
	pbar1 = gtk_progress_bar_new_with_adjustment(adj1);
	readtrack_pbar1 = pbar1;
	gtk_progress_set_format_string(GTK_PROGRESS(pbar1),"%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(pbar1),TRUE);
	gtk_table_attach_defaults(GTK_TABLE(tbl),pbar1,2,10,0,1);
	gtk_widget_show(pbar1);

	tbl = gtk_table_new(1, 10, TRUE);
	gtk_table_set_col_spacing(GTK_TABLE(tbl),6,10);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box1),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	lbl = gtk_label_new("");
	readtrack_small_info = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,3,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	lbl = gtk_label_new("");
	readtrack_small_info2 = lbl;
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,3,5,0,1);
	if (curset.proc_view == 0) 
		gtk_widget_show(lbl);

	l1 = rightjust_gtk_label_new(_("View:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),l1,5,7,0,1);
	gtk_widget_show(l1);

	omenu = gtk_combo_box_text_new();
	menuidx = 0; menuhistory = -1;

	for (i=0; i<3; i++) {
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(omenu), _(viewmodes[i]));
		if (curset.proc_view == i) { menuhistory = menuidx; }
		menuidx++;
	}

	if (menuhistory != -1) {
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), menuhistory);
	} else {
		curset.proc_view = 1;
		gtk_combo_box_set_active(GTK_COMBO_BOX(omenu), 1);
	}
	g_signal_connect(omenu, "changed", G_CALLBACK(viewmode_selected), NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),omenu,7,10,0,1);
	gtk_widget_show(omenu);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	viewmode_scrolled = scrolled_win;
	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);

	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(scrolled_win);

        font = pango_font_description_from_string(PANGO_MONOSPACE);

        txt = gtk_text_view_new();
	readtrack_textview = txt;
        gtk_text_view_set_editable(GTK_TEXT_VIEW(txt), FALSE);
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt), GTK_WRAP_WORD);
        gtk_container_add(GTK_CONTAINER(scrolled_win), txt);
	gtk_widget_set_size_request(txt, -1, tbf(150));
        gtk_widget_modify_font(txt, font);
        gtk_widget_show(txt);

	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_CANCEL);
	readtrack_button = 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_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(show_readtrack_btn_press), GINT_TO_POINTER(-1));

	button2 = gtk_button_new_with_label(_("Save Output"));
	readtrack_savebutton = button2;
	gtk_box_pack_start(GTK_BOX(box2),button2,TRUE,TRUE,10);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(show_master_save_press), GINT_TO_POINTER(-1));

	/* show only in extended view */
	if (curset.proc_view == 2) 
		gtk_widget_show(button2);

	/* grab cursor */
        gtk_grab_add(dialog);

	/* only center window when toplevel visible */
	if (!set_win_geometry(GTK_WIDGET(dialog)))
		my_center_dialog(dialog);

	gtk_widget_show(dialog);

	/* here is the action */
	start_master_action();

	/* update image-dir-lists */
	scan_imagedirs();

	/* when done with reading rename button to OK */
	gtk_label_set_text(GTK_LABEL(GTK_BIN(readtrack_button)->child),T_OK);
	
	dobeep(1);

	/* now wait until button is pressed */
	gtk_main();

	store_win_geometry(GTK_WIDGET(dialog));
	set_xcdr_title(dialog, toplevel, -1);

        gtk_grab_remove(GTK_WIDGET(dialog));

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

	return (dialog_get_value());
}


/*
 * called from radio buttons in redir menu
 */
static void redir_type_selected(GtkWidget *item, gpointer data) {

	masterparam.redirtype = GPOINTER_TO_INT(data); 

	if (!redir_entry) return;

	if (masterparam.redirtype != 3) {
		gtk_widget_set_sensitive(redir_entry, FALSE);
	} else {
		gtk_widget_set_sensitive(redir_entry, TRUE);
	}
}


/*
 * called from radio buttons in redir_multi menu
 */
static void redir_type_selected2(GtkWidget *item, gpointer data) {

	masterparam.redirtype2 = GPOINTER_TO_INT(data); 

	if (!redir_entry) return;

	if (masterparam.redirtype2 != 3) {
		gtk_widget_set_sensitive(redir_entry, FALSE);
	} else {
		gtk_widget_set_sensitive(redir_entry, TRUE);
	}
}


/*
 * pop-up a modal window, where the user can choose where
 * to add the new directory on the target disc. 
 * it centers automatically above the toplevel window 
 */
gint show_mstr_redir(gchar *dir, gchar *ret) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2, *entry;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1, *f2, *f3, *l1;
GtkWidget *b1_sep, *lbl, *btn;
GSList *group;
gchar redir[MAXLINE], redir2[MAXLINE], tmp2[MAXLINE];
gchar filename[MAXLINE];
gint is_dir;
gint bak_redirtype;
gchar *p;
gchar tmp[MAXLINE];

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

	bak_redirtype = masterparam.redirtype;
	redir_entry = NULL;

	/* 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_size_request(dialog, tbf(450), tbf(320));
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));
	cddb_window = dialog;

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_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);
	gtk_widget_show(box1);

	f1 = gtk_frame_new(_("Adding path to master directories"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	f2 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f2),GTK_SHADOW_IN);
	gtk_box_pack_start(GTK_BOX(box2),f2,FALSE,TRUE,5);
	gtk_widget_show(f2);

	strncpy(tmp2, dir, MAXLINE);
	convert_for_gtk2(tmp2);
	l1 = gtk_label_new(tmp2);
	gtk_container_add(GTK_CONTAINER(f2),l1);
	gtk_misc_set_alignment(GTK_MISC(l1),0.5,0.5);
	gtk_misc_set_padding(GTK_MISC(l1),5,5);
	gtk_widget_show(l1);

	/* handling a file or a directory here? */
	is_dir = is_directory(dir);

	if (is_dir) {
		strcpy(filename, "");
		lbl = gtk_label_new(_("Please choose where the contents of this directory\nshould be located on the Disc:"));
	} else {

		/* it's a file, so store its filename without path */
		get_purefile(dir, filename);
		lbl = gtk_label_new(_("Please choose where this file should be located on the Disc:"));
	}
	gtk_box_pack_start(GTK_BOX(box2),lbl,FALSE,TRUE,5);
	gtk_widget_show(lbl);

        b1_sep = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(box2),b1_sep,FALSE,TRUE,5);
	gtk_widget_show(b1_sep);

	btn = gtk_radio_button_new_with_label(NULL,_("Add to root directory of the Disc (\"/\")"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected),GINT_TO_POINTER(0));

	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	define_tooltip(btn,_("Will put this file or directory content in the root directory of the destination Disc. (Strips off its current path completely.)"));
	if (masterparam.redirtype == 0) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));

	strncpy(redir,dir,MAXLINE);
	get_basedir(redir);
	if (redir == NULL) { 
		strcpy(redir,"/"); 
	} else {
		/* look for last slash */
		p = rindex(redir,'/');
		if (p) {
			/* use only the part beginning from last slash */
			strncpy(tmp2, p, MAXLINE);
			strncpy(redir, tmp2, MAXLINE);
		} else {
			strcpy(redir,"/"); 
		}
	}

	strncpy(tmp2, redir, MAXLINE);
	convert_for_gtk2(tmp2);
	g_snprintf(tmp,MAXLINE,_("Add with last path component (\"%s\")"), tmp2);

	btn = gtk_radio_button_new_with_label(group,tmp);
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected),GINT_TO_POINTER(1));
	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	define_tooltip(btn,_("Will put this file or directory on the destination Disc while keeping its last part of the directory intact. (e.g. a directory /home/user will become /user on the Disc.)"));
	if (masterparam.redirtype == 1) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));

	strncpy(redir2,dir,MAXLINE);
	get_basedir(redir2);
	if (redir2 == NULL) { strcpy(redir2,"/"); }

	strncpy(tmp2, redir2, MAXLINE);
	convert_for_gtk2(tmp2);
	g_snprintf(tmp,MAXLINE,_("Add with full path (\"%s\")"), tmp2);

	btn = gtk_radio_button_new_with_label(group,tmp);
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected),GINT_TO_POINTER(2));
	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	define_tooltip(btn,_("Will put this file or directory in the same path on the destination Disc, as it is on the hard drive now. (e.g. a directory /home/user will also become /home/user on the Disc.)"));
	if (masterparam.redirtype == 2) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	
	btn = gtk_radio_button_new_with_label(group,_("Add with custom path:"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected),GINT_TO_POINTER(3));
	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	define_tooltip(btn,_("Lets you specify exactly where the file or directory content should be mapped to on the destination Disc. (e.g. a directory /home/user can be mapped to /backup/home-dirs/user.)"));
	if (masterparam.redirtype == 3) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);

	f3 = gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(box2),f3,FALSE,FALSE,5);
	gtk_widget_show(f3);

        entry = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(entry), MAXENTRY);
	redir_entry = entry;
	gtk_box_pack_start(GTK_BOX(f3),entry,TRUE,TRUE,20);
        gtk_widget_show(entry);
	gtk_entry_set_text(GTK_ENTRY(entry), masterparam.lastredirpath);
	if (masterparam.redirtype != 3) 
		gtk_widget_set_sensitive(redir_entry, FALSE);

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

	button1 = gtk_button_new_with_label(T_OK);
	cddb_info_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

	if (dialog_get_value() != 0) {
		/* restore original value of type */
		masterparam.redirtype = bak_redirtype;
		strcpy(redir,"");
	} else {
		/* ok pressed, do some business */
		g_free(masterparam.lastredirpath);
		strncpy(tmp, gtk_entry_get_text(GTK_ENTRY(redir_entry)), MAXLINE);
		convert_for_gtk2_filename(tmp);

		masterparam.lastredirpath = g_strdup(tmp);

		if (masterparam.redirtype == 0) {
			strcpy(redir,"/");
		}

		if (masterparam.redirtype == 2) {
			strcpy(redir,redir2);
		}

		if (masterparam.redirtype == 3) {
			strncpy(redir,masterparam.lastredirpath, MAXLINE);
		}
		strip_string(redir);

		/* because we handle only directories here, add a slash */
                if (strlen(redir) > 0) {
                        if (redir[strlen(redir)-1] != '/') {
                                strcat(redir,"/");
                        }       
                }
		
		/* and if we are adding a file, add its filename */
		if (strlen(redir) + strlen(filename) < MAXLINE) {
			strcat(redir, filename);
		}
	}

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

	/* now "redir" contains the string where we want to go */
	strncpy(ret, redir, MAXLINE);

	return (dialog_get_value());
}


/*
 * radio button to sync all cdtext artists
 */
static void cdtext_sync_artist(GtkWidget *item, gpointer data) {
gint i;
gchar *p;

	curset.sync_cdtext_artist = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item));

	i = 1;
	/* sync all */ 
	if (curset.sync_cdtext_artist == 1) {
		/* get artist of disc */
		p = (gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[0]));
		if (!p) return;
		while(cdtext_entry2[i]) {
			/* copy artist to all artists */
			gtk_entry_set_text(GTK_ENTRY(cdtext_entry2[i]), p);
			gtk_widget_set_sensitive(cdtext_entry2[i], FALSE);
			i++;
		}
	} else {
		/* no longer sync all */
		while(cdtext_entry2[i]) {
			gtk_widget_set_sensitive(cdtext_entry2[i], TRUE);
			i++;
		}
	}
}


/*
 * called when the cdtext artist of the disc is changed
 */
static void cdtext_artist_changed(GtkWidget *item, gpointer data) {
gint i;
gchar *p;

	i = 1;
	if (curset.sync_cdtext_artist == 1) {
		p = (gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[0]));
		if (!p) return;
		while(cdtext_entry2[i]) {
			/* copy current status to all fields */
			gtk_entry_set_text(GTK_ENTRY(cdtext_entry2[i]), p);
			i++;
		}
	}
}


/*
 * called by clear all button
 */
static void cdtext_clear_all(GtkWidget *item, gpointer data) {
gint i;

	i = 0;
	while(cdtext_entry1[i]) {
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry1[i]),"");
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry2[i]),"");
		i++;
	}
}


/*
 * set artist and disc title from cddb
 */
void cdtext_set_dtitle(gchar *dtitle) {
gchar title[MAXLINE];
gchar artist[MAXLINE];

	get_artist_and_title_from_cddb(dtitle, title, artist);
	if (cdtext_entry1[0])
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry1[0]),convert_for_gtk2(title));
	if (cdtext_entry2[0])
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry2[0]),convert_for_gtk2(artist));
}


/*
 * set track-title from cddb
 */
void cdtext_set_ttitle(gchar *ttitle, gint nr) {
gchar tmp[MAXLINE];
	
	strncpy(tmp, ttitle, MAXLINE);

	if (cdtext_entry1[nr])
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry1[nr]),convert_for_gtk2(tmp));
	if (cdtext_entry2[nr])
		gtk_entry_set_text(GTK_ENTRY(cdtext_entry2[nr]),"");

}


/*
 * called on ok button of cdtext editor (mode 0)
 * copies the entered cdtext data to memory structure
 */
static void cdtext_edit_ok_mode0() {
gint i;

	/* set cd-info first */
	g_free(cdinfo.title);
	cdinfo.title = g_strdup(gtk_entry_get_text(GTK_ENTRY(cdtext_entry1[0])));
	g_free(cdinfo.artist);
	cdinfo.artist = g_strdup(gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[0])));
	/* free cddb info now */
	if (cdinfo.cddb_dtitle) {
		g_free(cdinfo.cddb_dtitle);
		cdinfo.cddb_dtitle = NULL;
	}

	i = 1; 
	while(cdtext_entry2[i]) {
		/* copy the new entered data to my cd-text data */
		
		g_free(trackinfo[i-1]->title);
		trackinfo[i-1]->title = g_strdup(gtk_entry_get_text(GTK_ENTRY(cdtext_entry1[i])));
		g_free(trackinfo[i-1]->artist);
		trackinfo[i-1]->artist = g_strdup(gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[i])));

		/* free cddb info now */
		if (trackinfo[i-1]->cddb_ttitle) {
			g_free(trackinfo[i-1]->cddb_ttitle);
			trackinfo[i-1]->cddb_ttitle = NULL;
		}
		i++;
	}

	/* now the cd-text information is copied to the track-structure..*/
	/* force display of cd-text now */
	setupdata.option_displaycdtext = 1;

}


/*
 * called on ok button of cdtext editor (mode 1 and 2)
 * write the entered cd-text info to xinf-files and toc
 */
static void cdtext_edit_ok_mode12(gchar *tmptoc) {
gint i;
track_read_param_t *trackparam;
GList *loop;

	/* first edit the toc file */
	if (!tmptoc) {
		if (curset.tocfile && curset.tocfile[0] != '\0') {
			edit_title_artist_in_toc_file(curset.tocfile,
				(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry1[0])),
				(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[0])));
		}
	} else {
		/* use temporary toc file to edit */
		edit_title_artist_in_toc_file(tmptoc,
			(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry1[0])),
			(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[0])));
	}

	i = 1; 
	loop = g_list_first(trackreadset.trackparams);
	while(cdtext_entry2[i]) {
		if (!loop) {
			g_error("toc-file inconsistent....should never happen.\n");
		}
		trackparam = loop->data;
		edit_title_artist_in_xinf_file(trackparam->trackfile,
			(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry1[i])),
			(gchar *) gtk_entry_get_text(GTK_ENTRY(cdtext_entry2[i])));
		loop = loop->next;
		i++;
	}

}


/*
 * Lookup the titles on CDDB just via the toc file
 */
static void edit_cdtext_cddb(GtkWidget *widget, gpointer data) {
gint onthefly;

	if (strcmp(curset.tocfile,"-") == 0) {
		onthefly = 1;
	} else {
		onthefly = 0;
	}
	if (show_cddb_query(GTK_WIDGET(data), onthefly) == 0) {
		/* trigger artist sync */
		cdtext_artist_changed(NULL, NULL);
	}
}


/*
 * show the edit window for cd-text
 * mode = 0 when called from info-dialog, 
 * mode = 1 when called from duplicate write-dialog
 * mode = 2 when called from create write-dialog 
 * mode = 3 when called from duplicate write-dialog (on-the-fly) 
 */ 
gint show_edit_cdtext(gint mode, GtkWidget *writetoc_menu) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2, *button3;
GtkWidget *box1, *box2, *box3, *box4, *scrolled_window;
GtkWidget *f1, *l1, *tbl, *pic;
GtkWidget *lbl, *btn, *e1;
GtkWidget *menu, *menuitem;
gint i, canlookup;
gchar tmp[MAXLINE], tmp2[MAXLINE];
gchar tmptoc[MAXLINE];
gchar title[MAXLINE], artist[MAXLINE];
gint nrtracks, orgcdtextused;
GtkStyle *style;
GdkPixmap *pixmap1, *pixmap2, *pixmap3;
GdkBitmap *mask1, *mask2, *mask3;
gint bak_sync_cdtext_artist;
track_read_param_t *trackparam;
GList *loop;
image_files_t *entry;
GtkTooltips *tip;

	bak_sync_cdtext_artist = curset.sync_cdtext_artist;
	trackparam = NULL;
	loop = NULL;

	/* disc loaded? */
	if (mode == 0 || mode == 3) {
		nrtracks = cdinfo.nr_tracks;
		if (nrtracks < 0) {
			nrtracks = 0;
		}
	} else
	if (mode == 1 || mode == 2) {
		nrtracks = trackreadset.nrtracks;
		loop = g_list_first(trackreadset.trackparams);
	} else {
		return -1;
	}

	/* delete old entry-pointers */
	for (i = 0; i < MAXTRACKS+1; i++) {
		cdtext_entry1[i] = NULL;
		cdtext_entry2[i] = NULL;
	}

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

	/* 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_size_request(dialog, tbf(600), tbf(400));
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_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);
	gtk_widget_show(box1);

	f1 = gtk_frame_new(_("Edit CD-Text information"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	tbl = gtk_table_new(2, 10, TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),2);
	gtk_table_set_col_spacings(GTK_TABLE(tbl),5);
	gtk_box_pack_start(GTK_BOX(box2),tbl,FALSE,TRUE,0);
	gtk_widget_show(tbl);

	strcpy(title,"");
	strcpy(artist,"");

	/* called from info-screen, get info from cdinfo struct */
	if (mode == 0 || mode == 3) {

		/* get title and artist for the current cd */
		orgcdtextused = 0;
		if (setupdata.option_displaycdtext) {
			if (cdinfo.title && cdinfo.artist && cdinfo.title[0] != '\0') {
				strncpy(title, cdinfo.title, MAXLINE);
				strncpy(artist, cdinfo.artist, MAXLINE);
				orgcdtextused = 1;
			}
		}
		if (orgcdtextused == 0) {
			if (cdinfo.cddb_dtitle) {
				get_artist_and_title_from_cddb(cdinfo.cddb_dtitle,
				artist, title);
			} else {
				/* try cd-text as fallback */
				if (cdinfo.title && cdinfo.artist && 
				    cdinfo.title[0] != '\0') {
					strncpy(title, cdinfo.title, MAXLINE);
					strncpy(artist, cdinfo.artist, MAXLINE);
				}
			}
		}
	} else 
	/* read info from trackreadset (Duplicate-Write Disc menu) */
	if (mode == 1) {
		if (trackreadset.cdtitle && trackreadset.cdtitle[0]) {
			get_artist_and_title_from_cddb(trackreadset.cdtitle,
				 artist, title);
		}
	} else 
	/* read cdtitle from temporary toc file for the write-tracks menu */
	if (mode == 2) {
		generate_tmp_tocfile_name(tmptoc);
		get_cdtitle_from_tmp_tocfile(tmptoc, tmp);
		get_artist_and_title_from_cddb(tmp,
				 artist, title);
	}	

	lbl = gtk_label_new(_("Album title:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,2,0,1);
	gtk_widget_show(lbl);

	/* cd-title */
	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cdtext_entry1[0] = e1;
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,6,0,1);
	gtk_entry_set_text(GTK_ENTRY(e1), convert_for_gtk2(title));
	gtk_entry_set_position(GTK_ENTRY(e1), 0);
	if (nrtracks == 0) 
		gtk_widget_set_sensitive(e1, FALSE);
	gtk_widget_show(e1);

	btn = gtk_button_new_with_label(_("Clear all"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(cdtext_clear_all),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,7,10,0,1);
	gtk_widget_show(btn);	
	define_tooltip(btn,_("Clears all the CD-Text fields."));

	lbl = gtk_label_new(_("Performer:"));
	gtk_table_attach_defaults(GTK_TABLE(tbl),lbl,0,2,1,2);
	gtk_widget_show(lbl);


	/* cd-artist */
	e1 = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
	cdtext_entry2[0] = e1;
	gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,6,1,2);
	g_signal_connect(e1,"changed",
		G_CALLBACK(cdtext_artist_changed),NULL);
	gtk_entry_set_text(GTK_ENTRY(e1), convert_for_gtk2(artist));
	gtk_entry_set_position(GTK_ENTRY(e1), 0);
	if (nrtracks == 0) 
		gtk_widget_set_sensitive(e1, FALSE);
	gtk_widget_show(e1);

	btn = gtk_check_button_new_with_label(_("Use for all tracks"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(cdtext_sync_artist),NULL);
	gtk_table_attach_defaults(GTK_TABLE(tbl),btn,6,10,1,2);
	if (nrtracks == 0) 
		gtk_widget_set_sensitive(btn, FALSE);
	gtk_widget_show(btn);	
	define_tooltip(btn,_("Use the album performer also for all the tracks. This will copy the current album performer over all track performers."));

	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
     		                  GTK_POLICY_AUTOMATIC, 
                                  GTK_POLICY_AUTOMATIC);
        gtk_box_pack_start(GTK_BOX(box2),scrolled_window,TRUE,TRUE,5);
	gtk_widget_show(scrolled_window);

	box4 = gtk_vbox_new(FALSE,0);
	gtk_scrolled_window_add_with_viewport (
		GTK_SCROLLED_WINDOW (scrolled_window),box4);
	gtk_widget_show(box4);

	tbl = gtk_table_new(nrtracks+1, 21, TRUE);
	gtk_table_set_row_spacings(GTK_TABLE(tbl),2);
        gtk_box_pack_start(GTK_BOX(box4),tbl,FALSE,TRUE,0);
	gtk_widget_realize(tbl);
	gtk_widget_show(tbl);

        style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(tbl)));
        pixmap1 = gdk_pixmap_create_from_xpm_d(tbl->window,
                &mask1, &style->bg[GTK_STATE_NORMAL],(gchar **)minidata_xpm);
        pixmap2 = gdk_pixmap_create_from_xpm_d(tbl->window,
                &mask2, &style->bg[GTK_STATE_NORMAL],(gchar **)miniaudio_xpm);
	pixmap3 = gdk_pixmap_create_from_xpm_d(tbl->window,
		&mask3, &style->bg[GTK_STATE_NORMAL],(gchar **)mininodata_xpm);

	/* create title bar */
	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_OUT);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,0,1,0,1);
	gtk_widget_show(f1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_OUT);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,1,2,0,1);
	gtk_widget_show(f1);
	l1 = gtk_label_new(_("Nr."));
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_OUT);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,2,10,0,1);
	gtk_widget_show(f1);
	l1 = gtk_label_new(_("Track title"));
	gtk_misc_set_alignment(GTK_MISC(l1),0.0,0.5);
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_OUT);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,10,18,0,1);
	gtk_widget_show(f1);
	l1 = gtk_label_new(_("Performer"));
	gtk_misc_set_alignment(GTK_MISC(l1),0.0,0.5);
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);

	f1 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f1),GTK_SHADOW_OUT);
	gtk_table_attach_defaults(GTK_TABLE(tbl),f1,18,21,0,1);
	gtk_widget_show(f1);
	l1 = gtk_label_new(_("Length"));
	gtk_container_add(GTK_CONTAINER(f1),l1);
	gtk_widget_show(l1);

	/* fill track information */

	for (i = 0; i < nrtracks; i++) {
	   if (mode == 0 || mode == 3) {
                if (trackinfo[i]->type == 0) {
			pic = gtk_image_new_from_pixmap(pixmap1, mask1);
                        convert_frames2mbstring(trackinfo[i]->size,tmp2);
		} else {
			pic = gtk_image_new_from_pixmap(pixmap2, mask2);
                        convert_frames2minstring(trackinfo[i]->size,tmp2);
		}

		gtk_table_attach_defaults(GTK_TABLE(tbl),pic,0,1,i+1,i+2);
		gtk_widget_show(pic);
	
                g_snprintf(tmp,MAXLINE,"%2d.", trackinfo[i]->track_nr);
		l1 = gtk_label_new(tmp);
		gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,2,i+1,i+2);
		gtk_widget_show(l1);

		/* get strings to use for cd-text */
		strcpy(title,"");
		strcpy(artist,"");
		orgcdtextused = 0;
		if (setupdata.option_displaycdtext) {
			if (trackinfo[i]->title != NULL &&
			    trackinfo[i]->title[0] != '\0' ) {
				/* cd-text found.. use it */
				strncpy(title, trackinfo[i]->title, MAXLINE);
				orgcdtextused = 1;
			}
			if (trackinfo[i]->artist != NULL &&
			    trackinfo[i]->artist[0] != '\0' ) {
				strncpy(artist, trackinfo[i]->artist, MAXLINE); 
			}	
		}	

		/* no cd-text in use? try cddb */
		if (orgcdtextused == 0) {
			if (trackinfo[i]->cddb_ttitle != NULL) {
				/* use cddb-information */
				strncpy(title, trackinfo[i]->cddb_ttitle, 
					MAXLINE);
			} else {
				/* fall back to try cd-text again */
				if (trackinfo[i]->title != NULL &&
			   	    trackinfo[i]->title[0] != '\0' ) {
					strncpy(title, trackinfo[i]->title, MAXLINE);
				}	
				if (trackinfo[i]->artist != NULL &&
			   	    trackinfo[i]->artist[0] != '\0' ) {
					strncpy(artist, trackinfo[i]->artist, MAXLINE);
				}	
			}
		}
	   } else 

	   /* get info from trackparams list */
	   if (mode == 1) {
		if (!loop) {
			g_error("Toc file inconsistent....should never happen.\n");
		}
		trackparam = loop->data;
		if (!trackparam) {
			g_warning("trackparam pointer NULL?\n");
			loop = loop->next;
			continue;
		}
                if (trackparam->tracktype == 0) {
			pic = gtk_image_new_from_pixmap(pixmap1, mask1);
                        convert_frames2mbstring(trackparam->frames,tmp2);
		} else {
			pic = gtk_image_new_from_pixmap(pixmap2, mask2);
                        convert_frames2minstring(trackparam->frames,tmp2);
		}

		gtk_table_attach_defaults(GTK_TABLE(tbl),pic,0,1,i+1,i+2);
		gtk_widget_show(pic);
	
                g_snprintf(tmp,MAXLINE,"%2d.", trackparam->starttrack);
		l1 = gtk_label_new(tmp);
		gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,2,i+1,i+2);
		gtk_widget_show(l1);

		/* get title and artist from xinf file */
		strcpy(title,"");
		strcpy(artist,"");
		if (trackparam->trackfile) {
			get_title_artist_from_xinf(trackparam->trackfile,
				artist, title);
		}
		loop = loop->next;
	   } else 

	   /* from write tracks menu in create disc */
	   if (mode == 2) {
		if (!loop) {
			g_error("trackreadset inconsistent....should never happen.\n");
		}
		trackparam = loop->data;

                entry = get_entry_from_imagelist(trackparam->trackfile);
                if (entry == NULL) {
                        /* should never happen */
                        loop = loop->next;
                        continue;
                }

                if (trackparam->tracktype == 0) {
			if (entry->type == 0) {
				pic = gtk_image_new_from_pixmap(pixmap1, mask1);
			} else {
				pic = gtk_image_new_from_pixmap(pixmap3, mask3);
			}
                        convert_frames2mbstring((gint)((off_t)entry->size/DATASECTORSIZE),
				tmp2);
		} else {
			pic = gtk_image_new_from_pixmap(pixmap2, mask2);
                        convert_frames2minstring((gint)((off_t)entry->size/CDDAFRAME), tmp2);
		}

		gtk_table_attach_defaults(GTK_TABLE(tbl),pic,0,1,i+1,i+2);
		gtk_widget_show(pic);
		
                g_snprintf(tmp,MAXLINE,"%2d.", trackparam->starttrack);
		l1 = gtk_label_new(tmp);
		gtk_table_attach_defaults(GTK_TABLE(tbl),l1,1,2,i+1,i+2);
		gtk_widget_show(l1);

		/* get title and artist from xinf file */
		strcpy(title,"");
		strcpy(artist,"");
		if (trackparam->trackfile) {
			get_title_artist_from_xinf(trackparam->trackfile,
				artist, title);
		}
		loop = loop->next;
	  }
		/* title entry */
		e1 = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
		cdtext_entry1[i+1] = e1;
		gtk_table_attach_defaults(GTK_TABLE(tbl),e1,2,10,i+1,i+2);
		gtk_entry_set_text(GTK_ENTRY(e1), convert_for_gtk2(title));
		gtk_entry_set_position(GTK_ENTRY(e1), 0);
		gtk_widget_show(e1);	

		/* set a tooltip with the original filename */
		if (mode != 0 && mode != 3 && trackparam->trackfile) {
			tip = gtk_tooltips_new();
                	g_snprintf(tmp,MAXLINE,"%s", trackparam->trackfile);
			gtk_tooltips_set_tip(tip,e1,tmp,NULL);
		}

		/* artist entry */
		e1 = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(e1), MAXENTRY);
		cdtext_entry2[i+1] = e1;
		gtk_table_attach_defaults(GTK_TABLE(tbl),e1,10,18,i+1,i+2);
		gtk_entry_set_text(GTK_ENTRY(e1), convert_for_gtk2(artist));
		gtk_entry_set_position(GTK_ENTRY(e1), 0);
		gtk_widget_show(e1);	

		l1 = gtk_label_new(tmp2);
		gtk_table_attach_defaults(GTK_TABLE(tbl),l1,18,21,i+1,i+2);
		gtk_widget_show(l1);
	}

	/* terminate entry list */
	cdtext_entry1[i+1] = NULL;
	cdtext_entry2[i+1] = NULL;

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

	button1 = gtk_button_new_with_label(T_OK);
	cddb_info_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));

	/* in duplicate mode allow lookup from CDDB too */
	if (mode == 1 || mode == 3) {
		button3 = gtk_button_new_with_label(_("Lookup titles on CDDB"));
		gtk_box_pack_start(GTK_BOX(box3),button3,TRUE,TRUE,0);
		gtk_widget_show(button3);
		GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
		g_signal_connect(button3,"clicked",
			G_CALLBACK(edit_cdtext_cddb), dialog);
		define_tooltip(button3,_("Connect to the CDDB database to download the track titles that belong to that CD. This will overwrite the current entries!"));

		if (mode == 1) {
			/* check if we got enough data to lookup anyway */
			canlookup = 0;
			loop = g_list_last(trackreadset.trackparams);
			if (loop) {
				trackparam = loop->data;
				if (trackparam) {
					canlookup = trackparam->start_sec;
				}	
			}
			/* no data from toc file - lock button */
			if (trackreadset.nrtracks == 0 || canlookup == 0) {
				gtk_widget_set_sensitive(button3, FALSE);
			}
		}
	}

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(-1));


	/* callback for cd-text set-all artist */
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), 
		curset.sync_cdtext_artist);

	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

	/* ok button pressed */
	if (dialog_get_value() == 0) {
		if (mode == 0) {
			/* get info from entries and save to cdinfo-struct */
			cdtext_edit_ok_mode0();

			/* update cdlist with new info on screen */
			fill_cdlist();
		} else
		if (mode == 1) {
			/* get info from entries and change in xinf files */
			cdtext_edit_ok_mode12(NULL);

			/* update toc selector with new info */
			if ( writetoc_menu && GTK_WIDGET_VISIBLE(writetoc_menu)) {
				/* simulate click on toc selector */
				menu = gtk_option_menu_get_menu(GTK_OPTION_MENU (writetoc_menu));
				menuitem = gtk_menu_get_active(GTK_MENU(menu));
				gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
			}

			/* now reload the image list */
			scan_imagedirs();
		} else 
		if (mode == 2) {
			/* get info from entries and change in xinf files */
			generate_tmp_tocfile_name(tmptoc);
			cdtext_edit_ok_mode12(tmptoc);

			/* now reload the image list */
			scan_imagedirs();

			/* redraw now the image display */
			fill_write_tracks();
			redraw_writelist(cdlist,cdlist_l1);
			fill_writelist2(imglist2,imglist_l2);

		} else 
		if (mode == 3) {
			/* get info from entries and save to cdinfo-struct */
			cdtext_edit_ok_mode0();

			/* update toc selector with new info */
			if ( writetoc_menu && GTK_WIDGET_VISIBLE(writetoc_menu)) {
				/* simulate click on toc selector */
				menu = gtk_option_menu_get_menu(GTK_OPTION_MENU (writetoc_menu));
				menuitem = gtk_menu_get_active(GTK_MENU(menu));
				gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
			}
		}
	} else {
		/* cancel? restore sync_all_button */
		curset.sync_cdtext_artist = bak_sync_cdtext_artist;
	}

        gtk_grab_remove(GTK_WIDGET(dialog));

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


/*
 * pop-up a modal window, where the user can choose where
 * to add several directories on the target disc. 
 * it centers automatically above the toplevel window 
 * return -1 on cancel and 0,1,2,3 according to settings
 */
gint show_mstr_redir_multi(gchar *commondir, gint nrpaths, gchar *ret) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2, *entry;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1, *f2, *f3, *l1;
GtkWidget *b1_sep, *lbl, *btn;
GSList *group;
gchar redir[MAXLINE], tmp2[MAXLINE];
gint bak_redirtype;
gchar tmp[MAXLINE];
gchar tmp3[MAXLINE];
gchar reducedpath[MAXLINE];
gint returncode;

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

	bak_redirtype = masterparam.redirtype2;
	redir_entry = NULL;

	get_reducedpath(commondir, reducedpath);

	/* no common dir? don't try to prompt for option 2 */
	if (strcmp(commondir,"") == 0 && masterparam.redirtype2 == 1) {
		masterparam.redirtype2 = 0;
	}	

	/* 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_size_request(dialog, tbf(450), -1);
	/* make sure our window is always on top */
	gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(toplevel));
	cddb_window = dialog;

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_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);
	gtk_widget_show(box1);

	f1 = gtk_frame_new(_("Adding several paths to master directories"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	f2 = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(f2),GTK_SHADOW_IN);
	gtk_box_pack_start(GTK_BOX(box2),f2,FALSE,TRUE,5);
	gtk_widget_show(f2);

	strncpy(tmp3, commondir, MAXLINE);
	convert_for_gtk2(tmp3);
	g_snprintf(tmp,MAXLINE,_("%s/... (%d paths)"), tmp3, nrpaths);
	l1 = gtk_label_new(tmp);
	gtk_container_add(GTK_CONTAINER(f2),l1);
	gtk_misc_set_alignment(GTK_MISC(l1),0.5,0.5);
	gtk_misc_set_padding(GTK_MISC(l1),5,5);
	gtk_widget_show(l1);

	lbl = gtk_label_new(_("Please choose where all the selected paths should be mapped on the Disc.\nDo note that selecting only one path at a time would give much greater\ncontrol about the Disc layout."));
	gtk_box_pack_start(GTK_BOX(box2),lbl,FALSE,TRUE,5);
	gtk_widget_show(lbl);

        b1_sep = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(box2),b1_sep,FALSE,TRUE,5);
	gtk_widget_show(b1_sep);

	btn = gtk_radio_button_new_with_label(NULL,_("Add all with full path"));
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected2),GINT_TO_POINTER(0));

	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	define_tooltip(btn,_("Will put all selected files or directories in the same path on the destination Disc, as they are on the hard drive now. (e.g. the directories /home/user1 and /home/user2 will also become /home/user1 and /home/user2 on the Disc.)"));
	if (masterparam.redirtype2 == 0) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
	group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));

	if (strcmp(commondir,"") != 0) {
		g_snprintf(tmp2,MAXLINE,_("Add all with path component \"%s\" removed"), tmp3);
		btn = gtk_radio_button_new_with_label(group,tmp2);
		g_signal_connect(btn,"clicked",
			G_CALLBACK(redir_type_selected2),
			GINT_TO_POINTER(1));
		gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
		gtk_widget_show(btn);
		define_tooltip(btn,_("Will strip off the shown path component of all selected files and directories on the destination Disc. (e.g. the directories /export/home/user1 and /export/home/user2/src get their common path /export/home stripped and become /user1 and /user2/src on the Disc.)"));
		if (masterparam.redirtype2 == 1) 
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
		group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	}

	if (strcmp(commondir,"") != 0 && strcmp(reducedpath,"") != 0) {
		strncpy(tmp3, reducedpath, MAXLINE);
		convert_for_gtk2(tmp3);
		g_snprintf(tmp2,MAXLINE,_("Add all with path component \"%s\" removed"), tmp3);
		btn = gtk_radio_button_new_with_label(group,tmp2);
		g_signal_connect(btn,"clicked",
			G_CALLBACK(redir_type_selected2),
			GINT_TO_POINTER(2));
		gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
		gtk_widget_show(btn);
		define_tooltip(btn,_("Will strip off the shown path component of all selected files and directories on the destination Disc. (e.g. the directories /export/home/user1 and /export/home/user2/src get their common path /export stripped and become /home/user1 and /home/user2/src on the Disc.)"));
		if (masterparam.redirtype2 == 2) 
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);
		group = gtk_radio_button_group (GTK_RADIO_BUTTON(btn));
	}

	if (strcmp(commondir,"") != 0) {
		strncpy(tmp3, commondir, MAXLINE);
		convert_for_gtk2(tmp3);
		g_snprintf(tmp2,MAXLINE,_("Add all with path component \"%s\" replaced by:"), tmp3);
	} else {
		strncpy(tmp2, _("Add all with a prefixed path:"), MAXLINE);
	}
	btn = gtk_radio_button_new_with_label(group,tmp2);
	g_signal_connect(btn,"clicked",
		G_CALLBACK(redir_type_selected2),GINT_TO_POINTER(3));
	gtk_box_pack_start(GTK_BOX(box2),btn,FALSE,TRUE,0);
	gtk_widget_show(btn);
	if (strcmp(commondir,"") != 0) {
		define_tooltip(btn,_("Will strip off the shown path component of all selected files and directories and insert a new path instead on the destination Disc. (e.g. the directories /export/home/user1 and /export/home/user2/src get their common path /export/home stripped and replaced by /bak1 - they show up as /bak1/user1 and /bak1/user2/src on the Disc.)"));
	} else {
		define_tooltip(btn,_("Will prefix all the selected files and directories with a new path on the destination Disc. (e.g. the directories /home/user1 and /opt/backup can be prefixed with /old to become /old/home/user1 and /old/opt/backup on the Disc.)"));
	}
	if (masterparam.redirtype2 == 3) 
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn),1);

	f3 = gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(box2),f3,FALSE,FALSE,5);
	gtk_widget_show(f3);

        entry = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(entry), MAXENTRY);
	redir_entry = entry;
	gtk_box_pack_start(GTK_BOX(f3),entry,TRUE,TRUE,20);
        gtk_widget_show(entry);
	gtk_entry_set_text(GTK_ENTRY(entry), masterparam.lastredirpath2);
	if (masterparam.redirtype2 != 3) 
		gtk_widget_set_sensitive(redir_entry, FALSE);

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

	button1 = gtk_button_new_with_label(T_OK);
	cddb_info_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));

	if (dialog_get_value() != 0) {
		/* restore original value of type */
		masterparam.redirtype2 = bak_redirtype;
		strcpy(redir,"");
		returncode = -1;
	} else {
		/* ok pressed, do some business */
		g_free(masterparam.lastredirpath2);
		masterparam.lastredirpath2 = g_strdup(
			gtk_entry_get_text(GTK_ENTRY(redir_entry)));

		if (masterparam.redirtype2 == 0) {
			strcpy(redir,"");
		}

		if (masterparam.redirtype2 == 1) {
			strcpy(redir,"");
		}

		if (masterparam.redirtype2 == 2) {
			strcpy(redir,"");
		}

		if (masterparam.redirtype2 == 3) {
			strncpy(redir,masterparam.lastredirpath2, MAXLINE);
		}
		strip_string(redir);

		/* remove trailing slash */
                if (strlen(redir) > 0) {
                        if (redir[strlen(redir)-1] == '/') {
				redir[strlen(redir)-1] = '\0';
                        }       
                }
		/* add leading slash */
		if (redir[0] != '/') {
			strcpy(tmp,"/");
			strcat(tmp, redir);
			strncpy(redir, tmp, MAXLINE);
		}
		/* update changes in copy */
		if (masterparam.redirtype2 == 3) {
			g_free(masterparam.lastredirpath2);
			masterparam.lastredirpath2 = g_strdup(redir);
		}
		returncode = masterparam.redirtype2;
	}

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

	/* now "redir" contains the string where we want to go */
	strncpy(ret, redir, MAXLINE);

	return returncode;
}


/*
 * prompt for a new device string in setup
 * it centers automatically above the toplevel window 
 */
gint show_add_manual_device(gchar *newdev) {
GtkWidget *dialog;
GtkWidget *button1;
GtkWidget *button2, *entry;
GtkWidget *box1,*box2,*box3;
GtkWidget *f1;
GtkWidget *b1_sep, *lbl;

	dodebug(8, "show_add_manual_device\n");

	/* 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));
	cddb_window = dialog;

        g_signal_connect(dialog, "delete_event",
                G_CALLBACK (dialog_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);
	gtk_widget_show(box1);

	f1 = gtk_frame_new(_("Manually add writer or reader devices"));
	set_font_and_color_frame(f1,PANGO_BOLD,NULL);
	gtk_box_pack_start(GTK_BOX(box1),f1,TRUE,TRUE,0);
	gtk_widget_show(f1);

	box2 = gtk_vbox_new(FALSE,0);
	gtk_container_set_border_width (GTK_CONTAINER (box2), 5);
	gtk_container_add(GTK_CONTAINER(f1),box2);
	gtk_widget_show(box2);

	lbl = gtk_label_new(_("Please enter a valid cdrecord device specification:"));
	gtk_box_pack_start(GTK_BOX(box2),lbl,FALSE,TRUE,5);
	gtk_widget_show(lbl);

	b1_sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(box2),b1_sep,FALSE,TRUE,5);
	gtk_widget_show(b1_sep);

	lbl = gtk_label_new(_("This can be any device string as described in the\ncdrecord manpage resp. the documentation.\n\nHint: Type in a terminal \"sudo cdrecord -scanbus\"\nto get a list of all currently attached devices.\n\nThen below for example: \"5,0,0\" (SCSI CAM standard notation) or\n\"REMOTE:rscsi@host:\" to scan for network enabled devices."));
	gtk_box_pack_start(GTK_BOX(box2),lbl,FALSE,TRUE,5);
	gtk_widget_show(lbl);


        entry = gtk_entry_new();
	    gtk_entry_set_max_length(GTK_ENTRY(entry), MAXENTRY);
	gtk_box_pack_start(GTK_BOX(box2),entry,TRUE,TRUE,10);
        g_signal_connect(entry, "activate",
                G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));
        gtk_widget_show(entry);

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

	button1 = gtk_button_new_with_label(T_OK);
	cddb_info_okbutton = button1;
	gtk_box_pack_start(GTK_BOX(box3),button1,TRUE,TRUE,10);
	gtk_widget_show(button1);
	GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
	gtk_widget_grab_default (button1);
	g_signal_connect(button1,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(0));

	button2 = gtk_button_new_with_label(T_CANCEL);
	gtk_box_pack_start(GTK_BOX(box3),button2,TRUE,TRUE,10);
	gtk_widget_show(button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
	g_signal_connect(button2,"clicked",
		G_CALLBACK(dialog_btn_press), GINT_TO_POINTER(-1));


	/* grab cursor */
        gtk_grab_add(dialog);

	my_center_dialog(dialog);
	gtk_widget_show(dialog);


	/* now wait until button is pressed */
	gtk_main();

        gtk_grab_remove(GTK_WIDGET(dialog));


	strncpy(newdev, gtk_entry_get_text(GTK_ENTRY(entry)), MAXLINE);

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

	return (dialog_get_value());
}


/*
 * A version of the dialog that requests the user to wait - will 
 * be removed by call
 */
GtkWidget *show_dialog_wait(gchar *icon_file, gchar *ttext) {
GtkWidget *dialog;
GtkWidget *box1;
GtkWidget *b1_t,*pix,*lab;
gchar *ico;

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

	/* 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));

	/* create layout for dialog */
        box1 = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(dialog),box1);
        gtk_widget_show(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);
        gtk_widget_show(b1_t);

        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);
        }

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

	my_center_dialog(dialog);
	gtk_widget_show(dialog);

	return (dialog);
}


/*
 * remove the wait dialog now
 */
void show_dialog_wait_remove(GtkWidget *dialog) {

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