/* $Id: e2p_upgrade.c 853 2008-04-07 10:38:17Z tpgww $

Copyright (C) 2005-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 plugins/e2p_upgrade.c
@brief plugin for updating config files when a new emelFM2 version so requires

This file contains functions that help upgrading the default configuration
data file to the current version. Note that upgrading may also be needed for
imported config data - refer to the config plugin
*/

#include "emelfm2.h"
#include <string.h>
#include "e2_plugins.h"
#include "e2_option.h"
#include "e2_output.h"
#include "e2_dialog.h"
#include "e2_task.h"
#include "e2_complete.h"

static gboolean cancelled = FALSE;

static gchar *default_msg =
	N_("Configuration arrangements for this version %s of %s are considerably "
	"different from those of old versions. To reliably ensure access to the "
	"program's current features, it is best to start with fresh settings.\n"
	"If you proceed, the superseded configuration files in\n %s will have '.save' "
	"appended to their names.\nFeel free to delete them."
	);
#if 0
static gchar *option_msg =
	N_("Several default configuration settings of this version %s of %s"
	" are different from those of recent versions (see changelog).\n"
	"If you click OK, those settings will be updated where possible.\n"
	"Or else you can Cancel, and later, via the configuration dialog, manually"
	"change individual settings, or change all settings to current defaults."
	);
#endif //0
static void _e2p_upgrade_reconfig (void)
{
	//prevent attempts to clean non-existent backup data
	guint i;
	gpointer *walker;
	E2_OptionSet *set;
	for (i = 0, walker = options_array->pdata; i < options_array->len; i++, walker++)
	{
		set = *walker;
		if (set->type == E2_OPTION_TYPE_TREE)
			set->ex.tree.def = NULL;
	}
	//clear current option values
	e2_option_clear_data ();
	e2_option_default_register ();
	e2_option_file_read ();
}

//CHECKME assumes BGL is closed, native file only
static void _e2p_upgrade_backup (gchar *file)
{
	gchar *config_file = g_strdup_printf ("%s"G_DIR_SEPARATOR_S"%s",
		e2_cl_options.config_dir, file);
	gchar *local = F_FILENAME_TO_LOCALE (config_file);
#ifdef E2_VFS
	VPATH ddata = { local, NULL };
	if (e2_fs_access (&ddata, F_OK E2_ERR_NONE()) == 0)	//traverse link, if any
#else
	if (e2_fs_access (local, F_OK E2_ERR_NONE()) == 0)	//traverse link, if any
#endif
	{
		gchar *saved_file = g_strconcat (local, ".save", NULL);
		gdk_threads_leave ();	//downstream errors invoke local mutex locking
#ifdef E2_VFS
		VPATH sdata = { saved_file, NULL };
		e2_task_backend_rename (&ddata, &sdata);
#else
		e2_task_backend_rename (local, saved_file);
#endif
		gdk_threads_enter ();
		g_free (saved_file);
	}
	g_free (config_file);
	F_FREE (local);
}

