/* $Id: e2_select_image_dialog.c 891 2008-05-20 06:57:09Z tpgww $

Copyright (C) 2003-2008 tooar <tooar@gmx.net>

This file is part of emelFM2.
emelFM2 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 3, or (at your option)
any later version.

emelFM2 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 emelFM2; see the file GPL. If not, contact the Free Software
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

/**
@file src/dialogs/e2_select_image_dialog.c
@brief Select image dialog

This file contains all functions needed to create a select-image
dialog, which is opened when an icon is clicked on a tree-option
page in the main configuration dialog
*/

#include "emelfm2.h"
#include <string.h>
#include "e2_dialog.h"
#include "e2_select_image_dialog.h"
#include "e2_config_dialog.h"

static gchar *_e2_sidlg_get_icon_dir (E2_SID_Runtime *rt);
static void	_e2_sidlg_fill_custom_store (VPATH *localpath, E2_SID_Runtime *rt);
static gint _e2_sidlg_show_current (gboolean checkboth, E2_SID_Runtime *rt);

static GtkWidget *rem_btn;
#ifdef E2_VFSTMP
   FIXME initial_dir needs to point to this at session start ?
static VPATH localpath;
#endif
static VPATH *initial_dir;	//for custom icons, not cleared at session end

  /*********************/
 /***** callbacks *****/
/*********************/

/**
@brief setup object properties so it's possible to determine the currently selected icon or file

@param dialog the sid-dialog where the response was triggered
@param response the response for the clicked button
@param rt pointer to data for sid-dialog

@return
*/
static void _e2_sidlg_response_cb (GtkDialog *dialog, gint response, E2_SID_Runtime *rt)
{
	GtkTreePath *tpath;
	GList *selected;

	selected = (rt->page == 0) ?
		gtk_icon_view_get_selected_items (rt->customview):
		gtk_icon_view_get_selected_items (rt->stockview);

	if (selected != NULL)
		tpath = (GtkTreePath *)selected->data;	//single-mode selection means at most, 1 item
	else
		tpath = NULL;	//warning prevention only

	if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
	{
		if (rt->page == 0)
		{	//working with a custom icon
			if (selected != NULL)
			{
				GtkTreeIter iter;
				gchar *fullname;
				gtk_tree_model_get_iter (rt->custommodel, &iter, tpath);
				gtk_tree_model_get (rt->custommodel, &iter, 2, &fullname, -1);
				g_object_set_data_full (G_OBJECT (dialog), "image", fullname,
					(GDestroyNotify) g_free);
			}
			else //signal that this is one to ignore
				g_object_set_data (G_OBJECT (dialog), "image", NULL);
		}
		else
		{	//working with a stock icon
			if (selected != NULL)
			{
				GtkTreeIter iter;
				gchar *icon, *fullname;
				gtk_tree_model_get_iter (rt->stockmodel, &iter, tpath);
				gtk_tree_model_get (rt->stockmodel, &iter, 0, &icon, -1);
				fullname = g_strconcat ("gtk-", icon, NULL);
				g_object_set_data_full (G_OBJECT (dialog), "image", fullname,
					(GDestroyNotify) g_free);
				g_free (icon);
			}
			else
				g_object_set_data (G_OBJECT (dialog), "image", NULL);
		}
	}
	else if (response == E2_RESPONSE_REMOVE)
	{
		g_object_set_data_full (G_OBJECT (dialog), "image", g_strdup (""),
			(GDestroyNotify) g_free);
		if (selected != NULL)
			gtk_icon_view_unselect_path (
				(rt->page == 0) ? rt->customview : rt->stockview, tpath);
	}
	else //some other response
		g_object_set_data (G_OBJECT (dialog), "image", NULL); //ignore it

	if (selected != NULL)
	{
		gtk_tree_path_free (tpath);
		g_list_free (selected);
	}

	gtk_widget_set_sensitive (rem_btn, (response != E2_RESPONSE_REMOVE));
}
/**
@brief issue ok response for @a dialog
This is a callback for item-activated signal in stock-icons view

@param iconview the object where the activation occurred
@param path treepath of the activated item
@param dialog the parent dialog widget

@return
*/
static void _e2_sidlg_activated_cb (GtkIconView *iconview, GtkTreePath *path,
	GtkWidget *dialog)
{
	gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
}
/**
@brief notebook page-switch callback

@param notebook the object whose page changed
@param page UNUSED the notebook page which is now focused
@param page_num index of the new page
@param rt pointer to data for sid-dialog

@return
*/
static void _e2_sidlg_page_switch_cb (GtkNotebook *notebook, GtkNotebookPage *page,
		guint page_num, E2_SID_Runtime *rt)
{
	rt->page = page_num;
	gtk_widget_set_sensitive (rt->dir_chooser, (page_num == 0));
}
/**
@brief cleanup sid-dialog data

@param dialog
@param rt pointer to data for sid-dialog

@return
*/
static void _e2_sidlg_destroy_cb (GtkWidget *dialog, E2_SID_Runtime *rt)
{
	g_object_set_data (G_OBJECT (rt->parent), rt->name, NULL);
	g_free (rt->name);
	g_free (rt->icon);
	DEALLOCATE (E2_SID_Runtime, rt);
}
/**
@brief destroy sid-dialog

@param rt pointer to data for sid-dialog

@return
*/
static void _e2_sidlg_destroy_cb2 (E2_SID_Runtime *rt)
{
	gtk_widget_destroy (rt->dialog);
}
/**
@brief change custom icons directory

@param chooser the selection object
@param rt pointer to data for sid-dialog

@return
*/
static void _e2_sidlg_dir_change_cb (GtkFileChooser *chooser, E2_SID_Runtime *rt)
{
	gchar *uri = gtk_file_chooser_get_uri (chooser);
	if (uri != NULL)
	{
		gchar *dirpath = g_filename_from_uri (uri, NULL, NULL);
		if (dirpath != NULL)
		{
			gtk_list_store_clear (GTK_LIST_STORE (rt->custommodel));
#ifdef E2_VFSTMP
			VPATH local;
			local.localpath = dirpath;
			local.spacedata = ?;
			_e2_sidlg_fill_custom_store (&VPATH, rt);
#else
			_e2_sidlg_fill_custom_store (dirpath, rt);
#endif
			//show the relevant icon, if any
			_e2_sidlg_show_current (FALSE, rt);
			//remember for next session
			if (VPSTR (initial_dir) != NULL)
				g_free (VPSTR (initial_dir));
			initial_dir = dirpath;
		}
		g_free (uri);
	}
}

  /*****************/
 /***** utils *****/
