/*
*	options_page.c
*
*	creates the options page in the notebook and deals with the controls...
*
*	(c) 2001 Tim-Philipp Muller <t.i.m@orange.net>
*
*/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

/* GtkOptionMenu is deprecated in Gtk+-2.4. If we
 *  use GTK_DISABLE_DEPRECATED, the type cast macros
 *  will not be defined, and we'll get linker errors. */
#include <gtk/gtkversion.h>
#if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION >= 3))
# undef GTK_DISABLE_DEPRECATED
#endif

#include <gnet.h>

#include <gtk/gtkhbbox.h>
#include <gtk/gtkvbbox.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkfontsel.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkhscale.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkoptionmenu.h>
#include <gtk/gtkradiobutton.h>
#include <gtk/gtkradiomenuitem.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkspinbutton.h>
#include <gtk/gtktable.h>
#include <gtk/gtktogglebutton.h>

#include <time.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "core-conn.h"
#include "global.h"
#include "http_get.h"
#include "icons.h"
#include "linkhandler.h"
#include "misc.h"
#include "misc_gtk.h"
#include "misc_strings.h"
#include "notebook.h"
#include "options.h"
#include "options_page.h"

#include "status_page.h"
#include "statusbar.h"

enum
{
 OPTIONS_LINKHANDLER_INSTALL_KDE_HANDLER = 1,
 OPTIONS_LINKHANDLER_INSTALL_GNOME1_HANDLER,
 OPTIONS_LINKHANDLER_INSTALL_GNOME2_HANDLER,
 OPTIONS_LINKHANDLER_INSTALL_MOZILLA_HANDLER,
 OPTIONS_LINKHANDLER_INSTALL_WINDOWS_HANDLER
} ;

/* global variables */

static GtkWidget  *scale_slider = NULL;

/* checkbox widgets */
static GtkWidget	*cb_verifyexit, *cb_shutdowncoreonexit;
static GtkWidget	*cb_connectcore, *cb_spawncore;
static GtkWidget	*cb_restartcrashedcore;
static GtkWidget	*cb_notabtext;
static GtkWidget	*cb_linkdownload, *cb_nodoubleclick;
static GtkWidget	*cb_nogreen, *cb_slowcon, *cb_logtimestamp;
static GtkWidget	*cb_nolinkstolog;
static GtkWidget	*cb_setrules;
static GtkWidget	*cb_savewindowpos;
static GtkWidget	*cb_useapplet;

/* entry widgets */
static GtkWidget	*ew_incoming, *ew_temporary, *ew_nickname;
static GtkWidget	*ew_slistURL, *ew_slistURL2, *ew_completecommand;

static GtkWidget	*spinbutton_minfreespace = NULL;
static GtkWidget	*spinbutton_serverrotate = NULL;
static GtkWidget	*spinbutton_clearswin = NULL;

static GtkWidget	*spinbutton_maxdlspeed = NULL;
static GtkWidget	*spinbutton_maxulspeed = NULL;
static GtkWidget	*spinbutton_port = NULL;
static GtkWidget	*spinbutton_adminport = NULL;
static GtkWidget	*spinbutton_maxcon = NULL;

/* radio buttons */
static GtkWidget	*radio1_lh = NULL;
static GtkWidget	*radio2_lh = NULL;
static GtkWidget	*radio3_lh = NULL;

static guint       num_downloads; /* 0 */

/* functions */

static GtkWidget	*options_page_make_linkhandler_options_frame (GtkTooltips *tooltips);


/*******************************************************************************
 *
 *   onNewDownload
 *
 *******************************************************************************/

static void
onNewDownload (gpointer nada, gpointer hash, gchar *name, guint size, guint prio, gchar *tmpfn, guint id, gpointer data)
{
	++num_downloads;
}

/*******************************************************************************
 *
 *   onCoreOptions
 *
 *******************************************************************************/

static void
onCoreOptions (gpointer nada, const CoreOptions *copts, gpointer data)
{
	options_update_option_widgets();
}

/*******************************************************************************
 *
 *   onRemoveDownload
 *
 *******************************************************************************/

static void
onRemoveDownload (gpointer nada, const guint8 *hash, guint cancelled, gpointer data)
{
	--num_downloads;
}


/******************************************************************************
 *
 *  onCoreConnStatus
 *
 ******************************************************************************/

static void
onCoreConnStatus (GuiCoreConn *conn, guint status, GtkWidget *mainwindow)
{
	if (status != CONN_STATUS_COMMUNICATING)
		num_downloads = 0;
}


/*******************************************************************************
 *
 *   options_page_add_widget_to_table
 *
 ***/

static void
options_page_add_widget_to_table (GtkWidget   *table,
                                 const gchar *labeltxt,
                                 GtkWidget   *widget,
                                 guint        row,
                                 const gchar *tiptext,
                                 GtkTooltips *tooltips )
{
	gchar      *utf8;
	GtkWidget  *sblabel;

	g_return_if_fail ( table    != NULL );
	g_return_if_fail ( labeltxt != NULL );
	g_return_if_fail ( widget   != NULL );

	utf8 = TO_UTF8(labeltxt);

	sblabel = gtk_label_new(utf8);
	gtk_widget_show(sblabel);

	gtk_table_attach (GTK_TABLE (table), sblabel, 0, 1, row, row+1,
	                  (GtkAttachOptions) (GTK_FILL),
	                  (GtkAttachOptions) (0), 5, 0);
	gtk_label_set_justify (GTK_LABEL (sblabel), GTK_JUSTIFY_LEFT);
	gtk_misc_set_alignment (GTK_MISC (sblabel), 0, 0.5);

	gtk_widget_show (widget);
	gtk_table_attach (GTK_TABLE (table), widget, 1, 2, row, row+1,
	                  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
	                  (GtkAttachOptions) (0), 5, 0);

	if (tiptext!=NULL)
	{
		gchar *tip_utf8;

		g_return_if_fail ( tooltips != NULL );

		tip_utf8 = TO_UTF8(tiptext);
		gtk_tooltips_set_tip (tooltips, widget, tip_utf8, NULL);
		FREE_UTF8(tip_utf8);
	}

	FREE_UTF8(utf8);
}

/*******************************************************************************
 *
 *   options_page_add_entry_to_table
 *
 ***/

static GtkWidget *
options_page_add_entry_to_table (GtkWidget   *table,
                                 const gchar *labeltxt,
                                 guint        row,
                                 const gchar *tiptext,
                                 GtkTooltips *tooltips )
{
	GtkWidget  *entry;

	g_return_val_if_fail ( table    != NULL, NULL );
	g_return_val_if_fail ( labeltxt != NULL, NULL );

	entry = gtk_entry_new();

	options_page_add_widget_to_table (table, labeltxt, entry, row, tiptext, tooltips );

	return entry;
}


/*******************************************************************************
 *
 *   options_page_add_spinbutton_to_table
 *
 ***/

static GtkWidget *
options_page_add_spinbutton_to_table (GtkWidget   *table,
                                      const gchar *labeltxt,
                                      gfloat       default_val,
                                      gfloat       min_val,
                                      gfloat       max_val,
                                      gfloat       increment,
                                      guint        row,
                                      const gchar *tiptext,
                                      GtkTooltips *tooltips )
{
	GtkWidget *spinbutton;

	g_return_val_if_fail ( table    != NULL, NULL );
	g_return_val_if_fail ( labeltxt != NULL, NULL );

	spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT(gtk_adjustment_new(default_val,min_val,max_val,1.0,1.0,1.0)),increment,0);

	options_page_add_widget_to_table (table, labeltxt, spinbutton, row, tiptext, tooltips );

	return spinbutton;
}

/*******************************************************************************
 *
 *   options_update_option_widgets
 *
 *******************************************************************************/