static gint _e2p_upgrade_dialog (gchar *msg)
{
	//main button structs not created yet
	E2_Button E2P_BUTTON_OK =
		{ N_("_OK"),"",
#ifdef E2_IMAGECACHE
	//FIXME gtk images not yet available
		NULL,
#else
		GTK_STOCK_OK,
#endif
		NULL, E2_BTN_DEFAULT, E2_BTN_DEFAULT, GTK_RESPONSE_OK};
	E2_Button E2P_BUTTON_CANCEL =
		{ N_("_Cancel"),"",
#ifdef E2_IMAGECACHE
	//FIXME gtk images not yet available
		NULL,
#else
		GTK_STOCK_CANCEL,
#endif
		NULL, E2_BTN_DEFAULT, E2_BTN_DEFAULT, GTK_RESPONSE_CANCEL};

	GtkWidget *dialog = e2_dialog_create (
#ifdef E2_IMAGECACHE
	//FIXME gtk images not yet available
		NULL,
#else
		GTK_STOCK_DIALOG_INFO,
#endif
		msg, _("update information"), NULL, NULL);
	e2_dialog_show (dialog, NULL, 0,
		&E2P_BUTTON_CANCEL, &E2P_BUTTON_OK, NULL);
	gint choice = gtk_dialog_run (GTK_DIALOG (dialog));
	gtk_widget_destroy (dialog);
	cancelled = (choice != GTK_RESPONSE_OK);
	return choice;
}
//#if 0
static gchar *_e2p_upgrade_get_sed (void)
{
	gchar *sed = g_find_program_in_path ("sed");
	if (sed == NULL)
	{
		//FIXME should always warn the user about this
		printd (ERROR, "can't find 'sed' so i can't upgrade the config file");
		cancelled = TRUE;
	}
	return sed;
}
//#endif //0
#ifdef E2_VERSIONDOCS
static void _e2p_upgrade_numbers (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		gchar *localtmp = e2_utils_get_tempname (local);
		gchar *command = g_strconcat ("cp -f ", local, " ", localtmp, ".save;",
			sed, " -e '1s/", app.cfgfile_version, "/"VERSION RELEASE"/'",
				 " -e '2,$s/0\\.[0-9]\\.[0-9]/"VERSION"/'",
				 " ",localtmp,".save >",local,NULL);
		system (command);
		g_free (sed);
		g_free (cfg_file);
		F_FREE (local);
		g_free (localtmp);
		g_free (command);
	}
}
#endif
static void _e2p_upgrade_pre_0_1 (void)
{
	gchar *msg = g_strdup_printf (gettext (default_msg),
	VERSION, PROGNAME, e2_cl_options.config_dir);
	gint choice = _e2p_upgrade_dialog (msg);
	g_free (msg);

	if (choice == GTK_RESPONSE_OK)
	{
		_e2p_upgrade_backup ("config");
//		_e2p_upgrade_backup ("cache");  this one is ok to leave as is
		_e2p_upgrade_backup ("filetypes");
		_e2p_upgrade_backup ("plugins");
		_e2p_upgrade_backup ("settings");

		e2_option_clear_data ();
		e2_option_default_register ();
	}
	else
		exit (1);
}
/*
static void _e2p_upgrade_0_1 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//pseudo action to rename
		gchar *oldstr1 = _("<file actions>");
		gchar *newstr1 = g_strconcat (_A(5),".",_A(20),NULL);
		//keybinding to add
		gchar *oldstr2 = g_strconcat ("\t\t|",_("Delete"),"|false|",_A(5),".",_A(38),"|",NULL); //"delete"
		gchar *newstr2 = g_strconcat ("\t\t|<Shift>",_("Delete"),"|false|",_A(1),".",_A(98),"|",NULL); //"trashempty"
		//filetype string to revise
		gchar *oldstr3 = g_strconcat ("<", _A(13), ".", _A(90),";<", _A(13), ".", _A(72), ";>bzip2 -d -c %F [\\]| tar xf -;<", _A(13), ".", _A(71), ";<", _A(13), ".", _A(90),NULL);
		gchar *newstr3 = g_strconcat (_A(13), ".", _A(72), ";>bzip2 -d -c %f ","\\\\","| tar -C %D -xf -;<", _A(13), ".", _A(71), NULL);

			gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
			gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
				sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.0\\.[0-9]/"VERSION"/'",
				" -e 's/",oldstr1,"/",newstr1,"/'",
				" -e '/",oldstr2,"$/a\\\n",newstr2,"'",
				" -e 's/",oldstr3,"/",newstr3,"/' ",
				cfg_file,".save >",cfg_file,NULL);
//	printd (DEBUG, command);
//			e2_command_run (command, E2_COMMAND_RANGE_DEFAULT);
			system (command);
			g_free (command);
			g_free (cfg_file);

		g_free (newstr1);
		g_free (newstr2);
		g_free (oldstr2);
		g_free (newstr3);
		g_free (oldstr3);

		g_free (sed);
	}
}

static void _e2p_upgrade_0_1_1 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//keybinding to replace
		//NOTE needs |false|, not ||
			//dir line
		gchar *oldstr1 = g_strconcat("\t\t|",_("Insert"),"|false|",_A(1),".",_A(29),"|",NULL); //"clear"
		gchar *newstr1 = g_strconcat("\t\t|<Control>",_("Delete"),"|false|",_A(1),".",_A(29),"|",  //"clear"
			"\\\n\t\t|<Alt>",_("Delete"),"|false|",_A(1),".",_A(30),"|",NULL);	//clear-history

	//keybindings to add
			//general
		gchar *oldstr2 = g_strconcat("\t|<Ctrl>r","|false|",_A(13),".",_A(70),"|",NULL); //"refresh"
		gchar *newstr2 = g_strconcat
			("\t|<Control>1","|false|",_A(4),".",_A(43),"|1\\\n""\t|<CControl>2","|false|",_A(4),".",_A(43),"|2",NULL);

		//command line
		gchar *oldstr3 = g_strconcat("\t\t|<Ctrl>",_("Delete"),"|false|",_A(1),".",_A(29),"|",NULL);	//clear
		gchar *newstr3 = g_strconcat("\t\t|<Alt>",_("Delete"),"|false|",_A(1),".",_A(30),"|",NULL); //clear-history

		//helpdoc locations maybe version-specific
		//e.g. usage-help-doc=/usr/share/doc/emelfm2-0.1.2/USAGE
		gchar *oldstr4 = g_strconcat ("\\(usage-help-doc=.*-\\)",app.cfgfile_version,"\\(\\/.*\\)$", NULL);
		gchar *newstr4 = g_strconcat ("\\","1",VERSION,"\\","2",NULL);
		//config-help-doc=/usr/share/doc/emelfm2-0.1.2/CONFIGURATION
		gchar *oldstr5 = g_strconcat ("\\(config-help-doc=.*-\\)",app.cfgfile_version,"\\(\\/.*\\)$", NULL);

		//commandbar button to add (NOTE no / in match-item path, sed hates it)
		gchar *oldstr6 = g_strconcat
			(_("su.."),"|.*.png|",_("Run something as root"),"|",_A(17),"|xterm -e 'su -c \"%{.*read'",NULL);
		gchar *newstr6 = g_strconcat
			(_("mts.."),"|mounts_"E2IP".png|",_("Mount or unmount a device"),"|",_A(57),".",_A(24),"|",_C(4), NULL);

			gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
			gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
				sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.0\\.[0-9]/"VERSION"/'",
				" -e 's/",oldstr4,"/",newstr4,"/'",
				" -e 's/",oldstr5,"/",newstr4,"/'",
				" -e 's/",oldstr1,"/",newstr1,"/'",
				" -e '/",oldstr2,"$/a\\\n",newstr2,"'",
				" -e '/",oldstr3,"$/a\\\n",newstr3,"' ",
#ifdef E2_FS_MOUNTABLE
				"-e '/",oldstr6,"$/a\\\n",newstr6,"' ",	//~ to avoid problems with / in paths
#endif
				cfg_file,".save >",cfg_file,NULL);
//	printd (DEBUG, command);
//			e2_command_run (command, E2_COMMAND_RANGE_DEFAULT);
			system (command);
			g_free (command);
			g_free (cfg_file);

		g_free (newstr1);
		g_free (oldstr1);
		g_free (newstr2);
		g_free (oldstr2);
		g_free (newstr3);
		g_free (oldstr3);
		g_free (newstr4);
		g_free (oldstr4);
		g_free (oldstr5);
#ifdef E2_FS_MOUNTABLE
		g_free (newstr6);
		g_free (oldstr6);
#endif
		g_free (sed);
	}
}

static void _e2p_upgrade_0_1_2 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{	//get rid of icon file paths
		//keybinding to add
		gchar *oldstr2 = g_strconcat ("\t\t|<Ctrl>a","|false|",_A(10),".",_A(95),"|",NULL);
		gchar *newstr2 = g_strconcat("\t\t|<CControl>i","||",_A(10),".",_A(54),"|",NULL);
		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
			default_config_file, NULL);
		gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION, "/'",
#endif
//separate func for this " -e '2,$s/0\\.[0-1]\\.[0-9]/"VERSION"/'",
				" -e 's~"ICON_DIR"~~'",
				" -e '/",oldstr2,"$/a\\\n",newstr2,"' ",
				cfg_file,".save >",cfg_file,NULL);
		system (command);
		g_free (command);
		g_free (newstr2);
		g_free (oldstr2);
		g_free (cfg_file);

		g_free (sed);
	}
}

static void _e2p_upgrade_0_1_3 (void)
{	//one dialog only !
	gchar *msg = g_strdup_printf (gettext (option_msg),
	VERSION, PROGNAME);
	gint choice = _e2p_upgrade_dialog (msg);
	g_free (msg);

	if (choice == GTK_RESPONSE_OK)
	{

		gchar *sed = _e2p_upgrade_get_sed ();
		if (sed != NULL)
		{
			//keybinding to add
			gchar *oldstr1 = g_strconcat ("\t",_C(32),"||false|",_A(17),"|",NULL);
			gchar *newstr1 = g_strconcat ("\t\t|<Shift><Control>space"),"|false|",_A(10),".",_A(96),"|",NULL);
			//actions to rename
			gchar *oldstr2 = g_strconcat (_A(13),".",_A(45), NULL);
			gchar *newstr2 = g_strconcat (_A(10),".",_A(45), NULL);
			gchar *oldstr3 = g_strconcat (_A(13),".",_A(46),NULL);
			gchar *newstr3 = g_strconcat (_A(10),".",_A(46),NULL);
			gchar *oldstr4 = g_strconcat (_A(13),".",_A(54),NULL);
			gchar *newstr4 = g_strconcat (_A(10),".",_A(54),NULL);
			gchar *oldstr5 = g_strconcat (_A(13),".",_A(81),NULL);
			gchar *newstr5 = g_strconcat (_A(10),".",_A(81),NULL);
			gchar *oldstr6 = g_strconcat (_A(13),".",_A(90),NULL);
			gchar *newstr6 = g_strconcat (_A(10),".",_A(90),NULL);
			gchar *oldstr7 = g_strconcat (_A(13),".",_A(80),NULL);
			gchar *newstr7 = g_strconcat (_A(10),".",_A(80),NULL);
			gchar *oldstr8 = g_strconcat (_A(13),".",_A(95),NULL);
			gchar *newstr8 = g_strconcat (_A(10),".",_A(95),NULL);

			gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
			gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
					sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
					" -e '/",oldstr1,"$/a\\\n",newstr1,"'",
					" -e 's/",oldstr2,"/",newstr2,"/'",
					" -e 's/",oldstr3,"/",newstr3,"/'",
					" -e 's/",oldstr4,"/",newstr4,"/'",
					" -e 's/",oldstr5,"/",newstr5,"/'",
					" -e 's/",oldstr6,"/",newstr6,"/g'",	//this may have >1 per line
					" -e 's/",oldstr7,"/",newstr7,"/'",
					" -e 's/",oldstr8,"/",newstr8,"/' ",
					cfg_file,".save >",cfg_file,NULL);
			system (command);
			g_free (command);
			g_free (newstr1);
			g_free (oldstr1);
			g_free (newstr2);
			g_free (oldstr2);
			g_free (newstr3);
			g_free (oldstr3);
			g_free (newstr4);
			g_free (oldstr4);
			g_free (newstr5);
			g_free (oldstr5);
			g_free (newstr6);
			g_free (oldstr6);
			g_free (newstr7);
			g_free (oldstr7);
			g_free (newstr8);
			g_free (oldstr8);
			g_free (cfg_file);

			g_free (sed);
		}
	}
}
*/
static void _e2p_upgrade_0_1_5 (void)
{	//one dialog only !
	gchar *msg = g_strdup_printf (gettext (default_msg),
	VERSION, PROGNAME, e2_cl_options.config_dir);
	gint choice = _e2p_upgrade_dialog (msg);
	g_free (msg);

	if (choice == GTK_RESPONSE_OK)
		_e2p_upgrade_backup ("config");
}
/*
static void _e2p_upgrade_0_1_6 (void)
{	//one dialog only !
	gchar *msg = g_strdup_printf (gettext (option_msg),
	VERSION, PROGNAME);
	gint choice = _e2p_upgrade_dialog (msg);
	g_free (msg);

	if (choice == GTK_RESPONSE_OK)
	{
		gchar *sed = _e2p_upgrade_get_sed ();
		if (sed != NULL)
		{
			//keybindings to add
			gchar *oldstr1 = g_strconcat("\t|F3|false|",_A(5),".",_A(101),"|",NULL);
			gchar *newstr1 = g_strconcat("\t|<Shift>F3||",_A(5),".",_A(102),"|",NULL);
			gchar *oldstr2 = g_strconcat("\t|F4|false|",_A(5),".",_A(39),"|",NULL);
			gchar *newstr2 = g_strconcat("\t|<Shift>F4||",_A(5),".",_A(40),"|",NULL);
			gchar *oldstr3 = g_strconcat("\t|F5|false|",_A(5),".",_A(33),"|",NULL);
			gchar *newstr3 = g_strconcat("\t|<Shift>F5||",_A(5),".",_A(34),"|",NULL);
			gchar *oldstr4 = g_strconcat("\t|F6|false|",_A(5),".",_A(58),"|",NULL);
			gchar *newstr4 = g_strconcat("\t|<Shift>F6||",_A(5),".",_A(59),"|",NULL);
			//keybindings to change
			gchar *oldstr5 = g_strconcat("\t\t|<Shft>Up|false|",_A(17),NULL); //FIXME //_A(17)
			gchar *newstr5 = g_strconcat("\t\t|<Alt>Up||",_A(17),NULL);
			gchar *oldstr6 = g_strconcat("\t|<Ctrl>space||",_A(9),".",_A(68),NULL);
			gchar *newstr6 = g_strconcat("\t|<CControl>g","||",_A(9),".",_A(68),NULL);
			gchar *oldstr7 = g_strconcat("\t\t|<Shft><Ctrl>space|false|",_A(10),".",_A(96),NULL);
			gchar *newstr7 = g_strconcat("\t\t|space||",_A(10),".",_A(96),NULL);
			//action parameter to kill
			gchar *oldstr8 = _("expand");

			gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
			gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
					sed,
#ifndef E2_VERSIONDOCS
					" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
					" -e '/",oldstr1,"$/a\\\n",newstr1,"'",
					" -e '/",oldstr2,"$/a\\\n",newstr2,"'",
					" -e '/",oldstr3,"$/a\\\n",newstr3,"'",
					" -e '/",oldstr4,"$/a\\\n",newstr4,"'",
					" -e 's/",oldstr5,"/",newstr5,"/'",
					" -e 's/",oldstr6,"/",newstr6,"/'",
					" -e 's/",oldstr7,"/",newstr7,"/'",
*/
//					" -e 's/",oldstr8,"/*/' ",
/*					cfg_file,".save >",cfg_file,NULL);
			system (command);
			g_free (command);
			g_free (oldstr1);
			g_free (newstr1);
			g_free (oldstr2);
			g_free (newstr2);
			g_free (oldstr3);
			g_free (newstr3);
			g_free (oldstr4);
			g_free (newstr4);
			g_free (oldstr5);
			g_free (newstr5);
			g_free (oldstr6);
			g_free (newstr6);
			g_free (oldstr7);
			g_free (newstr7);

			g_free (sed);
		}
	}
}

static void _e2p_upgrade_0_1_6_2 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
		//keybindings to add
		gchar *oldstr1 = g_strconcat("\t\t|<Ctrl>h","|false|",_A(10),".",_A(80),"|",NULL);
		gchar *newstr1 = g_strconcat("\t\t|<Ctrl>m","|false|",_A(10),".",_A(21),"|",NULL);
		gchar *oldstr2 = g_strconcat("\t",_C(5),"||false||",NULL);
		gchar *newstr2 = g_strconcat("\t\t|<Shft>Return||",_A(1),".",_A(77),"|",NULL);

		gchar *command = g_strconcat ("cp -f ", cfg_file, " ", cfg_file, ".save;",
			sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
				 " -e '/",oldstr1,"$/a\\\n",newstr1,"'",
				 " -e '/",oldstr2,"$/a\\\n",newstr2,"'",
				//re-configure all tree-option name lines
				 " -e 's/^<\\(.*\\)/\\1=</' ",
				cfg_file,".save >",cfg_file,NULL);
		system (command);
		g_free (command);
		g_free (oldstr1);
		g_free (newstr1);
		g_free (oldstr2);
		g_free (newstr2);
		g_free (sed);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}

static void _e2p_upgrade_0_1_6_3 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		//keybindings to add
		gchar *oldstr1 = g_strconcat("\t\t|<Ctrl>m","|false|",_A(10),".",_A(21),"|",NULL);
		gchar *newstr1 = g_strconcat("\t\t|<Control>t","||",_A(10),".",_A(22),"|",NULL);
		gchar *oldstr9 = g_strconcat("\t|F5|false|",_A(5),".",_A(33),"|",NULL);
		gchar *newstr9 = g_strconcat("\t|<Control>F5||",_A(5),".",_A(36),"|",NULL);
		//context menu items to add
		gchar *oldstr10 = g_strconcat("\t",_("_Free space"),"||false|true|>stat",NULL);
		gchar *newstr10 = g_strconcat("\t||false|true|",_A(18),"|",NULL);
		gchar *newstr11 = g_strconcat("\t",_("_Edit user commands.."),"|gtk-preferences|false|true|",_A(2),".",_A(32),"|",_C(8),NULL);
		//toggle-action reformatting
		gchar *oldstr2 = g_strconcat("\\([^|]*",_A(108),"\\)|true",NULL);
		gchar *newstr2 = g_strconcat(_A(15),".",_A(111),"|\\1",NULL);
		gchar *oldstr3 = g_strconcat("\\([^|]*",_A(80),"\\)|true",NULL);
		gchar *newstr3 = g_strconcat(_A(15),".",_A(111),"|\\1",NULL);
		gchar *oldstr4 = g_strconcat("\\([^|]*",_A(22),"\\)|true",NULL);
		gchar *newstr4 = g_strconcat(_A(15),".",_A(111),"|\\1",NULL);
		gchar *oldstr5 = g_strconcat("\\([^|]*",_A(108),"\\)|false",NULL);
		gchar *newstr5 = g_strconcat(_A(15),".",_A(110),"|\\1",NULL);
		gchar *oldstr6 = g_strconcat("\\([^|]*",_A(80),"\\)|false",NULL);
		gchar *newstr6 = g_strconcat(_A(15),".",_A(110),"|\\1",NULL);
		gchar *oldstr7 = g_strconcat("\\([^|]*",_A(22),"\\)|false",NULL);
		gchar *newstr7 = g_strconcat(_A(15),".",_A(110),"|\\1",NULL);
		gchar *oldstr8 = g_strconcat (_A(9),".",_A(80),NULL);
		gchar *newstr8 = g_strconcat (_A(9),".",_A(79),NULL);
		gchar *command = g_strconcat (
				"cp -f ", local, " ", local, ".save;",
				sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
				 " -e '/",oldstr1,"$/a\\\n",newstr1,"'",
				 " -e '/",oldstr9,"$/a\\\n",newstr9,"'",
 				 " -e '/",oldstr10,".*$/a\\\n",newstr10,"\\\n",newstr11,"'",
				//renamed actions FIXME later - remove specific _() so is not translated
				 " -e 's/",_("<filter>"),"/",_A(22),"/'",
				 " -e 's/",_("toggle_full"),"/",_A(108),"/'",
				 " -e 's/",_("toggle_hidden"),"/",_A(80),"/'",
				 " -e 's/",oldstr2,"/",newstr2,"/'",
				 " -e 's/",oldstr3,"/",newstr3,"/'",
				 " -e 's/",oldstr4,"/",newstr4,"/'",
				 " -e 's/",oldstr5,"/",newstr5,"/'",
				 " -e 's/",oldstr6,"/",newstr6,"/'",
				 " -e 's/",oldstr7,"/",newstr7,"/'",
				 " -e 's/",oldstr8,"/",newstr8,"/'",
				 " -e 's/^\\(\t*\\)[\\]</\\1</'",
				 " -e 's/<Ctrl>/<Control>/'",
				 " -e 's/<Shft>/<Shift>/' ",
				local,".save >",local,NULL);
		system (command);

		g_free (cfg_file);
		F_FREE (local);
		g_free (command);
		g_free (oldstr1);
		g_free (newstr1);
		g_free (oldstr2);
		g_free (newstr2);
		g_free (oldstr3);
		g_free (newstr3);
		g_free (oldstr4);
		g_free (newstr4);
		g_free (oldstr5);
		g_free (newstr5);
		g_free (oldstr6);
		g_free (newstr6);
		g_free (oldstr7);
		g_free (newstr7);
		g_free (oldstr8);
		g_free (newstr8);
		g_free (oldstr9);
		g_free (newstr9);
		g_free (oldstr10);
		g_free (newstr10);
		g_free (newstr11);
		g_free (sed);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}

static void _e2p_upgrade_0_1_7_1 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//actions to rename
		gchar *oldstr1 = g_strconcat (_A(3),"\\.",_A(56), NULL);
		gchar *newstr1 = g_strconcat (_A(1),".",_A(56), NULL);
		//commandbar item re-assigned
		gchar *oldstr2 = g_strconcat(_("ps"),"|ps_"E2IP".png|",_("List child processes"),"|",_A(1),".",_("list_children"),"|",NULL);
		gchar *newstr2 = g_strconcat(_("ps"),"|ps_"E2IP".png|",_("Child processes"),"|",_A(28),".",_A(24),"|",NULL);
		gchar *oldstr7 = g_strconcat(_A(1),"\\.",_("list_children"),NULL);
		gchar *newstr7 = g_strconcat(_A(7),".",_A(28),NULL);
		//keybindings to add
		gchar *oldstr3 = g_strconcat("\t|F1|false|",_A(13),".",_A(70),"|",NULL);
		gchar *newstr3 = g_strconcat("\t|<Shift>F1||",_A(7),".",_A(28),"|\\n"
									"\t|<Control>F1||",_A(7),".",_A(66),"|\\n"
									"\t|<Alt>F1||",_A(7),".",_A(51),"|",NULL);
		gchar *oldstr4 = g_strconcat("\t\t|Tab|false|",_A(1),".",_A(31),"|",NULL);
		gchar *newstr4 = g_strconcat("\t\t|<Alt>Insert||",_A(7),".",_A(28),"|",NULL);
		gchar *oldstr8 = g_strconcat("\t|<Control>F5|false|",_A(5),".",_A(36),"|",NULL);
		gchar *newstr8 = g_strconcat("\t|<Alt>F5||",_A(5),".",_A(35),"|",NULL);
		//keybinding to delete
		gchar *oldstr5 = g_strconcat("\t\t|Home|false|cd|$HOME",NULL);
		//alias to delete
		gchar *oldstr6 = " *[^>].*[<>\\|].*||>";

		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
				default_config_file, NULL);
		gchar *local = D_FILENAME_TO_LOCALE (cfg_file);
		gchar *local2;
		if (e2_fs_access (local, R_OK E2_ERR_PTR()))
		{
			g_free (cfg_file);
			cfg_file = g_build_filename (e2_cl_options.config_dir, "config", NULL);
			local2 = F_FILENAME_TO_LOCALE (cfg_file);
			if (e2_fs_access (local2, R_OK E2_ERR_PTR()))
			{
				_e2p_upgrade_0_1_5 ();	//suggest default
				return;
			}
		}
		else
			local2 = local;

		gchar *command = g_strconcat ("cp -f ", local2, " ", local2, ".save;",
		sed,
#ifndef E2_VERSIONDOCS
				" -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
		" -e 's/",oldstr1,"/",newstr1,"/'",
		" -e 's/",oldstr2,"/",newstr2,"/'",
		" -e 's/",oldstr7,"/",newstr7,"/'",
		" -e '/",oldstr3,"$/a\\\n",newstr3,"'",
		" -e '/",oldstr4,"$/a\\\n",newstr4,"'",
		" -e '/",oldstr8,"$/a\\\n",newstr8,"'",
		" -e '/",oldstr5,"/d'",
		" -e '/",oldstr6,"/d' ",
		local2,".save >",local,NULL);
		system (command);

		g_free (cfg_file);
		if (local != local2)
			F_FREE (local2);
		g_free (local);
		g_free (command);
		g_free (oldstr1);
		g_free (newstr1);
		g_free (oldstr2);
		g_free (newstr2);
		g_free (oldstr3);
		g_free (newstr3);
		g_free (oldstr4);
		g_free (newstr4);
		g_free (oldstr5);
		g_free (oldstr7);
		g_free (newstr7);
		g_free (oldstr8);
		g_free (newstr8);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}
*/
static void _e2p_upgrade_0_2_0 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
			default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		gchar *command = g_strconcat ("cp -f ", local, " ", local, ".save;",
		sed,
#ifndef E2_VERSIONDOCS
			 " -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.1\\.[0-9]/"VERSION"/'",
			 " -e 's~\t\t|\\(.*\\)|\\.\\/%f~\t\t|\\1|%f~' ",
			 local,".save >",local,NULL);
		system (command);

		g_free (cfg_file);
		F_FREE (local);
		g_free (command);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}