/*****************/

/**
@brief get the appropriate directory for icons

@param rt pointer to data for sid-dialog

@return newly-allocated string with the path to use, localised with trailing /
*/
static gchar *_e2_sidlg_get_icon_dir (E2_SID_Runtime *rt)
{
	gboolean useiconpath;
	gchar *iconpath, *freeme;
	gpointer dtype = g_object_get_data (G_OBJECT (rt->parent), "dialog-form");
	if (GPOINTER_TO_INT (dtype) == E2_CFGDLG_SINGLE)
	{	//doing a single-page dialog
		iconpath = e2_utils_get_icons_path (TRUE);
	}
	else
	{	//doing a full config dialog
		//so a relevant option may have been changed in this session
		E2_OptionSet *set = e2_option_get ("use-icon-dir");

		if (set->widget != NULL)	//this option is part of the dialog
			useiconpath = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (set->widget));
		else
			useiconpath = e2_option_bool_get_direct (set);
		if (useiconpath)
		{
			set = e2_option_get ("icon-dir");
			if (set->widget != NULL)
			{
				freeme = gtk_editable_get_chars (GTK_EDITABLE (set->widget), 0, -1);
				iconpath = D_FILENAME_TO_LOCALE (freeme);
				g_free (freeme);
				if (!g_str_has_suffix (iconpath, G_DIR_SEPARATOR_S))
				{
					freeme = iconpath;
					iconpath = g_strconcat (freeme, G_DIR_SEPARATOR_S, NULL);
					g_free (freeme);
				}
			}
			else
				iconpath = g_strdup (ICON_DIR G_DIR_SEPARATOR_S);	//localised
		}
		else
			iconpath = g_strdup (ICON_DIR G_DIR_SEPARATOR_S);
	}

	return iconpath;
}