void
options_update_option_widgets (void)
{
	const CoreOptions *copts;
	const gchar       *sl1, *sl2, *exec;

	copts = gui_core_conn_get_core_options(core);

	gtk_entry_set_text (GTK_ENTRY(ew_nickname),   (copts->nick)        ? UTF8_SHORT_PRINTF("%s",copts->nick): "");
	gtk_entry_set_text (GTK_ENTRY(ew_incoming),   (copts->incomingdir) ? UTF8_SHORT_PRINTF("%s",copts->incomingdir): "");
	gtk_entry_set_text (GTK_ENTRY(ew_temporary),  (copts->tempdir)     ? UTF8_SHORT_PRINTF("%s",copts->tempdir): "");

	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_maxdlspeed), (gdouble) copts->max_dl_speed);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_maxulspeed), (gdouble) copts->max_ul_speed);

	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_port),       (gdouble) copts->clientport );
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_adminport),  (gdouble) copts->adminport  );
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_maxcon),     (gdouble) copts->maxconns   );

	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_serverrotate),
	                           opt_get_int(OPT_GUI_SERVERS_ROTATE_INTERVAL)*1.0);


	if ((sl1 = opt_get_str(OPT_GUI_SERVERLIST_URL_1)))
		gtk_entry_set_text (GTK_ENTRY(ew_slistURL), UTF8_SHORT_PRINTF("%s",sl1));

	if ((sl2 = opt_get_str(OPT_GUI_SERVERLIST_URL_2)))
		gtk_entry_set_text (GTK_ENTRY(ew_slistURL2), UTF8_SHORT_PRINTF("%s",sl2));

	if ((exec = opt_get_str(OPT_GUI_EXEC_ON_COMPLETE_COMMAND)))
		gtk_entry_set_text (GTK_ENTRY(ew_completecommand), UTF8_SHORT_PRINTF("%s",exec));

	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_clearswin),
	                           opt_get_int(OPT_GUI_STATUS_WINDOW_CLEAR_INTERVAL)*1.0);

	gtk_spin_button_set_value (GTK_SPIN_BUTTON(spinbutton_minfreespace),
	                           opt_get_int(OPT_GUI_DOWNLOADS_MIN_FREE_DISKSPACE)*1.0);

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_verifyexit),
	                              opt_get_bool(OPT_GUI_VERIFY_EXIT));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_shutdowncoreonexit),
	                              opt_get_bool(OPT_GUI_SHUTDOWN_CORE_ON_EXIT));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_spawncore),
	                              opt_get_bool(OPT_GUI_SPAWN_CORE_ON_STARTUP_IF_NEEDED));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_connectcore),
	                              opt_get_bool(OPT_GUI_AUTO_CONNECT_TO_CORE_ON_STARTUP));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_notabtext),
	                              opt_get_bool(OPT_GUI_MAIN_NOTEBOOK_HIDE_TAB_TEXT_LEFT_RIGHT));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_linkdownload),
	                              opt_get_bool(OPT_GUI_DOWNLOAD_ED2K_LINK_IMMEDIATELY));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_restartcrashedcore),
	                              opt_get_bool(OPT_GUI_RESTART_CRASHED_CORE));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_nodoubleclick),
	                              opt_get_bool(OPT_GUI_IGNORE_DOUBLE_CLICKS));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_nogreen),
	                              opt_get_bool(OPT_GUI_NO_GREEN));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_slowcon),
	                              opt_get_bool(OPT_GUI_SLOW_GUI_CORE_CONNECTION));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_logtimestamp),
	                              opt_get_bool(OPT_GUI_LOG_HAVE_TIMESTAMP));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_nolinkstolog),
	                              opt_get_bool(OPT_GUI_NO_LINKS_TO_LOGFILE));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1_lh),
	                              (opt_get_int(OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING) == LINKHANDLER_IF_NO_GUI_ASK));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2_lh),
	                              (opt_get_int(OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING) == LINKHANDLER_IF_NO_GUI_START_GUI));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio3_lh),
	                              (opt_get_int(OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING) == LINKHANDLER_IF_NO_GUI_REMEMBER_AND_QUIT));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_setrules),
	                              opt_get_bool(OPT_GUI_SET_RULES_HINT_ON_LISTS));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_savewindowpos),
	                              opt_get_bool(OPT_GUI_WINDOW_SAVE_POS_AND_SIZE));

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb_useapplet),
	                              opt_get_bool(OPT_GUI_USE_APPLET_IF_SUPPORTED));
}


static void
options_onOK_check_gui_flags (GString *error_msg)
{
	/* the GUI options flags we can read directly  */
	opt_set_bool (OPT_GUI_VERIFY_EXIT, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_verifyexit)));
	opt_set_bool (OPT_GUI_SHUTDOWN_CORE_ON_EXIT, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_shutdowncoreonexit)));
	opt_set_bool (OPT_GUI_SPAWN_CORE_ON_STARTUP_IF_NEEDED, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_spawncore)));
	opt_set_bool (OPT_GUI_AUTO_CONNECT_TO_CORE_ON_STARTUP, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_connectcore)));
	opt_set_bool (OPT_GUI_DOWNLOAD_ED2K_LINK_IMMEDIATELY, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_linkdownload)));
	opt_set_bool (OPT_GUI_RESTART_CRASHED_CORE, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_restartcrashedcore)));
	opt_set_bool (OPT_GUI_IGNORE_DOUBLE_CLICKS, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_nodoubleclick)));
	opt_set_bool (OPT_GUI_NO_GREEN, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_nogreen)));
	opt_set_bool (OPT_GUI_SLOW_GUI_CORE_CONNECTION, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_slowcon)));
	opt_set_bool (OPT_GUI_LOG_HAVE_TIMESTAMP, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_logtimestamp)));
	opt_set_bool (OPT_GUI_NO_LINKS_TO_LOGFILE, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_nolinkstolog)));
	opt_set_bool (OPT_GUI_MAIN_NOTEBOOK_HIDE_TAB_TEXT_LEFT_RIGHT, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_notabtext)));

	opt_set_bool (OPT_GUI_WINDOW_SAVE_POS_AND_SIZE, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_savewindowpos)));
	opt_set_bool (OPT_GUI_USE_APPLET_IF_SUPPORTED, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_useapplet)));

	if ( opt_get_bool(OPT_GUI_SET_RULES_HINT_ON_LISTS) != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cb_setrules)) )
	{
		opt_set_bool (OPT_GUI_SET_RULES_HINT_ON_LISTS, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb_setrules)));
	}
}


static void
options_onOK_check_linkhandler_radio_buttons (GString *error_msg)
{
	g_return_if_fail ( radio1_lh != NULL );
	g_return_if_fail ( radio2_lh != NULL );
	g_return_if_fail ( radio3_lh != NULL );
	g_return_if_fail ( error_msg != NULL );

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio1_lh)))
	{
		opt_set_int (OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING, LINKHANDLER_IF_NO_GUI_ASK);
		return;
	}

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio2_lh)))
	{
		opt_set_int (OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING, LINKHANDLER_IF_NO_GUI_START_GUI);
		return;
	}

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio3_lh)))
	{
		opt_set_int (OPT_GUI_LINKHANDLER_ACTION_IF_NO_GUI_RUNNING, LINKHANDLER_IF_NO_GUI_REMEMBER_AND_QUIT);
		return;
	}

	error_msg = g_string_append (error_msg, "linkhandler radio button inconsistency");
	g_return_if_reached();
}


static void
options_onOK_check_nick (GString *error_msg, const CoreOptions *copts)
{
	gchar   *nickname_utf8, *nickname;

	g_return_if_fail ( error_msg   != NULL );
	g_return_if_fail ( ew_nickname != NULL );

	nickname_utf8 = gtk_editable_get_chars (GTK_EDITABLE(ew_nickname), 0, -1);
	nickname      = TO_LOCALE(nickname_utf8);

	if ( !nickname || *nickname == 0x00)
	{
		g_string_append (error_msg, _("You have to enter a nickname.\n"));
	}
	else
	{
		g_return_if_fail (copts->nick != NULL);

		if (strcmp(nickname, copts->nick) != 0)
			gui_core_conn_send_set_nickname(core, nickname);
	}

	G_FREE(nickname_utf8);
	G_FREE(nickname);
}


static void
options_onOK_check_incoming  (GString *error_msg, const CoreOptions *copts)
{
	gchar  *incoming_utf8, *incoming;

	g_return_if_fail ( error_msg   != NULL );
	g_return_if_fail ( ew_incoming != NULL );

	incoming_utf8 = gtk_editable_get_chars (GTK_EDITABLE(ew_incoming), 0, -1);
	incoming      = TO_LOCALE(incoming_utf8);

	/* check if incoming directory exists and we have read and write permission */
	if (strcmp (incoming, copts->incomingdir) != 0 )
	{
		if (gui_core_conn_is_local(core) && !g_file_test(incoming, G_FILE_TEST_EXISTS) )
		{
			g_string_append (error_msg, _("incoming directory does not exist.\n"));
		}

		else if (gui_core_conn_is_local(core) && !g_file_test(incoming, G_FILE_TEST_IS_DIR) )
		{
			g_string_append (error_msg, _("incoming directory is not a directory.\n"));
		}

		else
		{
			if (gui_core_conn_is_local(core) && access(incoming, R_OK | W_OK) != 0)
			{
				g_string_append (error_msg,
					_("incoming directory - we don't have both read and write permission.\n"
					   "but I'll change it anyway\n"
					   "(in case the core runs under a different user ID than the GUI)\n\n"));
			}

			gui_core_conn_send_set_incoming(core, incoming);
		}
	}

	G_FREE(incoming_utf8);
	G_FREE(incoming);
}