static void _e2p_upgrade_0_3_0 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//out-of-date bindings and commands
		gchar *oldstr1 = g_strconcat ("|",_("_Run"),"|\\./%f",NULL);
		gchar *newstr1 = g_strconcat ("|",_("_Run"),"|%p",NULL);
		gchar *oldstr4 = g_strconcat ("command-encoder=\\(.*\\)enca -L %{", _("File encoding:"),"} -x UTF-8 <%f", NULL);
		gchar *newstr4 = g_strconcat ("command-encoder=\\1enca -L %{(languages)@", _("File encoding:"),"} -x UTF-8 <%p", NULL);
		gchar *oldstr5 = g_strconcat ("%{",_("Editor command:"),"} %f", NULL);
		gchar *newstr5 = g_strconcat ("%{(editors)@",_("Editor command:"),"} %p", NULL);
		//superseded config options
		gchar *oldstr2 = "^fileop-background=.*$";
		gchar *oldstr3 = "^address-completion=.*$";
		//cache flags whose order has changed
		gchar *oldstr6 = "^find-plugin-flags=.*$";
		//renamed option
		gchar *oldstr7 = "^color-drag-highlight";
		gchar *newstr7 = "color-highlight";

		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
			default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		gchar *command = g_strconcat ("cp -f ", local, " ", local, ".save;",
		sed,
#ifndef E2_VERSIONDOCS
			 " -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.2\\.[0-9]/"VERSION"/'",
			 " -e 's~",oldstr1,"~",newstr1,"~'",	//a pattern includes "/"
			 " -e 's/",oldstr4,"/",newstr4,"/'",
			 " -e 's/",oldstr5,"/",newstr5,"/'",
			 " -e 's/",oldstr7,"/",newstr7,"/'",
			 " -e '/",oldstr2,"/d'",
			 " -e '/",oldstr3,"/d'",
			 " ",local,".save >",local,NULL);
		system (command);
		g_free (cfg_file);
		F_FREE (local);
		g_free (command);

		cfg_file = g_build_filename (e2_cl_options.config_dir,
			"cache", NULL);	//default_cache_file, NULL);
		local = F_FILENAME_TO_LOCALE (cfg_file);
		command = g_strconcat ("cp -f ", local, " ", local, ".save;",
		sed, " -e '/",oldstr6,"/d'",
			 " ",local,".save >",local,NULL);
		system (command);

		g_free (oldstr1);
		g_free (newstr1);
		g_free (oldstr4);
		g_free (newstr4);
		g_free (oldstr5);
		g_free (newstr5);
		g_free (cfg_file);
		F_FREE (local);
		g_free (command);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}