/**
@brief fill liststore for custom icons

@param localpath pointer to icons-directory path data
@param rt pointer to data for sid-dialog

@return
*/
static void	_e2_sidlg_fill_custom_store (VPATH *localpath, E2_SID_Runtime *rt)
{
	GList *entries;
	//get all files
	entries = (GList *)e2_fs_dir_foreach (localpath,
					E2_DIRWATCH_NO,	//assume local icons, so fast read
					NULL, NULL, NULL E2_ERR_NONE());
	if (!E2DREAD_FAILED (entries))
	{
		GList *member;
		gint w, h;
		GtkSettings *s = gtk_settings_get_default ();
		if (!gtk_icon_size_lookup_for_settings (s, GTK_ICON_SIZE_LARGE_TOOLBAR, &w, &h))
		{
			w = h = 18;	//can't find useful size, use this default
		}

		GtkListStore *store = GTK_LIST_STORE (rt->custommodel);
		for (member = entries; member != NULL; member = g_list_next (member))
		{
			GtkTreeIter iter;
			gchar *fullpath;
			GdkPixbuf *pix;
			 //CHECKME encoding
			fullpath = g_build_filename (VPSTR(localpath), (gchar*) member->data, NULL);
			pix = gdk_pixbuf_new_from_file_at_scale (fullpath, w, h, TRUE, NULL);
			if (pix != NULL)
			{
				gtk_list_store_insert_with_values (store, &iter, -1,
						0, (gchar*) member->data,
						1, pix,
						2, fullpath, //CHECKME encoding
						-1);
			}
			g_free (fullpath);
		}
		g_list_foreach (entries, (GFunc) g_free, NULL);
		g_list_free (entries);
	}
}
/**
@brief create and fill liststore for custom icons

@param rt pointer to data for sid-dialog

@return the store
*/
static GtkListStore *_e2_sidlg_create_custom_store (E2_SID_Runtime *rt)
{
	//store with columns for basename, pixbuf, fullpath CHECKME nama and path encoding ?
	GtkListStore *store = gtk_list_store_new (3,
		G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING);

	rt->custommodel = GTK_TREE_MODEL (store);	//the filler wants this
	//FIXME populate this lot of icons at idle, if the current icon is not custom
	gchar *path = _e2_sidlg_get_icon_dir (rt);
#ifdef E2_VFS
	VPATH localpath;
	localpath.localpath = path;
	localpath.spacedata = NULL;	//local icon files
	_e2_sidlg_fill_custom_store (&localpath, rt);
#else
	_e2_sidlg_fill_custom_store (path, rt);
#endif
	g_free (path);

	return store;
}

/**
@brief idle callback to populate stock icons view
@param store object in which to save icons' data

@return FALSE to terminate the source
*/
static gboolean _e2_sidlg_fill_stock_store (GtkListStore *store)
{
	GSList *ids = gtk_stock_list_ids ();
	if (ids != NULL)
	{
		GtkStyle *style = gtk_widget_get_style (app.main_window);
		GtkTextDirection dir = gtk_widget_get_direction (app.main_window);
		GSList *member;

		ids = g_slist_sort (ids, (GCompareFunc) strcmp);
		for (member = ids; member != NULL; member = g_slist_next (member))
		{
			GtkIconSet *iset = gtk_style_lookup_icon_set (style, (const gchar*) member->data);
			if (iset != NULL)
			{
				GdkPixbuf *pix = gtk_icon_set_render_icon (iset, style, dir,
							GTK_STATE_NORMAL, GTK_ICON_SIZE_LARGE_TOOLBAR, NULL, NULL);
				if (pix != NULL)
				{
					GtkTreeIter iter;
					gtk_list_store_insert_with_values (store, &iter, -1,
						0, (gchar*) member->data + 4,	//skip leading "gtk-"
						1, pix,
						-1);
					g_object_unref (G_OBJECT (pix));
				}
			}
			g_free (member->data);
		}
		g_slist_free (ids);
	}
	return FALSE;
}