static void
options_onOK_check_temporary (GString *error_msg, const CoreOptions *copts)
{
	gchar  *temporary_utf8, *temporary;

	g_return_if_fail ( error_msg    != NULL );
	g_return_if_fail ( ew_temporary != NULL );

	temporary_utf8 = gtk_editable_get_chars (GTK_EDITABLE(ew_temporary), 0, -1);
	temporary      = TO_LOCALE(temporary_utf8);

	/* check if temporary directory exists and we have read and write permission */

	if (strcmp (temporary, copts->tempdir) != 0 )
	{
		if (gui_core_conn_is_local(core) && !g_file_test(temporary, G_FILE_TEST_EXISTS) )
		{
			g_string_append (error_msg, _("temporary directory does not exist.\n"));
		}

		else if (gui_core_conn_is_local(core) && !g_file_test(temporary, G_FILE_TEST_IS_DIR) )
		{
			g_string_append (error_msg, _("temporary directory is not a directory.\n"));
		}

		else
		{
			if (gui_core_conn_is_local(core) && access (temporary, R_OK | W_OK) != 0 )
			{
				g_string_append (error_msg,
						_("temporary directory - we don't have both read and write permission.\n"
						   "but I'll change it anyway\n"
						   "(in case the core runs under a different user ID than the GUI)\n\n"));
			}

			if (num_downloads > 0)
			{
				g_string_append (error_msg, _("Can't change temp folder while there are unfinished downloads.\n"));
			}
			else
			{
				gui_core_conn_send_set_temp(core, temporary);
			}
		}
	}

	G_FREE(temporary_utf8);
	G_FREE(temporary);
}

static void
options_onOK_check_slistURL (GString *error_msg)
{
	gchar   *slistURL_utf8, *slistURL, *slistURL2_utf8, *slistURL2;

	g_return_if_fail ( error_msg    != NULL );
	g_return_if_fail ( ew_slistURL  != NULL );
	g_return_if_fail ( ew_slistURL2 != NULL );

	slistURL_utf8    = gtk_editable_get_chars (GTK_EDITABLE(ew_slistURL), 0, -1);
	slistURL2_utf8   = gtk_editable_get_chars (GTK_EDITABLE(ew_slistURL2), 0, -1);
	slistURL         = TO_LOCALE(slistURL_utf8);
	slistURL2        = TO_LOCALE(slistURL2_utf8);

	if ( !opt_get_str(OPT_GUI_SERVERLIST_URL_1)
	     || strcmp (slistURL, opt_get_str(OPT_GUI_SERVERLIST_URL_1)) != 0)
	{
		/* check if URL is valid */
		GURI *checkurl = gnet_uri_new (slistURL);

		if (misc_gnet_http_url_okay(checkurl))
			opt_set_str(OPT_GUI_SERVERLIST_URL_1, slistURL);
		else
			g_string_append (error_msg, _("There was an error parsing the serverlist URL (look at status window for details).\n"));

		if (checkurl)
			gnet_uri_delete(checkurl);
	}

	if ( !opt_get_str(OPT_GUI_SERVERLIST_URL_2)
	     || strcmp (slistURL2, opt_get_str(OPT_GUI_SERVERLIST_URL_2)) != 0 )
	{
		/* check if URL is valid */
		GURI *checkurl = gnet_uri_new (slistURL2);

		if (misc_gnet_http_url_okay(checkurl))
			opt_set_str(OPT_GUI_SERVERLIST_URL_2,slistURL2);
		else
			g_string_append (error_msg, _("There was an error parsing the second serverlist URL (see status window).\n"));

		if (checkurl)
			gnet_uri_delete(checkurl);
	}

	G_FREE(slistURL_utf8);
	G_FREE(slistURL2_utf8);
	G_FREE(slistURL);
	G_FREE(slistURL2);
}

static void
options_onOK_check_completecommand (GString *error_msg)
{
	gchar   *completecommand_utf8, *completecommand;

	g_return_if_fail ( error_msg          != NULL );
	g_return_if_fail ( ew_completecommand != NULL );

	completecommand_utf8 = gtk_editable_get_chars (GTK_EDITABLE(ew_completecommand), 0, -1);
	completecommand      = TO_LOCALE(completecommand_utf8);

	opt_set_str(OPT_GUI_EXEC_ON_COMPLETE_COMMAND, completecommand);

	G_FREE(completecommand_utf8);
	G_FREE(completecommand);
}

static gboolean
show_icon_scale_msg_delayed (gpointer data)
{
	status_msg(_("Icons will be resized the next time you start the GUI\n"));
	return FALSE;
}

static void
options_onOK_check_icon_scale_factor (GString *error_msg)
{
	if (scale_slider)
	{
		gdouble val = gtk_range_get_value(GTK_RANGE(scale_slider));
		guint   ival = (((guint)val)/5) * 5;
		if (ival != opt_get_int(OPT_GUI_ICON_SCALING_FACTOR))
		{
			opt_set_int(OPT_GUI_ICON_SCALING_FACTOR, ival);
			/* delay msg to come after 'Done.' from core */
			(void) g_timeout_add(1500, show_icon_scale_msg_delayed, NULL);
		}
	}
}


static gboolean
options_onOK_get_new_options_timeout_callback (gpointer data)
{
	gui_core_conn_send_get_options(core); /* which in turn will update the widgets.. */
	return FALSE;       /* call us only once */
}


void
options_ok_button_clicked (GtkWidget *widget, gpointer gdata)
{
	const CoreOptions *copts;
	gint               dummyint;
	GString           *error_msg;             /* to store our error messages */

	copts = gui_core_conn_get_core_options(core);

	// checking validity of options (initial string for error messages)

	error_msg = g_string_new ("");

	options_onOK_check_gui_flags (error_msg);
	options_onOK_check_linkhandler_radio_buttons (error_msg);
	options_onOK_check_nick (error_msg, copts);

	gui_core_conn_send_set_max_speeds (core,
	                     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (spinbutton_maxdlspeed)),
	                     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (spinbutton_maxulspeed)));

	options_onOK_check_incoming (error_msg, copts);
	options_onOK_check_temporary (error_msg, copts);

	dummyint = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinbutton_port));
	if (copts->clientport != dummyint)
	{
		gui_core_conn_send_set_port(core, dummyint);
		status_msg (_("GUI: listening port changed - will take effect on restart (of the core).\n"));
		if (dummyint<1024)
		{
			g_string_append (error_msg, _("\nWarning: You have chosen a port <1024 to listen to.\n"
											"This usually requires root privileges (just thought I'd point that out).\n\n"));
		}
	}

	dummyint = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinbutton_adminport));
	if (copts->adminport != dummyint)
	{
		gui_core_conn_send_set_admin_port(core, dummyint);
		status_msg (_("GUI: admin listening port changed - will take effect on restart (of the core).\n"));
		if (dummyint<1024)
		{
			g_string_append (error_msg, _("\nWarning: You have chosen an admin port <1024 to listen to.\n"
											"This usually requires root privileges (just thought I'd point that out).\n\n"));
		}
	}

	dummyint = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinbutton_maxcon));
	if (copts->maxconns != dummyint)
		gui_core_conn_send_set_max_connections(core, dummyint);


	opt_set_int (OPT_GUI_SERVERS_ROTATE_INTERVAL, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinbutton_serverrotate)));

	if ( opt_get_int(OPT_GUI_SERVERS_ROTATE_INTERVAL) > 0
	        && opt_get_int(OPT_GUI_SERVERS_ROTATE_INTERVAL) < 30 )
	{
		opt_set_int(OPT_GUI_SERVERS_ROTATE_INTERVAL, 30);	/* make sure it's not too extreme */
	}

	opt_set_int (OPT_GUI_DOWNLOADS_MIN_FREE_DISKSPACE,
	             gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinbutton_minfreespace)));

	options_onOK_check_slistURL (error_msg);

	options_onOK_check_completecommand (error_msg);

	options_onOK_check_icon_scale_factor(error_msg);

	opt_set_int ( OPT_GUI_STATUS_WINDOW_CLEAR_INTERVAL,
	              gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinbutton_clearswin)));

	notebook_show_hide_tab_label_text ();

	// if there were errors, pop up dialog window

	if (error_msg->len != 0)
	{
		misc_gtk_ok_dialog (GTK_MESSAGE_WARNING, error_msg->str);
	}
	else
	{
		opt_write_to_disk();
	}


	g_string_free (error_msg, TRUE);

	/* core might be a bit slow updating the options, so get them now, in 2secs and in 5 secs */
	gui_core_conn_send_get_options(core);
	g_timeout_add (2000, options_onOK_get_new_options_timeout_callback, NULL);
	g_timeout_add (5000, options_onOK_get_new_options_timeout_callback, NULL);
}


static void
options_cancel_button_clicked (GtkWidget *widget, gpointer gdata)
{
	options_update_option_widgets ();
}

static void
options_refresh_button_clicked (GtkWidget *widget, gpointer gdata)
{
	gui_core_conn_send_get_options(core);
}