static void _e2p_upgrade_0_3_1 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//renamed actions
		gchar *oldlist = _("<list>");
		gchar *oldstr1 = g_strconcat (_A(66),".",_A(38),NULL);
		gchar *newstr1 = g_strconcat (_A(29),".",_A(66),NULL);
		gchar *oldstr2 = g_strconcat (_A(0),".",oldlist,NULL);
		gchar *newstr2 = g_strconcat (_A(0),".",_A(24),NULL);
		gchar *oldstr3 = g_strconcat (_A(28),".",oldlist,NULL);
		gchar *newstr3 = g_strconcat (_A(7),".",_A(28),NULL);
		gchar *oldstr4 = g_strconcat (_A(51),".",oldlist,NULL);
		gchar *newstr4 = g_strconcat (_A(7),".",_A(51),NULL);
		gchar *oldstr5 = g_strconcat (_A(57),".",oldlist,NULL);
		gchar *newstr5 = g_strconcat (_A(57),".",_A(24),NULL);
		gchar *oldstr6 = g_strconcat (_A(66),".",oldlist,NULL);
		gchar *newstr6 = g_strconcat (_A(7),".",_A(66),NULL);
		gchar *oldstr7 = g_strconcat (_A(14),".",oldlist,NULL);
		gchar *newstr7 = g_strconcat (_A(14),".",_A(24),NULL);

		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
			default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		gchar *command = g_strconcat ("cp -f ", local, " ", local, ".save;",
		sed,
#ifndef E2_VERSIONDOCS
			 " -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.[2-3]\\.[0-9]/"VERSION"/'",
			 " -e 's/",oldstr1,"/",newstr1,"/'",
			 " -e 's/",oldstr2,"/",newstr2,"/'",
			 " -e 's/",oldstr3,"/",newstr3,"/'",
			 " -e 's/",oldstr4,"/",newstr4,"/'",
			 " -e 's/",oldstr5,"/",newstr5,"/'",
			 " -e 's/",oldstr6,"/",newstr6,"/'",
			 " -e 's/",oldstr7,"/",newstr7,"/'",
			 " ",local,".save >",local,NULL);
		system (command);

		g_free (oldstr1);
		g_free (newstr1);
		g_free (oldstr2);
		g_free (newstr2);
		g_free (oldstr3);
		g_free (newstr3);
		g_free (oldstr4);
		g_free (newstr4);
		g_free (oldstr5);
		g_free (newstr5);
		g_free (oldstr6);
		g_free (newstr6);
		g_free (oldstr7);
		g_free (newstr7);
		g_free (cfg_file);
		F_FREE (local);
		g_free (command);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}