/**
@brief create empty liststore for all gtk stock icons

@return the store
*/
static GtkListStore *_e2_sidlg_create_stock_store (void)
{
	GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, GDK_TYPE_PIXBUF);

	return store;
}

/**
@brief create scrolled window showing stock icons

@param rt pointer to data for sid-dialog

@return
*/
static GtkWidget *_e2_sidlg_create_stock_icon_browser (E2_SID_Runtime *rt)
{
	GtkListStore *store = _e2_sidlg_create_stock_store ();
	rt->stockmodel = GTK_TREE_MODEL (store);
	rt->stockview = GTK_ICON_VIEW (gtk_icon_view_new_with_model (rt->stockmodel));
	g_object_unref (G_OBJECT (store));

	gtk_icon_view_set_text_column (rt->stockview, 0);
	gtk_icon_view_set_pixbuf_column (rt->stockview, 1);
	gtk_icon_view_set_item_width (rt->stockview, 100);	//FIXME relate width to font size
	gtk_icon_view_set_margin (rt->stockview, E2_PADDING);
//	gtk_icon_view_set_spacing (rt->stockview, E2_PADDING_XSMALL);
	gtk_icon_view_set_row_spacing (rt->stockview, E2_PADDING_SMALL);
	gtk_icon_view_set_column_spacing (rt->stockview, E2_PADDING_SMALL);

	g_signal_connect (G_OBJECT(rt->stockview), "item-activated",
		G_CALLBACK (_e2_sidlg_activated_cb), rt->dialog);

	GtkWidget *sw = e2_widget_get_sw_plain (GTK_POLICY_AUTOMATIC,
		GTK_POLICY_AUTOMATIC);

	gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (rt->stockview));
	//FIXME populate this lot of icons at idle, if the current icon is not stock
	//g_idle_add ((GSourceFunc)_e2_sidlg_fill_stock_store, store);
	_e2_sidlg_fill_stock_store (store);

	return sw;
}

/**
@brief create scrolled window showing stock icons

@param rt pointer to data for sid-dialog

@return
*/
static GtkWidget *_e2_sidlg_create_custom_icon_browser (E2_SID_Runtime *rt)
{
	GtkListStore *store = _e2_sidlg_create_custom_store (rt);
	rt->custommodel = GTK_TREE_MODEL (store);
	rt->customview = GTK_ICON_VIEW (gtk_icon_view_new_with_model (rt->custommodel));
	g_object_unref (G_OBJECT (store));

	gtk_icon_view_set_text_column (rt->customview, 0);
	gtk_icon_view_set_pixbuf_column (rt->customview, 1);
	gtk_icon_view_set_item_width (rt->customview, 80);	//FIXME relate width to font size
	gtk_icon_view_set_margin (rt->customview, E2_PADDING);
//	gtk_icon_view_set_spacing (rt->customview, E2_PADDING_XSMALL);
	gtk_icon_view_set_row_spacing (rt->customview, E2_PADDING);
	gtk_icon_view_set_column_spacing (rt->customview, E2_PADDING_SMALL);

	g_signal_connect (G_OBJECT(rt->customview), "item-activated",
		G_CALLBACK (_e2_sidlg_activated_cb), rt->dialog);

	GtkWidget *sw = e2_widget_get_sw_plain (GTK_POLICY_AUTOMATIC,
		GTK_POLICY_AUTOMATIC);

	gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (rt->customview));

	return sw;
}