static void
options_rotate_tabs_button_clicked (GtkWidget *widget, gpointer gdata)
{
	switch (opt_get_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS))
	{
		case GTK_POS_LEFT:      opt_set_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS, GTK_POS_TOP);
		break;
		case GTK_POS_RIGHT:     opt_set_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS, GTK_POS_BOTTOM);
		break;
		case GTK_POS_TOP:       opt_set_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS, GTK_POS_RIGHT);
		break;
		case GTK_POS_BOTTOM:    opt_set_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS, GTK_POS_LEFT);
		break;
	}

	notebook_set_tab_pos((GtkPositionType)opt_get_int(OPT_GUI_MAIN_NOTEBOOK_TAB_POS));

	notebook_show_hide_tab_label_text();
}

/* options_icontheme_selected
 *
 *
 *
 *
 */

static void
options_icontheme_selected (GtkWidget *widget, gpointer data)
{
	gchar *base;

	g_return_if_fail ( data != NULL );

	base = g_path_get_basename(data);

	opt_set_str (OPT_GUI_ICON_THEME, base);

	statusbar_msg (_(" The new icon theme ('%s') will be active after the next GUI restart."), base);

	G_FREE(base);
} ;

#if 0
/***************************************************************************
 *
 *   downloads_view_get_current_font_name
 *
 ***************************************************************************/

gchar *
downloads_view_get_current_font_name (void)
{
	GtkStyle *treeview_style;

	treeview_style = gtk_rc_get_style(downloads_view);

	if ((treeview_style) && (treeview_style->font_desc))
		return pango_font_description_to_string(treeview_style->font_desc);

	return NULL;
}
#endif

/*******************************************************************************
 *
 *  options_page_onSelectFont
 *
 ***/

static void
options_page_onSelectFont (GtkWidget *widget, gpointer data)
{
	const gchar *fn;    /* file path of ~/.ed2k_gui/font.gtkrc-2.0 file */
	GtkWidget   *fsd;
	GtkStyle    *defstyle, *curstyle;
	FILE        *f;
	gchar       *fname, *deffname; /* font name */
	gint        ret;

	fsd = gtk_font_selection_dialog_new(UTF8_SHORT_PRINTF("%s",_("Select a font")));

	defstyle = gtk_widget_get_default_style();
	if ((defstyle) && (defstyle->font_desc))
		deffname = pango_font_description_to_string(defstyle->font_desc);
	else
		deffname = g_strdup(_("(unknown)"));

	curstyle = gtk_rc_get_style(fsd);
	if ((curstyle) && (curstyle->font_desc))
	{
		fname = pango_font_description_to_string(curstyle->font_desc);
		gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fsd), fname);
		statusbar_msg(_("Current font: %s   Default font is: %s"), fname, deffname);
		g_free(fname);
		fname = NULL;
	}
	else
	{
		statusbar_msg(_("Default font is: %s"), deffname);
		fname = NULL;
	}

	ret = gtk_dialog_run(GTK_DIALOG(fsd));

	statusbar_msg("  ");

	if ( ret != GTK_RESPONSE_OK )
	{
		gtk_widget_destroy(fsd);
		g_free(deffname);
		return;
	}

	fname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(fsd));

	if (!fname)
	{
		gtk_widget_destroy(fsd);
		statusbar_msg(_("No font was selected."));
		fname = "default";
	}

	fn = opt_get_opt_filename_without_instance("font.gtkrc-2.0");

	f = fopen (fn, "w");

	if (!f)
	{
		statusbar_msg("Could not write %s file: %s", fn, g_strerror(errno));
		gtk_widget_destroy(fsd);
		g_free(deffname);
		return;
	}

	fprintf(f, "# ~/.ed2k_gui/font.gtkrc-2.0\n#\n");
	fprintf(f, _("# Automatically generated. DO NOT EDIT!\n"));
	fprintf(f, "#\n");
	fprintf(f, _("# Please edit ~/.ed2k_gui/custom.gtkrc-2.0 for\n"
	             "#  ed2k_gui-specific personal Gtk+-2.x style or\n"
	             "#  theme changes, not this file.\n"));
	fprintf(f, "#\nstyle \"user-font\"\n{\n  font_name=\"%s\"\n}\n", fname);
	fprintf(f, "widget_class \"*\" style \"user-font\"\n");

	fclose(f);
	gtk_widget_destroy(fsd);

	gtk_rc_reparse_all();

	g_free(deffname);
}

/*******************************************************************************
 *
 *  options_page_lookfeel_frame_add_option_menu_dir_item
 *
 ***/

static void
options_page_lookfeel_frame_add_option_menu_dir_item ( GSList **om_group,
                                                       GtkWidget *menu_iconthemes,
                                                       gchar *icondir )
{
	GtkWidget *menu_item;

	g_return_if_fail ( om_group != NULL );
	g_return_if_fail ( icondir  != NULL );

	menu_item = gtk_radio_menu_item_new_with_label (*om_group, icondir);

	GTK_WIDGET_SET_FLAGS (menu_item, GTK_CAN_DEFAULT);

	*om_group  = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM(menu_item));

	gtk_widget_show(menu_item);

	/* menu_item takes ownership of the allocated icondir string */
	g_signal_connect (G_OBJECT (menu_item), "activate",
	                  G_CALLBACK(options_icontheme_selected),
	                  (gpointer) icondir );

	/* free the allocated icondir string when the menu item is destroyed */
	g_object_set_data_full (G_OBJECT(menu_item), icondir, icondir, g_free);

	gtk_menu_shell_append (GTK_MENU_SHELL(menu_iconthemes), menu_item);
}


/*******************************************************************************
 *
 *  icon_scale_slider_format_value_func
 *
 ***/

static gchar *
icon_scale_slider_format_value_func (GtkScale *scale, gdouble value)
{
	return g_strdup(UTF8_SHORT_PRINTF(" %s: %u%% ", _("Icon scaling factor"), (((guint)value)/5)*5));
}


/*******************************************************************************
 *
 *  options_page_make_lookfeel_icon_themes_frame
 *
 *  creates the 'Icon Themes' frame and returns it
 *
 ***/

static GtkWidget *
options_page_make_lookfeel_icon_themes_frame (void)
{
	GtkWidget  *hbuttonbox;
	GtkWidget  *menu_iconthemes;
	GtkWidget  *guiopt_look_theme_frame;
	GtkWidget  *vbox, *hbox;
	GtkWidget  *om_iconthemes;
	GSList     *node, *omdirs;
	GSList     *om_group = NULL;

	guiopt_look_theme_frame = gtk_frame_new(UTF8_SHORT_PRINTF(_(" Icon theme ")));
	gtk_widget_show(guiopt_look_theme_frame);
	gtk_container_set_border_width (GTK_CONTAINER(guiopt_look_theme_frame),5);

	omdirs = icons_get_installed_icon_themes();

	g_return_val_if_fail ( omdirs != NULL, guiopt_look_theme_frame );

	menu_iconthemes = gtk_menu_new();
	gtk_widget_show(menu_iconthemes);
	GTK_WIDGET_SET_FLAGS (menu_iconthemes, GTK_CAN_DEFAULT);

	om_iconthemes = gtk_option_menu_new();
	gtk_widget_show (om_iconthemes);
	GTK_WIDGET_SET_FLAGS (om_iconthemes, GTK_CAN_DEFAULT);
	gtk_container_set_border_width (GTK_CONTAINER(om_iconthemes),5);

	/* note: do not free list contents! menu widgets take OWNERSHIP of the allocated directory strings. */
	for ( node = omdirs;  node != NULL;  node = node->next )
		options_page_lookfeel_frame_add_option_menu_dir_item ( &om_group, menu_iconthemes, (gchar*) node->data );

	g_slist_free(omdirs);

	gtk_option_menu_set_menu (GTK_OPTION_MENU(om_iconthemes), menu_iconthemes);

	hbuttonbox = gtk_hbutton_box_new();
	gtk_widget_show(hbuttonbox);
	gtk_container_add(GTK_CONTAINER(hbuttonbox), om_iconthemes);

	scale_slider = gtk_hscale_new_with_range(10.0, 190.0, 5.0);
	gtk_widget_show(scale_slider);
	gtk_scale_set_digits(GTK_SCALE(scale_slider), 0);
	gtk_range_set_value(GTK_RANGE(scale_slider), (gdouble) opt_get_int(OPT_GUI_ICON_SCALING_FACTOR));
	g_signal_connect(scale_slider, "format-value", G_CALLBACK(icon_scale_slider_format_value_func), NULL);

	vbox = gtk_vbox_new(FALSE, 5);
	gtk_widget_show(vbox);

	hbox = gtk_hbox_new(FALSE, 5); /* used for padding the scale slider */
	gtk_widget_show(hbox);

	gtk_box_pack_start(GTK_BOX(hbox), scale_slider, TRUE, TRUE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(hbox), 25);

	gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 15);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

	gtk_container_add(GTK_CONTAINER(guiopt_look_theme_frame), vbox);

	return guiopt_look_theme_frame;
}


/*******************************************************************************
 *
 *  options_page_make_lookfeel_frame
 *
 *  creates the 'GUI Look and Feel' frame and returns it
 *
 ***/