#ifdef E2_TREEDIALOG
static void _e2p_upgrade_0_3_3 (void)
{
	gchar *sed = _e2p_upgrade_get_sed ();
	if (sed != NULL)
	{
		//keybinding to add
		gchar *oldstr1 = g_strconcat("\t|F9|false|",_A(5),".",_A(52),"|",NULL);
		gchar *newstr1 = g_strconcat("\t|<Shift>F9||",_A(10),".",_A(99),"|",NULL);

		gchar *cfg_file = g_build_filename (e2_cl_options.config_dir,
			default_config_file, NULL);
		gchar *local = F_FILENAME_TO_LOCALE (cfg_file);
		gchar *command = g_strconcat ("cp -f ", local, " ", local, ".save;",
		sed,
#ifndef E2_VERSIONDOCS
			 " -e '1s/", app.cfgfile_version, "/", VERSION RELEASE, "/'",
#endif
//separate func for this " -e '2,$s/0\\.[2-3]\\.[0-9]/"VERSION"/'",
			" -e '/",oldstr1,"$/a\\\n",newstr1,"'",
			 " ",local,".save >",local,NULL);
		system (command);

		g_free (oldstr1);
		g_free (newstr1);
		g_free (cfg_file);
		F_FREE (local);
		g_free (command);
	}
	else
		_e2p_upgrade_0_1_5 ();	//suggest default
}
#endif