/**
@brief initialize notebook page
This checks stored strings, so expects both icon liststores to be already full of
strings at least
Sets rt->page, but does NOT change the notebook page accordingly
@param checkboth TRUE to check stock items as well as others
@param rt pointer to data for sid-dialog

@return relevant notebook page no.
*/
static gint _e2_sidlg_show_current (gboolean checkboth, E2_SID_Runtime *rt)
{
	GtkTreeIter iter;
	if (checkboth
		&& gtk_tree_model_get_iter_first (rt->stockmodel, &iter)
		&& e2_tree_find_iter_from_str_simple (rt->stockmodel, 0,
				rt->icon + 4, //the stored data omits leading "gtk-"
				&iter, FALSE))
	{	//the selected item is a stock item
		//select & show the corresponding icon in the view
		GtkTreePath *path = gtk_tree_model_get_path (rt->stockmodel, &iter);
		if (path != NULL)
		{
			gtk_icon_view_set_cursor (rt->stockview, path, NULL, FALSE);
			gtk_icon_view_select_path (rt->stockview, path);
#ifdef USE_GTK2_8
			//older gtk just ensures visible
			gtk_icon_view_scroll_to_path (rt->stockview, path, TRUE, 0.5, 0.5);
#endif
			gtk_tree_path_free (path);
		}
		return 1;	//notebook page no.
	}
	else
	{ 	//the selected item is a custom-icon
		//point to the icon file, if possible
		if ((rt->icon != NULL) && (*rt->icon != '\0'))
		{
			//rt->icon has no path if the image file is in default dir, or it's a full path
			gint srchcol;

			if (g_path_is_absolute (rt->icon))
				srchcol = 2;	//look for full-path match
			else
				srchcol = 0;	//look for name match

			//CHECKME file/path encoding ?
			if (gtk_tree_model_get_iter_first (rt->custommodel, &iter)
				&& e2_tree_find_iter_from_str_simple (rt->custommodel, srchcol,
					rt->icon, &iter, FALSE))
			{
				GtkTreePath *path = gtk_tree_model_get_path (rt->custommodel, &iter);
				if (path != NULL)
				{
					gtk_icon_view_set_cursor (rt->customview, path, NULL, FALSE);
					gtk_icon_view_select_path (rt->customview, path);
#ifdef USE_GTK2_8
					//older gtk just ensures visible
					gtk_icon_view_scroll_to_path (rt->customview, path, TRUE, 0.5, 0.5);
#endif
					gtk_tree_path_free (path);
				}
			}
		}
		return 0;
	}
}

  /******************/
 /***** public *****/
/******************/

/**
@brief create icon-selection dialog

@param parent the main config-dialog widget
@param name dialog title string
@param icon gtk-stock-icon name, or path to icon file, taken from tree-option store
@param response_func callback function for all responses for this dialog
@param set pointer to data for the tree-option to which the dialog relates

@return the dialog widget, or NULL if error occurred
*/
GtkWidget *e2_sid_create (GtkWidget *parent, const gchar *name, gchar *icon,
	gpointer response_func, E2_OptionSet *set)
{
	//get or create and inititialize select image dialog runtime object and
	//ensure that only one runtime object (and only one dialog) exists
	//for every parent widget
	E2_SID_Runtime *rt = g_object_get_data (G_OBJECT (parent), name);
	//the user may have double-clicked on an icon, or ...
	if (rt != NULL && rt->dialog != NULL && GTK_WIDGET_VISIBLE (rt->dialog))
	{	//the dialog already exists
		printd (NOTICE, "select image dialog already exists");
		if (rt->icon != NULL)
			g_free (rt->icon);
		rt->icon = g_strdup (icon);
		//make dialog show the icon
		_e2_sidlg_show_current (TRUE, rt);
		//present the window
		gtk_window_present (GTK_WINDOW (rt->dialog));
		gtk_notebook_set_current_page (rt->notebook, rt->page);

		return rt->dialog;
	}
	else
	{
		printd (NOTICE, "creating select image dialog");
		rt = ALLOCATE0 (E2_SID_Runtime);
		CHECKALLOCATEDWARN (rt, return NULL;)
		//set up runtime object
		rt->name = g_strdup (name);
		//CHECKME can icon be absolute path ?
		rt->icon = g_strdup (icon);
		rt->parent = parent;
	}

	//create dialog widgets

	rt->dialog = e2_dialog_create (NULL, NULL, rt->name, _e2_sidlg_response_cb, rt);
	g_signal_connect (rt->dialog, "response", G_CALLBACK (response_func), set);
	//when the dialog is destroyed, free the runtime object
	g_signal_connect (rt->dialog, "destroy", G_CALLBACK (_e2_sidlg_destroy_cb), rt);
	//ensure this dialog is destroyed with the parent widget
	if (parent != NULL)
		g_object_set_data_full (G_OBJECT (parent), rt->name, rt,
			(GDestroyNotify) _e2_sidlg_destroy_cb2);

	if (VPSTR (initial_dir) != NULL && (e2_utils_get_modifiers () & GDK_CONTROL_MASK))
	{
		g_free (VPSTR (initial_dir));
		initial_dir = NULL;
	}
	if (initial_dir == NULL)
		initial_dir = _e2_sidlg_get_icon_dir (rt);

	//before any notebook page-switch cb, setup this button
	const gchar *message = _("Choose icons directory");
	rt->dir_chooser = gtk_file_chooser_button_new (message,
		GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
	gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (rt->dir_chooser), TRUE);
	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (rt->dir_chooser), initial_dir);
	g_signal_connect (G_OBJECT (rt->dir_chooser), "current-folder-changed",
		G_CALLBACK (_e2_sidlg_dir_change_cb), rt);
	gtk_widget_show (rt->dir_chooser);