static GtkWidget *
options_page_make_lookfeel_frame (GtkTooltips *tooltips)
{
	GtkWidget  *guiopt_look_frame;
	GtkWidget  *guiopt_look_label;
	GtkWidget  *guiopt_look_theme_frame;
	GtkWidget  *guiopt_look_table;
	GtkWidget  *vbox9, *vbox10, *hbox3, *hbox5;
	GtkWidget  *rotate_button, *rotate_buttonbox, *font_button;
	const gchar *utf8;

	utf8 = UTF8_SHORT_PRINTF("<span size='large'>\n<b>%s</b>\n</span>",
	                          _(" GUI Look and Feel Options "));

	guiopt_look_label = gtk_label_new (utf8);
	gtk_widget_show (guiopt_look_label);
	gtk_label_set_use_markup (GTK_LABEL (guiopt_look_label), TRUE);

	guiopt_look_frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (guiopt_look_frame), GTK_SHADOW_NONE);
	gtk_frame_set_label_widget (GTK_FRAME (guiopt_look_frame), guiopt_look_label);
	gtk_widget_show (guiopt_look_frame);

	vbox9 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox9);
	gtk_container_add (GTK_CONTAINER (guiopt_look_frame), vbox9);

	guiopt_look_table = gtk_table_new (2, 3, FALSE);
	gtk_widget_show (guiopt_look_table);
	gtk_container_set_border_width (GTK_CONTAINER(guiopt_look_table),10);
	gtk_box_pack_start (GTK_BOX (vbox9), guiopt_look_table, TRUE, TRUE, 0);

	cb_notabtext = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("hide text in notebook tabs when on the side"),
	                              tooltips,
	                              _("When the notebook tabs are on the left or on the right\n"
	                                "the tab text ('downloads' etc.) will be hidden, leaving\n"
	                                "only the tab icons."),
	                              1, 0 );

	cb_nodoubleclick = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("disable double-click in lists"),
	                              tooltips,
	                              _("Make double clicks in lists have no effect.\n"
	                                "Useful for some wheel-mouse users."),
	                              1, 1 );

	cb_nogreen = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("I really hate the colour green"),
	                              tooltips,
	                              _("Set this true to remove the default green colour\n"
	                                "and use the system default theme for the GUI.\n"
	                                "Will become active on GUI restart."),
	                              0, 0 );

	cb_setrules = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("Set rule hints on lists"),
	                              tooltips,
	                              _("Switches the rules in the lists on or off ('Rules' means that every second line\n"
	                                "of a list has a grey background)\n"),
	                              0, 1 );

	cb_savewindowpos = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("Save window position and size"),
	                              tooltips,
	                              _("Determines whether the GUI will save its own window position and size "
	                                "(instead of letting the window manager take care of that)."),
	                              0, 2 );

	cb_useapplet = misc_gtk_attach_new_check_button_to_table ( guiopt_look_table,
	                              _("Show applet if supported"),
	                              tooltips,
	                              _("Shows a little applet in the panel if the window manager or desktop environment "
	                                "supports it. Currently this is only supported in GNOME 2.2 or later."),
	                              1, 2 );

	vbox10 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox10);
	gtk_box_pack_start (GTK_BOX (vbox9), vbox10, TRUE, TRUE, 0);

	hbox3 = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox3);
	gtk_box_pack_start (GTK_BOX (vbox10), hbox3, TRUE, TRUE, 0);

	rotate_buttonbox = gtk_vbutton_box_new();
	gtk_widget_show(rotate_buttonbox);
	gtk_box_pack_start(GTK_BOX(hbox3), rotate_buttonbox, TRUE, TRUE, 0);
	new_icon_button_pack_and_signal_connect(&rotate_button,
	                                        rotate_buttonbox,
	                                        _("Rotate tab layout"),
	                                        options_rotate_tabs_button_clicked,
	                                        NULL,
	                                        1,
	                                        ICON_REFRESH);
	gtk_button_box_set_layout(GTK_BUTTON_BOX(rotate_buttonbox), GTK_BUTTONBOX_SPREAD);

	new_icon_button_pack_and_signal_connect(&font_button,
	                                        rotate_buttonbox,
	                                        _("Select Font ..."),
	                                        options_page_onSelectFont,
	                                        NULL,
	                                        1,
	                                        ICON_NONE);

	hbox5 = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox5);
	gtk_box_pack_start (GTK_BOX (hbox3), hbox5, TRUE, TRUE, 0);

	guiopt_look_theme_frame = options_page_make_lookfeel_icon_themes_frame();
	gtk_box_pack_start (GTK_BOX (hbox3), guiopt_look_theme_frame, TRUE, TRUE, 5);

	return guiopt_look_frame;
}


/* options_page_make_guigeneral_frame
 *
 * creates the 'GUI General' frame and returns it
 *
 */

static GtkWidget *
options_page_make_guigeneral_frame (GtkTooltips *tooltips)
{
	GtkWidget   *guiopt_general_frame;
	GtkWidget   *guiopt_general_label;
	GtkWidget   *guiopt_general_table;
	const gchar *utf8 = UTF8_SHORT_PRINTF("<span size='large' weight='ultrabold'>\n<b>%s</b>\n</span>",
	                                       _(" GUI General Options "));

	guiopt_general_label = gtk_label_new (utf8);
	gtk_label_set_use_markup (GTK_LABEL (guiopt_general_label), TRUE);
	gtk_widget_show (guiopt_general_label);

	guiopt_general_frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (guiopt_general_frame), GTK_SHADOW_NONE);
	gtk_frame_set_label_widget (GTK_FRAME (guiopt_general_frame), guiopt_general_label);
	gtk_widget_show (guiopt_general_frame);

	guiopt_general_table = gtk_table_new (8, 2, FALSE);
	gtk_widget_show (guiopt_general_table);
	gtk_container_set_border_width (GTK_CONTAINER(guiopt_general_table),10);
	gtk_container_add (GTK_CONTAINER (guiopt_general_frame), guiopt_general_table);

	cb_verifyexit = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("ask before exit"),
	                              tooltips,
	                              _("Ask for confirmation before closing the GUI"),
	                              0, 0 );

	cb_shutdowncoreonexit = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("shutdown core on exit"),
	                              tooltips,
	                              _("Kill running core when the GUI is closed (otherwise it keeps running in the background"),
	                              0, 1 );

	cb_spawncore = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("auto-spawn core"),
	                              tooltips,
	                              _("Automatically start a donkey core at startup unless there is already a core running"),
	                              0, 2 );

	cb_connectcore = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("auto-connect to core"),
	                              tooltips,
	                              _("Automatically connect to running core at GUI startup"),
	                              0, 3 );

	cb_linkdownload = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("download ed2k:// links immediately"),
	                              tooltips,
	                              _("If set to true, links will be immediately downloaded.\n"
	                                "Otherwise, they will show up in the search page first."),
	                              1, 0 );

	cb_logtimestamp = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("show timestamps in status window"),
	                              tooltips,
	                              _("Display date and time in status window messages"),
	                              1, 1 );

	cb_nolinkstolog = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("do not write ed2k:// links to logfile"),
	                              tooltips,
	                              _("Output ed2k links only to the status window, but not to the logfile"),
	                              1, 2 );

	cb_restartcrashedcore = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("try to restart crashed core"),
	                              tooltips,
	                              _("Try to spawn a new donkey core process in case of a core crash."),
	                              1, 3 );

	cb_slowcon = misc_gtk_attach_new_check_button_to_table ( guiopt_general_table,
	                              _("minimise core-gui transfers"),
	                              tooltips,
	                              _("Set this TRUE if you are controlling the core from a slow network connection.\n"
	                                "It will reduce the transfers between the core and the gui to a minimum."),
	                              1, 4 );

	return guiopt_general_frame;
}

/* options_page_make_page1_frame
 *
 *
 */

static GtkWidget *
options_page_make_page1_frame (GtkTooltips *tooltips)
{
	GtkWidget *guiopt_vbox;
	GtkWidget *vbox7;
	GtkWidget *scrollwin;

	guiopt_vbox = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (guiopt_vbox);

	vbox7 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox7);
	gtk_box_pack_start (GTK_BOX (vbox7), guiopt_vbox, TRUE, TRUE, 5);
	gtk_container_set_border_width (GTK_CONTAINER(vbox7),5);

	/*********** get GUI General frame        **********/
	gtk_box_pack_start (GTK_BOX (guiopt_vbox), options_page_make_guigeneral_frame(tooltips), TRUE, TRUE, 0);

	/*********** get GUI Look and Feel frame  **********/
	gtk_box_pack_start (GTK_BOX (guiopt_vbox), options_page_make_lookfeel_frame(tooltips), TRUE, TRUE, 5);

	scrollwin = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrollwin),
				GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	// now add whole frame to scrolled window
	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), vbox7);
	gtk_widget_show (scrollwin);

	return scrollwin;
}


/* options_page_make_page2_frame
 *
 *
 */