static void _e2p_upgrade_0_3_6 (void)
{
	//get rid of outdated cache flags for find plugin, which hasn't been loaded yet
	e2_cache_clean1 ("find-plugin-flags");
}

gboolean init_plugin (Plugin *p)
{
#define ANAME "uprade"
	p->signature = ANAME VERSION;

	if (strcmp (app.cfgfile_version,"0.1") < 0)
		//this one's major - dump the lot and start afresh
		_e2p_upgrade_pre_0_1();
//	else if (strcmp (app.cfgfile_version,"0.1.6") < 0)
//	else if (strcmp (app.cfgfile_version,"0.1.7") < 0)
//		_e2p_upgrade_0_1_5 ();
	else
	{
/*	//do all the recent 'little' uprades in sequence - ugly !!
		if (strcmp (app.cfgfile_version,"0.1.1") < 0)
			_e2p_upgrade_0_1 ();
		if (strcmp (app.cfgfile_version,"0.1.2") < 0)
			_e2p_upgrade_0_1_1 ();
		if (strcmp (app.cfgfile_version,"0.1.3") < 0)
			_e2p_upgrade_0_1_2 ();
		if (strcmp (app.cfgfile_version,"0.1.3.2") < 0)	//.2 interim release
			_e2p_upgrade_0_1_3 ();
		if (strcmp (app.cfgfile_version,"0.1.5.2") < 0)
			_e2p_upgrade_0_1_5 ();
		else
*/
/* NO MORE DETAILED UPGRADES < 0.2.0
		if (strcmp (app.cfgfile_version,"0.1.6.2") < 0)
				_e2p_upgrade_0_1_6_2 ();
			if (strcmp (app.cfgfile_version,"0.1.6.3") < 0)
				_e2p_upgrade_0_1_6_3 ();
			if (strcmp (app.cfgfile_version,"0.1.7.1") < 0)
				_e2p_upgrade_0_1_7_1 ();
*/
//NOTE check that config plugin uses this same definition
#define OLDEST_UPGRADE "0.2.0"

			if (strcmp (app.cfgfile_version,"0.1.9") < 0)	//some number < OLDEST_UPGRADE
				_e2p_upgrade_0_1_5 ();
			else
			{
#ifdef E2_VERSIONDOCS
				_e2p_upgrade_numbers ();	//always update docs version etc
#endif

				if (strcmp (app.cfgfile_version,"0.2.0") < 0)
					_e2p_upgrade_0_2_0 ();
				if (strcmp (app.cfgfile_version,"0.3.0") < 0)
					_e2p_upgrade_0_3_0 ();
				if (strcmp (app.cfgfile_version,"0.3.0.1") < 0)
					_e2p_upgrade_0_3_1 ();
#ifdef E2_TREEDIALOG
				if (strcmp (app.cfgfile_version,"0.3.3") < 0)
					_e2p_upgrade_0_3_3 ();
#endif
				if (strcmp (app.cfgfile_version,"0.3.5.1") < 0)
					_e2p_upgrade_0_3_6 ();
				else
					cancelled = TRUE;
			}
			if (!cancelled)
				_e2p_upgrade_reconfig ();	//implement all updates
	}
	return TRUE;
}

gboolean clean_plugin (Plugin *p)
{
	return TRUE;
}