#ifdef USE_GTK2_12TIPS
	gtk_widget_set_tooltip_text (
#else
	e2_widget_set_tooltip (NULL,
#endif
		rt->dir_chooser, message);

	//a notebook is used to change between the icon views
	rt->notebook = GTK_NOTEBOOK (e2_widget_add_notebook
		(GTK_DIALOG (rt->dialog)->vbox, TRUE, E2_PADDING, _e2_sidlg_page_switch_cb, rt));
	//the custom icon browser is a scrolled window
	GtkWidget *sw = _e2_sidlg_create_custom_icon_browser (rt);
	GtkWidget *label = gtk_label_new_with_mnemonic (_("_other"));
	gtk_notebook_append_page_menu (rt->notebook, sw, label, label);
	//and the stock icon browser is another scrolled window
	sw = _e2_sidlg_create_stock_icon_browser (rt);
	label = gtk_label_new_with_mnemonic (_("_stock"));
	gtk_notebook_append_page_menu (rt->notebook, sw, label, label);

	//decide the initial notebook page, icon, file, and remember page, that's
	//set to 0 in page-switch cb triggered in gtk_widget_show_all()
	gint page = _e2_sidlg_show_current (TRUE, rt);

	//we don't put the chooser in default action-area, that's always homogenous
	GtkWidget *bbox = gtk_hbox_new (FALSE, 0);
	GtkWidget *bbox2 = gtk_vbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (bbox), bbox2, FALSE, TRUE, 5);	//FIXME relate size to buttonbox padding
	gtk_box_pack_start (GTK_BOX (bbox2), rt->dir_chooser, TRUE, TRUE, 5);

	g_object_ref (G_OBJECT (GTK_DIALOG (rt->dialog)->action_area));
	gtk_container_remove (GTK_CONTAINER(GTK_DIALOG (rt->dialog)->vbox),
		GTK_DIALOG (rt->dialog)->action_area);
	gtk_box_pack_start (GTK_BOX (bbox), GTK_DIALOG (rt->dialog)->action_area, FALSE, FALSE, 0);
	g_object_unref (G_OBJECT (GTK_DIALOG (rt->dialog)->action_area));

	gtk_box_pack_end (GTK_BOX (GTK_DIALOG (rt->dialog)->vbox), bbox, FALSE, FALSE, 0);

	rem_btn = e2_dialog_add_defined_button (rt->dialog, &E2_BUTTON_REMOVE);
#ifdef USE_GTK2_12TIPS
	gtk_widget_set_tooltip_text (
#else
	e2_widget_set_tooltip (NULL,
#endif
		rem_btn, _("Remove the current icon"));
	if (*icon == '\0')	//nothing to remove at present
		gtk_widget_set_sensitive (rem_btn, FALSE);

	gtk_window_set_default_size (GTK_WINDOW (rt->dialog), -1, 350);
	e2_dialog_show (rt->dialog, rt->parent, 0,
		&E2_BUTTON_APPLY, &E2_BUTTON_CANCEL, &E2_BUTTON_OK, NULL); //sets notebook page to 0

	if (page != 0)
		gtk_notebook_set_current_page (rt->notebook, page);

	return rt->dialog;
}