static GtkWidget *
options_page_make_page2_frame (GtkTooltips *tooltips)
{
	const gchar  *utf8;
	GtkWidget    *scrollwin;
	GtkWidget    *coreopt_vbox;
	GtkWidget    *coreopt_table;
	GtkWidget    *coreopt_frame;
	GtkWidget    *coreopt_frame_label;
	GtkWidget    *blanklabels[8];	/* 8 = number of ROWS */
	guint         row, rows = sizeof(blanklabels)/sizeof(GtkWidget*);

	utf8 = UTF8_SHORT_PRINTF (" <span size='large' weight='ultrabold'><b>\n%s\n</b></span> ", _(" Core options "));
	coreopt_frame_label = gtk_label_new (utf8);
	gtk_label_set_use_markup (GTK_LABEL (coreopt_frame_label), TRUE);
	gtk_widget_show (coreopt_frame_label);

	coreopt_frame = gtk_frame_new(NULL);
	gtk_frame_set_label_widget (GTK_FRAME (coreopt_frame), coreopt_frame_label);
	gtk_frame_set_shadow_type (GTK_FRAME (coreopt_frame), GTK_SHADOW_NONE);
	gtk_widget_show (coreopt_frame);
	gtk_container_set_border_width (GTK_CONTAINER(coreopt_frame),5);

	coreopt_vbox = gtk_vbox_new(TRUE, 0);
	gtk_widget_show (coreopt_vbox);
	gtk_container_add(GTK_CONTAINER(coreopt_frame), coreopt_vbox);
	coreopt_table = gtk_table_new (rows, 4, FALSE);
	gtk_box_pack_start(GTK_BOX(coreopt_vbox), coreopt_table, FALSE, TRUE, 5);
	gtk_widget_show (coreopt_table);

	/* make some empty labels in the last column so the entry widget field is not massively big */
	for (row=0; row<rows; row++)
	{
		blanklabels[row] = gtk_label_new ("     ");
		gtk_widget_show (blanklabels[row]);
		gtk_table_attach (GTK_TABLE (coreopt_table), blanklabels[row], 2, 3, row, row+1,
					(GtkAttachOptions) (GTK_FILL),
					(GtkAttachOptions) (0), 3, 0);
	}

	ew_nickname = options_page_add_entry_to_table(coreopt_table, _(" nickname "), 0, NULL, tooltips);

	spinbutton_maxdlspeed = options_page_add_spinbutton_to_table(coreopt_table, _(" max download speed "),
		0.0, 0.0, 99999.0, 1.0, 1,
		_("The maximum speed with which you want the donkey to download, in kB/s. 0=no limit. "
			 "Note: The donkey has a ratio system. If you specify less than "
			 "10kB/s as max.upload speed, then your "
			 "download will be limited according to some fixed factor. "
			 "(Also: 1 kB/s = 8kbit/s. Line speeds are usually advertised in kbit/s, "
			 "so you need to divide by 8 to get your line speed in kB/s)"), tooltips
	);
	
	spinbutton_maxulspeed = options_page_add_spinbutton_to_table(coreopt_table, _(" max upload speed"),
		0.0, 0.0, 99999.0, 0.5, 2,
		_("The maximum speed with which you want the donkey to upload in kB/s. "
		 "You should set this to at least 20kB/s if you have a fast line, otherwise your "
		 "max. download speed will be limited. You should not set this value higher than "
		 "your upload line speed minus 3kB/s. "
		 "(Note: 1 kB/s = 8kbit/s. Line speeds are usually advertised in kbit/s, "
		 "so you need to divide by 8 to get your line speed in kB/s)"), tooltips
	);
	
	gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinbutton_maxdlspeed), 1);
	gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinbutton_maxulspeed), 1);

	ew_incoming = options_page_add_entry_to_table(coreopt_table, _(" incoming dir"), 3, NULL, tooltips);

	ew_temporary = options_page_add_entry_to_table(coreopt_table, _(" temp dir"), 4, NULL, tooltips);

	spinbutton_maxcon = options_page_add_spinbutton_to_table(coreopt_table, _(" max connections "),
		50.0, 50.0, 8192.0, 5.0, 5,
		_("The maximum number of sockets the donkey should use at any given time. "
			"Don't set this value too low! Try something between 350-500 and lower the "
			"value in case you get problems with your router (if you have one)."), tooltips
	);

	spinbutton_port = options_page_add_spinbutton_to_table(coreopt_table, _(" port for other clients "),
		0.0, 1.0, 65535.0, 1.0, 6, _("The port the core listens on for other clients."), tooltips
	);

	spinbutton_adminport = options_page_add_spinbutton_to_table(coreopt_table, _(" port for controllers/gui "),
		0.0, 1.0, 65535.0, 1.0, 7, _("The port the core listens on for a GUI."), tooltips
	);

	scrollwin = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrollwin),
				GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	// now add whole frame to scrolled window
	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), coreopt_frame);
	gtk_widget_show (scrollwin);

  return scrollwin;
}


/* options_page_make_page3_frame
 *
 *
 */

static GtkWidget *
options_page_make_page3_frame (GtkTooltips *tooltips)
{
	GtkWidget   *coreopt_vbox;
	GtkWidget   *coreopt_table;
	GtkWidget   *coreopt_frame;
	GtkWidget   *coreopt_frame_label;
	GtkWidget   *blanklabels[11];	/* 10 = number of ROWS */
	GtkWidget   *scrollwin;
	const gchar *utf8;
	guint        row, rows = sizeof(blanklabels)/sizeof(GtkWidget*);

	utf8 = UTF8_SHORT_PRINTF (" <span size='large' weight='ultrabold'><b>\n%s\n</b></span> ", _(" More GUI options "));
	coreopt_frame_label = gtk_label_new (utf8);
	gtk_label_set_use_markup (GTK_LABEL (coreopt_frame_label), TRUE);
	gtk_widget_show (coreopt_frame_label);

	coreopt_frame = gtk_frame_new(NULL);
	gtk_frame_set_label_widget (GTK_FRAME (coreopt_frame), coreopt_frame_label);
	gtk_frame_set_shadow_type (GTK_FRAME (coreopt_frame), GTK_SHADOW_NONE);
	gtk_widget_show (coreopt_frame);
	gtk_container_set_border_width (GTK_CONTAINER(coreopt_frame),5);

	coreopt_vbox = gtk_vbox_new(TRUE, 0);
	gtk_widget_show (coreopt_vbox);
	gtk_container_add(GTK_CONTAINER(coreopt_frame), coreopt_vbox);
	coreopt_table = gtk_table_new (rows, 4, FALSE);
	gtk_box_pack_start(GTK_BOX(coreopt_vbox), coreopt_table, FALSE, TRUE, 5);
	gtk_widget_show (coreopt_table);

	/* make some empty labels in the last column so the entry widget field is not massively big */
	for (row=0; row<rows; row++)
	{
		blanklabels[row] = gtk_label_new ("     ");
		gtk_widget_show (blanklabels[row]);
		gtk_table_attach (GTK_TABLE (coreopt_table), blanklabels[row], 2, 3, row, row+1,
					(GtkAttachOptions) (GTK_FILL),
					(GtkAttachOptions) (0), 3, 0);
	}

	gtk_widget_show(coreopt_frame);

	spinbutton_serverrotate = options_page_add_spinbutton_to_table(coreopt_table, _(" server rotation interval "),
		0.0, 0.0, 1440.0, 5.0, 4,
		_("Reconnect to another server after this many minutes (0=never). Minimum is 30 minutes."), tooltips
	);

	ew_slistURL = options_page_add_entry_to_table(coreopt_table, _(" url to favorite html serv-list "),  5, NULL, tooltips);
	ew_slistURL2 = options_page_add_entry_to_table(coreopt_table, _(" url to secondary html serv-list "), 6, NULL, tooltips);
	ew_completecommand = options_page_add_entry_to_table(coreopt_table, _(" post-download command "), 7,
		_("Shell command that will be executed whenever a download is complete. "
		"The GUI will export the filename in the variable $ED2K_FN and the incoming directory "
		"in the variable $ED2K_IN"), tooltips
	);

	spinbutton_clearswin = options_page_add_spinbutton_to_table(coreopt_table, _(" clear status window interval"),
		0.0, 0.0, 1440.0, 5.0, 8,
		_("Automatically clear the status log window after this many minutes (0=never)."), tooltips
	);

	spinbutton_minfreespace = options_page_add_spinbutton_to_table(coreopt_table, _(" stop if free temp space is less than x MB"),
		0.0, 0.0, 9999.0, 0.0, 10,
		_("Pauses all downloads if there is less than x MegaBytes of free space on the temp folder partition (0=ignore)."),
		tooltips
	);

	scrollwin = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrollwin),
				GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	// now add whole frame to scrolled window
	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), coreopt_frame);
	gtk_widget_show (scrollwin);

  return scrollwin;
}


/******************************************************************************
 *
 *   options_register_linkhandler_button_callback
 *
 */

static void
options_register_linkhandler_button_callback (GtkWidget *widget, gpointer data)
{
	const gchar *errmsg = NULL;
	const gchar *env = NULL;

	switch (GPOINTER_TO_UINT(data))
	{
		case OPTIONS_LINKHANDLER_INSTALL_KDE_HANDLER:
		{
			errmsg = linkhandler_install_kde();
			env = "KDE";
		}
		break;

		case OPTIONS_LINKHANDLER_INSTALL_GNOME1_HANDLER:
		{
			errmsg = linkhandler_install_gnome1();
			env = "Gnome 1";
		}
		break;

		case OPTIONS_LINKHANDLER_INSTALL_GNOME2_HANDLER:
		{
			errmsg = linkhandler_install_gnome2();
			env = "Gnome 2";
		}
		break;
		
		case OPTIONS_LINKHANDLER_INSTALL_WINDOWS_HANDLER:
		{
			errmsg = linkhandler_install_windows();
			env = "Windows";
		}
		break;

		case OPTIONS_LINKHANDLER_INSTALL_MOZILLA_HANDLER:
		{
			misc_gtk_ok_dialog (GTK_MESSAGE_INFO, 
			                    _("Currently it is not possible to automatically install "
			                      "ed2k-gtk-gui as the program that handles ed2k:// links "
			                      "with the Mozilla or Firefox Web Browsers.\n\n"
			                      "However, you can easily configure this yourself:\n"
			                      "  1. start Mozilla or Firefox\n"
			                      "  2. type 'about:config' into the location bar at the top\n"
			                      "  3.  right click on the list and select New -> String\n"
			                      "  4. in the dialog that pops up, type\n"
			                      "      'network.protocol-handler.app.ed2k'\n" 
			                      "  5. press OK\n"
			                      "  6. in the next dialog type 'ed2k_gui'\n" 
			                      "  7. press OK\n"
			                      "\n"
			                      "Now you should be able to send ed2k:// links directly to "
			                      "ed2k-gtk-gui when you click on them in Mozilla or Firefox."));
		}
		return; /* sic! */

		default: errmsg = "invalid case value in options_register_linkhandler_button_callback()!";
	}

	if (!errmsg)
	{
		gchar *msg = g_strdup_printf (_(" ed2k-link handler for %s installed successfully. "), env);

		misc_gtk_ok_dialog (GTK_MESSAGE_INFO, msg);

		G_FREE(msg);
	}
	else
	{
		gchar *msg = g_strdup_printf ( "\n%s%s:\n\n%s\n",
		                               _(" An error occured while trying to install an ed2k-link handler for "),
		                               env, errmsg);

		misc_gtk_ok_dialog (GTK_MESSAGE_WARNING, msg);

		G_FREE(msg);
	}
}



/******************************************************************************
 *
 *   options_page_make_linkhandler_options_frame
 *
 *   creates the frame with the linkhandler options
 *
 */

static GtkWidget *
options_page_make_linkhandler_options_frame (GtkTooltips *tooltips)
{
	GtkWidget *hbox;
	GtkWidget *label;
	GtkWidget *frame;

	hbox = gtk_hbox_new(FALSE, 5);
	gtk_widget_show (hbox);

	frame = gtk_frame_new(NULL);
	gtk_widget_show(frame);
	label = gtk_label_new (UTF8_SHORT_PRINTF("<i>%s</i>",_(" If no GUI is running...   ")));
	gtk_label_set_use_markup(GTK_LABEL(label),TRUE);
	gtk_widget_show(label);
	gtk_frame_set_label_widget (GTK_FRAME(frame), label);

	radio1_lh = gtk_radio_button_new_with_label(NULL, UTF8_SHORT_PRINTF("%s",_(" ask what to do ")));
	gtk_widget_show(radio1_lh);
	gtk_box_pack_start(GTK_BOX(hbox), radio1_lh, TRUE, TRUE, 5);

	radio2_lh = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(radio1_lh), UTF8_SHORT_PRINTF("%s",_(" start GUI ")));
	gtk_widget_show(radio2_lh);
	gtk_box_pack_start(GTK_BOX(hbox), radio2_lh, TRUE, TRUE, 5);

	radio3_lh = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(radio1_lh), UTF8_SHORT_PRINTF("%s",_(" silently remember link ")));
	gtk_widget_show(radio3_lh);
	gtk_box_pack_start(GTK_BOX(hbox), radio3_lh, TRUE, TRUE, 5);

	gtk_container_set_border_width(GTK_CONTAINER(frame),25);
	gtk_container_set_border_width(GTK_CONTAINER(hbox),10);
	gtk_container_add(GTK_CONTAINER(frame), hbox);

	return frame;
}

/******************************************************************************
 *
 *   options_page_make_linkhandler_page_frame
 *
 *   creates the link handler setup frame for the options page
 *
 */

static GtkWidget *
options_page_make_linkhandler_page_frame (GtkTooltips *tooltips)
{
	GtkWidget   *scrollwin, *vbox, *vbuttonbox,  *frame;
	GtkWidget   *framelabel, *label, *emptylabel;
	const gchar *utf8_title;
	gchar       *utf8;

#if defined(G_OS_UNIX)
	GtkWidget   *kde_button, *gnome1_button, *gnome2_button, *moz_button;
	GtkWidget   *hbox1, *hbox2, *hbox3, *hbox4;
	GtkWidget   *kde_hbox, *kde_bbox, *gnome1_hbox, *gnome1_bbox, *gnome2_hbox, *gnome2_bbox;
	GtkWidget   *moz_hbox, *moz_bbox;
#elif defined(G_OS_WIN32)
	GtkWidget   *win_button;
	GtkWidget   *hbox1;
	GtkWidget   *win_hbox, *win_bbox;
#endif


	utf8_title = UTF8_SHORT_PRINTF("\n<span size='large' weight='ultrabold'><b>%s\n</b></span> ",
	                                _(" ed2k-link handler "));
	framelabel = gtk_label_new (utf8_title);
	gtk_label_set_use_markup (GTK_LABEL (framelabel), TRUE);
	gtk_widget_show (framelabel);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_label_widget (GTK_FRAME (frame), framelabel);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
	gtk_widget_show (frame);
	gtk_container_set_border_width (GTK_CONTAINER(frame),15);

	scrollwin = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_show (scrollwin);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrollwin),
				GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), frame);

	vbox = gtk_vbox_new(FALSE,15);
	gtk_widget_show(vbox);
	gtk_container_add(GTK_CONTAINER(frame), vbox);

#if defined(G_OS_WIN32)
	utf8 = TO_UTF8(_(" You can make the GUI handle ed2k-links within Windows applications. Then you "
    "can just click on an ed2k-link in your browser, and the "
    "GUI will start downloading the file that this ed2k-link describes."));
#else
	utf8 = TO_UTF8(_(" You can make the GUI handle ed2k-links within KDE and GNOME applications. Then you "
    "can just click on an ed2k-link in your browser, and the "
    "GUI will start downloading the file that this ed2k-link describes. This works "
    "with some browsers (Konqueror, Galeon, Epiphany, Mozilla, Firefox) "
    "but not with others (Opera). "));
#endif

	label = gtk_label_new(utf8);
    gtk_misc_set_alignment (GTK_MISC (label), 0.1, 0.5);
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
    gtk_widget_show(label);
    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 10);


	gtk_box_pack_start(GTK_BOX(vbox), options_page_make_linkhandler_options_frame(tooltips), FALSE, FALSE, 5);

	vbuttonbox = gtk_vbox_new(FALSE, 15);
	gtk_widget_show (vbuttonbox);

	gtk_box_pack_start (GTK_BOX (vbox), vbuttonbox, TRUE, TRUE, 0);

#if defined(G_OS_UNIX)
	hbox1 = gtk_hbox_new(FALSE, 15);
	gtk_box_pack_start(GTK_BOX(vbuttonbox), hbox1, TRUE, TRUE, 10);

	kde_hbox =  make_icon_and_label_hbox(_(" Install ed2k:// link handler for KDE "), ICON_SYS_KDE);
	gtk_widget_show(kde_hbox);

	gtk_box_pack_start(GTK_BOX(hbox1), kde_hbox, TRUE, TRUE, 50);
	kde_bbox = gtk_hbutton_box_new();
	emptylabel = gtk_label_new(" ");
	gtk_widget_show(emptylabel);
	gtk_box_pack_start(GTK_BOX(hbox1), kde_bbox, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(hbox1), emptylabel, FALSE, FALSE, 10);

	gtk_widget_show(kde_bbox);

	new_button_pack_and_signal_connect(&kde_button, kde_bbox, _(" Install "),
			options_register_linkhandler_button_callback,
			GUINT_TO_POINTER(OPTIONS_LINKHANDLER_INSTALL_KDE_HANDLER), 1);


	hbox2 = gtk_hbox_new(FALSE, 15);
	gtk_box_pack_start(GTK_BOX(vbuttonbox), hbox2, TRUE, TRUE, 10);

	gnome1_hbox =  make_icon_and_label_hbox(_(" Install ed2k:// link handler for GNOME 1 "), ICON_SYS_GNOME1);
	gtk_widget_show(gnome1_hbox);

	gtk_box_pack_start(GTK_BOX(hbox2), gnome1_hbox, TRUE, TRUE, 50);
	gnome1_bbox = gtk_hbutton_box_new();
	emptylabel = gtk_label_new(" ");
	gtk_widget_show(emptylabel);
	gtk_box_pack_start(GTK_BOX(hbox2), gnome1_bbox, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(hbox2), emptylabel, FALSE, FALSE, 10);
	gtk_widget_show(gnome1_bbox);


	new_button_pack_and_signal_connect (
		&gnome1_button,
		gnome1_bbox,
		_(" Install "),
		options_register_linkhandler_button_callback,
		GUINT_TO_POINTER(OPTIONS_LINKHANDLER_INSTALL_GNOME1_HANDLER),
		1
	);

	hbox3 = gtk_hbox_new(FALSE, 15);
	gtk_box_pack_start(GTK_BOX(vbuttonbox), hbox3, TRUE, TRUE, 10);

	gnome2_hbox =  make_icon_and_label_hbox(_(" Install ed2k:// link handler for GNOME 2 "), ICON_SYS_GNOME2);
	gtk_widget_show(gnome2_hbox);

	gtk_box_pack_start(GTK_BOX(hbox3), gnome2_hbox, TRUE, TRUE, 50);
	gnome2_bbox = gtk_hbutton_box_new();
	gtk_widget_show(gnome2_bbox);
        
	emptylabel = gtk_label_new(" ");
	gtk_widget_show(emptylabel);
	gtk_box_pack_start(GTK_BOX(hbox3), gnome2_bbox, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(hbox3), emptylabel, FALSE, FALSE, 10);


	new_button_pack_and_signal_connect (
		&gnome2_button,
		gnome2_bbox,
		_(" Install "),
		options_register_linkhandler_button_callback,
		GUINT_TO_POINTER(OPTIONS_LINKHANDLER_INSTALL_GNOME2_HANDLER),
		1
	);

	hbox4 = gtk_hbox_new (FALSE, 15);
	gtk_box_pack_start (GTK_BOX (vbuttonbox), hbox4, TRUE, TRUE, 10);

	moz_hbox =  make_icon_and_label_hbox (_(" Install ed2k:// link handler for the Mozilla or Firefox Web Browser "), ICON_SYS_MOZILLA);
	gtk_widget_show (moz_hbox);

	gtk_box_pack_start (GTK_BOX (hbox4), moz_hbox, TRUE, TRUE, 50);
	moz_bbox = gtk_hbutton_box_new ();
	gtk_widget_show (moz_bbox);
        
	emptylabel = gtk_label_new(" ");
	gtk_widget_show (emptylabel);
	gtk_box_pack_start (GTK_BOX (hbox4), moz_bbox, FALSE, FALSE, 5);
	gtk_box_pack_start (GTK_BOX (hbox4), emptylabel, FALSE, FALSE, 10);


	new_button_pack_and_signal_connect (
		&moz_button,
		moz_bbox,
		_(" Install "),
		options_register_linkhandler_button_callback,
		GUINT_TO_POINTER (OPTIONS_LINKHANDLER_INSTALL_MOZILLA_HANDLER),
		1
	);

	gtk_widget_show(hbox1);
	gtk_widget_show(hbox2);
	gtk_widget_show(hbox3);
	gtk_widget_show(hbox4);
#elif defined(G_OS_WIN32)
	hbox1 = gtk_hbox_new(FALSE, 15);
	gtk_box_pack_start(GTK_BOX(vbuttonbox), hbox1, TRUE, TRUE, 10);

	win_hbox =  make_icon_and_label_hbox(_(" Install ed2k:// link handler for Windows "), ICON_SYS_WINDOWS);
	gtk_widget_show(win_hbox);

	gtk_box_pack_start(GTK_BOX(hbox1), win_hbox, TRUE, TRUE, 50);
	win_bbox = gtk_hbutton_box_new();
	emptylabel = gtk_label_new(" ");
	gtk_widget_show(emptylabel);
	gtk_box_pack_start(GTK_BOX(hbox1), win_bbox, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(hbox1), emptylabel, FALSE, FALSE, 10);

	gtk_widget_show(win_bbox);

	new_button_pack_and_signal_connect(&win_button, win_bbox, _(" Install "),
			options_register_linkhandler_button_callback,
			GUINT_TO_POINTER(OPTIONS_LINKHANDLER_INSTALL_WINDOWS_HANDLER), 1);
			
	gtk_widget_show(hbox1);
#endif

	FREE_UTF8(utf8);

	return scrollwin;
}



/* options_page_create
 *
 * (new version by Axel C)
 *
 *
 */

GtkWidget *
options_page_create (void)
{
	GtkWidget *vbox5;
	GtkWidget *opt_buttonbox;
	GtkWidget *ok_button;
	GtkWidget *cancel_button;
	GtkWidget *refresh_button;
	GtkWidget *vbox6;
	GtkWidget *notebook1;
	GtkWidget *label61;
	GtkWidget *label62;
	GtkWidget *label999;
	GtkWidget *label_linkhandler;
	GtkTooltips *tooltips;

	/* To keep track of the number of downloads */
	g_signal_connect(core, "core-options",    (GCallback) onCoreOptions,    NULL);
	g_signal_connect(core, "new-download",    (GCallback) onNewDownload,    NULL);
	g_signal_connect(core, "remove-download", (GCallback) onRemoveDownload, NULL);

	tooltips = gtk_tooltips_new();

	vbox5 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox5);

	opt_buttonbox = gtk_hbutton_box_new ();
	gtk_widget_show (opt_buttonbox);
	gtk_box_pack_end (GTK_BOX (vbox5), opt_buttonbox, FALSE, TRUE, 10);
	gtk_button_box_set_layout (GTK_BUTTON_BOX (opt_buttonbox), GTK_BUTTONBOX_END);
	gtk_box_set_spacing (GTK_BOX (opt_buttonbox), 5);

	// TODO: XXX: this should be an 'apply' button and not an 'ok' button.
	//            also: use STOCK buttons.
	new_icon_button_pack_and_signal_connect(&ok_button, opt_buttonbox, _(" OK "), options_ok_button_clicked, NULL, 1,
					ICON_OK);

	new_icon_button_pack_and_signal_connect(&cancel_button, opt_buttonbox, _(" Cancel "), options_cancel_button_clicked, NULL, 1,
					ICON_CANCEL);
	new_icon_button_pack_and_signal_connect(&refresh_button, opt_buttonbox, _(" Refresh "), options_refresh_button_clicked, NULL, 1,
					ICON_REFRESH);

	vbox6 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox6);
	gtk_box_pack_start (GTK_BOX (vbox5), vbox6, TRUE, TRUE, 0);

	notebook1 = gtk_notebook_new ();
	gtk_widget_show (notebook1);
	gtk_container_add (GTK_CONTAINER (vbox6), notebook1);
	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook1), GTK_POS_LEFT);

	/********** get page 1 frame (GUI I) *******************/
	gtk_container_add (GTK_CONTAINER (notebook1), options_page_make_page1_frame(tooltips));

	/********** get page 3 frame (GUI II) ******************/
	gtk_container_add (GTK_CONTAINER (notebook1), options_page_make_page3_frame(tooltips));

	/********** get next frame (linkhandler)  *******************/
	gtk_container_add (GTK_CONTAINER (notebook1), options_page_make_linkhandler_page_frame(tooltips));

	/********** get page 2 frame (CORE)  *******************/
	gtk_container_add (GTK_CONTAINER (notebook1), options_page_make_page2_frame(tooltips));

	label61 = make_icon_and_label_hbox(_(" GUI 1 "), ICON_CONFIGURE);
	gtk_widget_show (label61);
	gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label61);
//	gtk_label_set_justify (GTK_LABEL (label61), GTK_JUSTIFY_LEFT);

	label999 = make_icon_and_label_hbox(_(" GUI 2 "), ICON_CONFIGURE);
	gtk_widget_show (label999);
	gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label999);
//	gtk_label_set_justify (GTK_LABEL (label999), GTK_JUSTIFY_LEFT);

	label_linkhandler = make_icon_and_label_hbox(_(" GUI 3 "), ICON_CONFIGURE);
	gtk_widget_show(label_linkhandler);
	gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), label_linkhandler);

	label62 = make_icon_and_label_hbox(_(" Core "), ICON_CONFIGURE);
	gtk_widget_show (label62);
	gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 3), label62);
//	gtk_label_set_justify (GTK_LABEL (label62), GTK_JUSTIFY_LEFT);

	g_signal_connect(core, "core-conn-status", (GCallback) onCoreConnStatus, NULL);

	return vbox5;
}

