anjuta r3893 - in trunk: . libanjuta/interfaces plugins plugins/build-basic-autotools plugins/debug-manager plugins/gdb plugins/run-program po src



Author: sgranjoux
Date: Mon Apr 28 19:49:42 2008
New Revision: 3893
URL: http://svn.gnome.org/viewvc/anjuta?rev=3893&view=rev

Log:
	* configure.in,
	po/POTFILES.in,
	plugins/Makefile.am,
	src/anjuta.ui,
	(added) plugins/run-program/anjuta-run-program-48.png,
	(added) plugins/run-program/anjuta-run-program.glade,
	(added) plugins/run-program/anjuta-run-program.plugin.in,
	(added) plugins/run-program/anjuta-run-program.ui,
	(added) plugins/run-program/execute.c,
	(added) plugins/run-program/execute.h,
	(added) plugins/run-program/Makefile.am,
	(added) plugins/run-program/parameters.c,
	(added) plugins/run-program/parameters.h,
	(added) plugins/run-program/plugin.c,
	(added) plugins/run-program/plugin.h,
	(added) plugins/run-program/utils.c,
	(added) plugins/run-program/utils.h:
	New run program plugin, includes a new dialog box to set
	program arguments

	* plugins/debug-manager/anjuta-debug-manager.plugin.in,
	plugins/debug-manager/anjuta-debug-manager.ui,
	plugins/debug-manager/plugin.c,
	plugins/debug-manager/start.c:
	Update debugger plugin to use run program parameter dialog

	* plugins/build-basic-autotools/build-basic-autotools.c,
	plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui:
	Remove run program menu item

	* libanjuta/interfaces/libanjuta.idl,
	plugins/gdb/plugin.c,
	plugins/gdb/debugger.c,
	plugins/gdb/debugger.h,
	plugins/debug-manager/command.c,
	plugins/debug-manager/command.h:
	Use a gchar * null terminated array instead of a GList for
	passing environment variables


Added:
   trunk/plugins/run-program/
   trunk/plugins/run-program/Makefile.am
   trunk/plugins/run-program/anjuta-run-program-48.png   (contents, props changed)
   trunk/plugins/run-program/anjuta-run-program.glade
   trunk/plugins/run-program/anjuta-run-program.plugin.in
   trunk/plugins/run-program/anjuta-run-program.ui
   trunk/plugins/run-program/execute.c   (contents, props changed)
   trunk/plugins/run-program/execute.h   (contents, props changed)
   trunk/plugins/run-program/parameters.c   (contents, props changed)
   trunk/plugins/run-program/parameters.h   (contents, props changed)
   trunk/plugins/run-program/plugin.c   (contents, props changed)
   trunk/plugins/run-program/plugin.h   (contents, props changed)
   trunk/plugins/run-program/utils.c   (contents, props changed)
   trunk/plugins/run-program/utils.h   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/libanjuta/interfaces/libanjuta.idl
   trunk/plugins/Makefile.am
   trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
   trunk/plugins/build-basic-autotools/build-basic-autotools.c
   trunk/plugins/debug-manager/anjuta-debug-manager.plugin.in
   trunk/plugins/debug-manager/anjuta-debug-manager.ui
   trunk/plugins/debug-manager/command.c
   trunk/plugins/debug-manager/command.h
   trunk/plugins/debug-manager/plugin.c
   trunk/plugins/debug-manager/start.c
   trunk/plugins/gdb/debugger.c
   trunk/plugins/gdb/debugger.h
   trunk/plugins/gdb/plugin.c
   trunk/po/POTFILES.in
   trunk/src/anjuta.ui

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Mon Apr 28 19:49:42 2008
@@ -1196,6 +1196,7 @@
 plugins/project-wizard/templates/sdl/src/Makefile
 plugins/project-wizard/templates/sdl/po/Makefile
 plugins/language-support-cpp-java/Makefile
+plugins/run-program/Makefile
 anjuta.desktop.in
 manuals/Makefile
 manuals/reference/Makefile

Modified: trunk/libanjuta/interfaces/libanjuta.idl
==============================================================================
--- trunk/libanjuta/interfaces/libanjuta.idl	(original)
+++ trunk/libanjuta/interfaces/libanjuta.idl	Mon Apr 28 19:49:42 2008
@@ -3144,7 +3144,7 @@
 	*
 	* Returns: TRUE if sucessfull, other FALSE.
 	*/
-	gboolean set_environment (const List<const gchar*> env);
+	gboolean set_environment (gchar **env);
 
 	/**
 	* ianjuta_debugger_start:

Modified: trunk/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am	(original)
+++ trunk/plugins/Makefile.am	Mon Apr 28 19:49:42 2008
@@ -32,7 +32,8 @@
 	language-manager \
 	symbol-db \
 	symbol-browser \
-	sourceview
+	sourceview \
+	run-program
 
 # indent
 

Modified: trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
==============================================================================
--- trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui	(original)
+++ trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui	Mon Apr 28 19:49:42 2008
@@ -17,7 +17,6 @@
 				<menuitem name="CleanModule" action="ActionBuildCleanModule"/>
 				<menuitem name="CleanProject" action="ActionBuildCleanProject"/>
 				<separator name="separator13"/>
-				<menuitem name="Execute" action="ActionBuildExecute"/>
 			</menu>
 		</placeholder>
 	</menubar>

Modified: trunk/plugins/build-basic-autotools/build-basic-autotools.c
==============================================================================
--- trunk/plugins/build-basic-autotools/build-basic-autotools.c	(original)
+++ trunk/plugins/build-basic-autotools/build-basic-autotools.c	Mon Apr 28 19:49:42 2008
@@ -1167,12 +1167,6 @@
 }
 
 static void
-build_execute_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
-{
-	execute_program (plugin, NULL);
-}
-
-static void
 build_build_module (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dirname = g_dirname (plugin->current_editor_filename);
@@ -1375,12 +1369,6 @@
 		G_CALLBACK (build_distribution_project)
 	},
 	{
-		"ActionBuildExecute", NULL,
-		N_("_Execute Program..."), "F3",
-		N_("Execute program"),
-		G_CALLBACK (build_execute_project)
-	},
-	{
 		"ActionBuildBuildModule", GTK_STOCK_EXECUTE,
 		N_("_Build Module"), "F11",
 		N_("Build module associated with current file"),

Modified: trunk/plugins/debug-manager/anjuta-debug-manager.plugin.in
==============================================================================
--- trunk/plugins/debug-manager/anjuta-debug-manager.plugin.in	(original)
+++ trunk/plugins/debug-manager/anjuta-debug-manager.plugin.in	Mon Apr 28 19:49:42 2008
@@ -4,3 +4,4 @@
 Location=anjuta-debug-manager:DebugManagerPlugin
 Icon=anjuta-debug-manager-plugin-48.png
 Interfaces=IAnjutaDebugManager
+Dependencies=anjuta-run-program:RunProgramPlugin

Modified: trunk/plugins/debug-manager/anjuta-debug-manager.ui
==============================================================================
--- trunk/plugins/debug-manager/anjuta-debug-manager.ui	(original)
+++ trunk/plugins/debug-manager/anjuta-debug-manager.ui	Mon Apr 28 19:49:42 2008
@@ -3,12 +3,6 @@
 	<menubar name="MenuMain">
 		<placeholder name="PlaceHolderDebugMenus">
 			<menu name="MenuDebug" action="ActionMenuDebug">
-				<menuitem name="RunTarget" action="ActionDebuggerRunTarget" />
-				<menuitem name="RestartTarget" action="ActionDebuggerRestartTarget" />
-				<menuitem name="AttachProcess" action="ActionDebuggerAttachProcess" />
-				<menuitem name="Stop" action="ActionDebuggerStop" />
-				<menuitem name="AddSource" action="ActionDebuggerAddSource" />
-				<separator name="separator3"/>
 
 				<menuitem name="Run" action="ActionDebuggerRunContinue" />
 				<menuitem name="RunToPosition" action="ActionDebuggerRunToPosition" />
@@ -38,9 +32,22 @@
 				</menu>
 				<separator name="separator6"/>
 				<menuitem name="GdbCommand" action="ActionGdbCommand" />
+				<separator name="separator3"/>
+				<menuitem name="AddSource" action="ActionDebuggerAddSource" />
 
 			</menu>
 		</placeholder>
+		<placeholder name="PlaceHolderRunMenus">
+			<menu name="MenuRun" action="ActionMenuRun">
+				<placeholder name="PlaceHolderRunCommands">
+					<menuitem name="RunTarget" action="ActionDebuggerRunTarget" />
+					<menuitem name="AttachProcess" action="ActionDebuggerAttachProcess" />
+				</placeholder>
+				<placeholder name="PlaceHolderStopCommands">
+					<menuitem name="Stop" action="ActionDebuggerStop" />
+				</placeholder>
+			</menu>
+		</placeholder>
 	</menubar>
 	<toolbar name="ToolbarDebug">
 		<placeholder name="PlaceholderDebugToolbar" >

Modified: trunk/plugins/debug-manager/command.c
==============================================================================
--- trunk/plugins/debug-manager/command.c	(original)
+++ trunk/plugins/debug-manager/command.c	Mon Apr 28 19:49:42 2008
@@ -349,7 +349,7 @@
 			gchar *name;
 			gchar *value;
 		} var;
-		GList *env;
+		gchar **env;
 		gchar *dir;
 	} data;
 	struct _DmaQueueCommand *next;
@@ -408,11 +408,7 @@
 		cmd->data.dir = g_strdup (va_arg (args, gchar *));
 		break;
 	case SET_ENVIRONMENT_COMMAND:
-		for (list = va_arg (args, GList *); list != NULL; list = g_list_next (list))
-		{
-			cmd->data.env = g_list_prepend (cmd->data.env, g_strdup (list->data));
-		}
-		cmd->data.env = g_list_reverse (cmd->data.env);
+		cmd->data.env = g_strdupv (va_arg (args, gchar **));
 		break;
 	case START_COMMAND:
 		cmd->data.start.args = g_strdup (va_arg (args, gchar *));
@@ -656,7 +652,7 @@
 }
 
 gboolean
-dma_queue_set_environment(DmaDebuggerQueue *self, const GList *variables)
+dma_queue_set_environment(DmaDebuggerQueue *self, gchar **variables)
 {
 	return dma_debugger_queue_append (self, dma_command_new (DMA_SET_ENVIRONMENT_COMMAND, variables));
 }
@@ -1051,8 +1047,7 @@
 		if (cmd->data.dir) g_free (cmd->data.dir);
 		break;
 	case SET_ENVIRONMENT_COMMAND:
-        g_list_foreach (cmd->data.env, (GFunc)g_free, NULL);
-        g_list_free (cmd->data.env);
+		g_strfreev (cmd->data.env);
 		break;
 	case ATTACH_COMMAND:
         g_list_foreach (cmd->data.attach.dirs, (GFunc)g_free, NULL);

Modified: trunk/plugins/debug-manager/command.h
==============================================================================
--- trunk/plugins/debug-manager/command.h	(original)
+++ trunk/plugins/debug-manager/command.h	Mon Apr 28 19:49:42 2008
@@ -60,7 +60,7 @@
 gboolean dma_queue_initialize (DmaDebuggerQueue *self);
 gboolean dma_queue_load (DmaDebuggerQueue *self, const gchar *file, const gchar* mime_type, const GList *search_dirs);
 gboolean dma_queue_set_working_directory (DmaDebuggerQueue *self, const gchar *directory);
-gboolean dma_queue_set_environment (DmaDebuggerQueue *self, const GList *variables);
+gboolean dma_queue_set_environment (DmaDebuggerQueue *self, gchar **variables);
 gboolean dma_queue_attach (DmaDebuggerQueue *self, pid_t pid, const GList *search_dirs);
 gboolean dma_queue_start (DmaDebuggerQueue *self, const gchar *args, gboolean terminal, gboolean stop);
 gboolean dma_queue_unload (DmaDebuggerQueue *self);

Modified: trunk/plugins/debug-manager/plugin.c
==============================================================================
--- trunk/plugins/debug-manager/plugin.c	(original)
+++ trunk/plugins/debug-manager/plugin.c	Mon Apr 28 19:49:42 2008
@@ -582,20 +582,7 @@
 on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
 {
 	enable_log_view (this, TRUE);
-	if (dma_run_target (this->start))
-	{
-		GtkAction *action;
-		action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
-		gtk_action_set_sensitive (action, TRUE);
-	}
-
-}
-
-static void
-on_restart_debug_activate (GtkAction* action, DebugManagerPlugin* this)
-{
-	enable_log_view (this, TRUE);
-	dma_rerun_target (this->start);
+	dma_run_target (this->start);
 }
 
 static void
@@ -846,25 +833,17 @@
 	{
 		"ActionDebuggerRunTarget",
 		NULL,
-		N_("Run Target..."),
+		N_("_Debug Program"),
 		"<shift>F12",
-		N_("load and start the target for debugging"),
+		N_("Start debugger and load the program"),
 		G_CALLBACK (on_start_debug_activate)
 	},
 	{
-		"ActionDebuggerRestartTarget",
-		NULL,
-		N_("Restart Target"),
-		NULL,
-		N_("restart the same target for debugging"),
-		G_CALLBACK (on_restart_debug_activate)
-	},
-	{
 		"ActionDebuggerAttachProcess",
 		"debugger-attach",
-		N_("_Attach to Process..."),
+		N_("_Debug Process..."),
 		NULL,
-		N_("Attach to a running program"),
+		N_("Start debugger and attach to a running program"),
 		G_CALLBACK (on_attach_to_project_action_activate)
 	},
 	{
@@ -1074,7 +1053,6 @@
 	DebugManagerPlugin *this;
     static gboolean initialized = FALSE;
 	AnjutaUI *ui;
-	GtkAction *action;
 	
 	DEBUG_PRINT ("DebugManagerPlugin: Activating Debug Manager plugin...");
 	this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
@@ -1149,10 +1127,7 @@
 	/* Start debugger part */
 	this->start = dma_start_new (this);
 	
-
 	dma_plugin_debugger_stopped (this, 0);
-	action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
-	gtk_action_set_sensitive (action, FALSE);
 	
 	/* Add watches */
 	this->project_watch_id = 

Modified: trunk/plugins/debug-manager/start.c
==============================================================================
--- trunk/plugins/debug-manager/start.c	(original)
+++ trunk/plugins/debug-manager/start.c	Mon Apr 28 19:49:42 2008
@@ -125,30 +125,13 @@
 
 	DmaDebuggerQueue *debugger;
 
-	gboolean run_in_terminal;
 	gboolean stop_at_beginning;
-
- 	GList *source_dirs;
-	GList *environment_vars;
-	GList *recent_target;
-	GList *recent_dirs;
-	GList *recent_args;
+	GList *source_dirs;
 };
 
 /* Widgets found in glade file
  *---------------------------------------------------------------------------*/
 
-#define PARAMETER_DIALOG "parameter_dialog"
-#define TERMINAL_CHECK_BUTTON "parameter_run_in_term_check"
-#define STOP_AT_BEGINNING_CHECK_BUTTON "stop_at_beginning_check"
-#define PARAMETER_COMBO "parameter_combo"
-#define TARGET_COMBO "target_combo"
-#define TARGET_SELECT_SIGNAL "on_select_target_clicked"
-#define ADD_VAR_BUTTON "add_button"
-#define REMOVE_VAR_BUTTON "remove_button"
-#define VAR_TREEVIEW "environment_treeview"
-#define DIR_CHOOSER "working_dir_chooser"
-
 #define ADD_SOURCE_DIALOG "source_paths_dialog"
 #define SOURCE_ENTRY "src_entry"
 #define SOURCE_LIST "src_clist"
@@ -157,9 +140,17 @@
 #define UP_BUTTON "up_button"
 #define DOWN_BUTTON "down_button"
 
-#define ANJUTA_RESPONSE_SELECT_TARGET 0
+/* Constants
+ *---------------------------------------------------------------------------*/
 
-#define MAX_RECENT_ITEM		12
+#define RUN_PROGRAM_URI	"run_program_uri"
+#define RUN_PROGRAM_ARGS "run_program_args"
+#define RUN_PROGRAM_DIR	"run_program_directory"
+#define RUN_PROGRAM_ENV	"run_program_environment"
+#define RUN_PROGRAM_NEED_TERM	"run_program_need_terminal"
+
+#define RUN_PROGRAM_ACTION_GROUP "ActionGroupRun"
+#define RUN_PROGRAM_PARAMETER_ACTION "ActionProgramParameters"
 
 static void attach_process_clear (AttachProcess * ap, gint ClearRequest);
 
@@ -300,89 +291,26 @@
  *---------------------------------------------------------------------------*/
 
 static void
-anjuta_session_set_limited_string_list (AnjutaSession *session, const gchar *section, const gchar *key, GList **value)
-{
-	GList *node;
-	
-	while ((node = g_list_nth (*value, MAX_RECENT_ITEM)) != NULL)
-	{
-		g_free (node->data);
-		*value = g_list_delete_link (*value, node);
-	}
-	anjuta_session_set_string_list (session, section, key, *value);
-}
-
-static void
 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *self)
 {
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 
-	anjuta_session_set_limited_string_list (session, "Debugger", "Program arguments", &self->recent_args);
-	anjuta_session_set_limited_string_list (session, "Debugger", "Program uri", &self->recent_target);
-	anjuta_session_set_int (session, "Execution", "Run in terminal", self->run_in_terminal + 1);
 	anjuta_session_set_int (session, "Debugger", "Stop at beginning", self->stop_at_beginning + 1);
-	anjuta_session_set_string_list (session, "Debugger", "Source directories", self->source_dirs);
-	anjuta_session_set_string_list (session, "Debugger", "Working directories", self->recent_dirs);
-	anjuta_session_set_string_list (session, "Debugger", "Environment variables", self->environment_vars);
 }
 
 static void on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *self)
 {
-    gint run_in_terminal;
 	gint stop_at_beginning;
 
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 
- 	if (self->recent_args != NULL)
- 	{		
- 		g_list_foreach (self->recent_args, (GFunc)g_free, NULL);
- 		g_list_free (self->recent_args);
- 	}
- 	self->recent_args = anjuta_session_get_string_list (session, "Debugger", "Program arguments");
-
- 	if (self->recent_target != NULL)
- 	{		
- 		g_list_foreach (self->recent_target, (GFunc)g_free, NULL);
- 		g_list_free (self->recent_target);
- 	}
- 	self->recent_target = anjuta_session_get_string_list (session, "Debugger", "Program uri");
-	
-	/* The flag is store as 1 == FALSE, 2 == TRUE */
-	run_in_terminal = anjuta_session_get_int (session, "Execution", "Run in terminal");
-	if (run_in_terminal == 0)
-		self->run_in_terminal = TRUE;	/* Default value */
-	else
-		self->run_in_terminal = run_in_terminal - 1;
-	
 	stop_at_beginning = anjuta_session_get_int (session, "Debugger", "Stop at beginning");
 	if (stop_at_beginning == 0)
 		self->stop_at_beginning = TRUE;	/* Default value */
 	else
 		self->stop_at_beginning = stop_at_beginning - 1;
-	
-	/* Initialize source_dirs */
- 	if (self->source_dirs != NULL)
- 	{		
- 		g_list_foreach (self->source_dirs, (GFunc)g_free, NULL);
- 		g_list_free (self->source_dirs);
- 	}
- 	self->source_dirs = anjuta_session_get_string_list (session, "Debugger", "Source directories");
-	
- 	if (self->recent_dirs != NULL)
- 	{		
- 		g_list_foreach (self->recent_dirs, (GFunc)g_free, NULL);
- 		g_list_free (self->recent_dirs);
- 	}
- 	self->recent_dirs = anjuta_session_get_string_list (session, "Debugger", "Working directories");
-
- 	if (self->environment_vars != NULL)
- 	{		
- 		g_list_foreach (self->environment_vars, (GFunc)g_free, NULL);
- 		g_list_free (self->environment_vars);
- 	}
- 	self->environment_vars = anjuta_session_get_string_list (session, "Debugger", "Environment variables");
 }
 
 /* Attach to process private functions
@@ -920,19 +848,31 @@
 /* Load file private functions
  *---------------------------------------------------------------------------*/
 
+static void
+show_parameters_dialog (DmaStart *this)
+{
+	AnjutaUI *ui;
+	GtkAction *action;
+	
+	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this->plugin)->shell, NULL);
+	action = anjuta_ui_get_action (ui, RUN_PROGRAM_ACTION_GROUP, RUN_PROGRAM_PARAMETER_ACTION);
+	if (action != NULL)
+	{
+		gtk_action_activate (action);
+	}
+}
+
 static gboolean
-dma_start_load_uri (DmaStart *this)
+dma_start_load_uri (DmaStart *this, const gchar *target)
 {
 	GList *search_dirs;
 	GnomeVFSURI *vfs_uri;
 	gchar *mime_type;
 	gchar *filename;
 
-	if (this->recent_target == NULL) return FALSE;	/* Missing URI */
-	
 	if (!dma_quit_debugger (this)) return FALSE;
 	
-	vfs_uri = gnome_vfs_uri_new ((const gchar *)(this->recent_target->data));
+	vfs_uri = gnome_vfs_uri_new (target);
 		
 	g_return_val_if_fail (vfs_uri != NULL, TRUE);
 	
@@ -940,19 +880,19 @@
 
 	if (save_all_files_and_continue (this->plugin))
 	{
-		build_target (this->plugin, (const gchar *)(this->recent_target->data));
+		build_target (this->plugin, (const gchar *)target);
 	}
 	
 	search_dirs = get_source_directories (this->plugin);
 	
-	mime_type = gnome_vfs_get_mime_type ((const gchar *)(this->recent_target->data));
+	mime_type = gnome_vfs_get_mime_type ((const gchar *)target);
 	if (mime_type == NULL)
 	{
 		anjuta_util_dialog_error(GTK_WINDOW (this->plugin->shell),
-				_("Unable to open %s. Debugger cannot start."), (const gchar *)(this->recent_target->data));
+				_("Unable to open %s. Debugger cannot start."), target);
 		return FALSE;
 	}
-	filename = gnome_vfs_get_local_path_from_uri ((const gchar *)(this->recent_target->data));
+	filename = gnome_vfs_get_local_path_from_uri (target);
 	
 	dma_queue_load (this->debugger, filename, mime_type, this->source_dirs);
 	
@@ -964,101 +904,10 @@
 	return TRUE;
 }
 
-/* Run program dialog
+/* Add source dialog
  *---------------------------------------------------------------------------*/
 
 static void
-on_select_target (GtkButton *button, gpointer user_data)
-{
-	gtk_dialog_response (GTK_DIALOG (user_data), ANJUTA_RESPONSE_SELECT_TARGET);
-}
-
-static void
-on_environment_add_button (GtkButton *button, GtkTreeView *view)
-{
-	GtkTreeIter iter;
-	GtkListStore *model;
-	GtkTreeViewColumn *column;
-	GtkTreePath *path;
-		
-	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
-	gtk_list_store_append (model, &iter);
-	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
-	column = gtk_tree_view_get_column (view, 0);
-	gtk_tree_view_set_cursor (view, path, column ,TRUE);
-	gtk_tree_path_free (path);
-}
-
-static void
-on_environment_remove_button (GtkButton *button, GtkTreeView *view)
-{
-	GtkTreeIter iter;
-	GtkTreeSelection* sel;
-
-	sel = gtk_tree_view_get_selection (view);
-	if (gtk_tree_selection_get_selected (sel, NULL, &iter))
-	{
-		GtkListStore *model;
-		model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
-		
-		gtk_list_store_remove (model, &iter);
-	}
-}
-
-static void
-on_environment_variable_edited (GtkCellRendererText *cell,
-						  gchar *path,
-                          gchar *text,
-                          GtkTreeView *view)
-{
-	GtkTreeIter iter;
-	GtkListStore *model;
-	
-	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));	
-	if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
-	{
-		GtkTreeViewColumn *column;
-		GtkTreePath *path;
-		gtk_list_store_set (model, &iter, VARIABLE_COLUMN, text, -1);		
-		path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
-		column = gtk_tree_view_get_column (view, 1);
-		gtk_tree_view_set_cursor (view, path, column ,TRUE);
-	}
-}
-
-static void
-on_environment_selection_changed (GtkTreeSelection *selection, GtkWidget *button)
-{
-	gtk_widget_set_sensitive (button, gtk_tree_selection_get_selected (selection, NULL, NULL));
-}
-
-static void
-on_environment_value_edited (GtkCellRendererText *cell,
-						  gchar *path,
-                          gchar *text,
-                          GtkTreeView *view)
-{
-	GtkTreeIter iter;
-	GtkListStore *model;
-	
-	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));	
-	if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
-	{
-		gtk_list_store_set (model, &iter, VALUE_COLUMN, text, -1);		
-	}
-}
-
-static void
-on_add_string_in_model (gpointer data, gpointer user_data)
-{
-	GtkListStore* model = (GtkListStore *)user_data;
-	GtkTreeIter iter;
-	
-	gtk_list_store_append (model, &iter);
-	gtk_list_store_set (model, &iter, 0, (const gchar *)data, -1);
-}
-
-static void
 on_add_uri_in_model (gpointer data, gpointer user_data)
 {
 	GtkListStore* model = (GtkListStore *)user_data;
@@ -1071,298 +920,6 @@
 	g_free (local);
 }
 
-static void
-on_add_variable_in_model (gpointer data, gpointer user_data)
-{
-	GtkListStore* model = (GtkListStore *)user_data;
-	GtkTreeIter iter;
-	gchar **var;
-	
-	var = g_strsplit ((const gchar *)data, "=", 2);
-
-	if (var)
-	{
-		gtk_list_store_append (model, &iter);
-		gtk_list_store_set (model, &iter, 0, var[0], 1, var[1], -1);
-		g_strfreev (var);
-	}
-}
-
-static void
-on_add_directory_in_chooser (gpointer data, gpointer user_data)
-{
-	GtkFileChooser* chooser = (GtkFileChooser *)user_data;
-	gchar *local;
-
-	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
-	gtk_file_chooser_add_shortcut_folder (chooser, (const gchar *)local, NULL);
-	g_free (local);
-}
-
-static gboolean
-on_add_variable_in_list (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
-{
-	GList** list = (GList **)user_data;
-	gchar* name;
-	gchar* value;
-
-	gtk_tree_model_get (model, iter, 0, &name, 1, &value, -1);
-	*list = g_list_prepend (*list, g_strconcat(name, "=", value, NULL));
-	g_free (name);
-	g_free (value);
-	
-	return FALSE;
-}
-
-static gboolean
-dma_set_parameters (DmaStart *this)
-{
-	GladeXML *gxml;
-	GtkWidget *dlg;
-	GtkWindow *parent;
-	GtkToggleButton *term;
-	GtkToggleButton *stop_at_beginning;
-	GtkComboBox *params;
-	GtkComboBox *target;
-	gint response;
-	GtkTreeModel* model;
-	GtkTreeView *vars;
-	GtkFileChooser *dirs;
-	GtkCellRenderer *renderer;	
-	GtkTreeViewColumn *column;
-	GtkTreeSelection *selection;
-	GObject *button;
-	GValue value = {0,};
-	const gchar *project_root_uri;
-	
-	parent = GTK_WINDOW (this->plugin->shell);
-	gxml = glade_xml_new (GLADE_FILE, PARAMETER_DIALOG, NULL);
-	if (gxml == NULL)
-	{
-		anjuta_util_dialog_error(parent, _("Missing file %s"), GLADE_FILE);
-		return FALSE;
-	}
-		
-	dlg = glade_xml_get_widget (gxml, PARAMETER_DIALOG);
-	term = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gxml, TERMINAL_CHECK_BUTTON));
-	stop_at_beginning = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gxml, STOP_AT_BEGINNING_CHECK_BUTTON));
-	params = GTK_COMBO_BOX (glade_xml_get_widget (gxml, PARAMETER_COMBO));
-	target = GTK_COMBO_BOX (glade_xml_get_widget (gxml, TARGET_COMBO));
-	vars = GTK_TREE_VIEW (glade_xml_get_widget (gxml, VAR_TREEVIEW));
-	dirs = GTK_FILE_CHOOSER (glade_xml_get_widget (gxml, DIR_CHOOSER));
-
-	/* Connect signals */	
-	glade_xml_signal_connect_data (gxml, TARGET_SELECT_SIGNAL, GTK_SIGNAL_FUNC (on_select_target), dlg);
-	button = G_OBJECT (glade_xml_get_widget (gxml, ADD_VAR_BUTTON));
-	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_add_button), vars);
-	button = G_OBJECT (glade_xml_get_widget (gxml, REMOVE_VAR_BUTTON));
-	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_remove_button), vars);
-	selection = gtk_tree_view_get_selection (vars);
-	g_signal_connect (selection, "changed", G_CALLBACK (on_environment_selection_changed), GTK_WIDGET (button));
-	
-	g_object_unref (gxml);
-
-	/* Fill parameter combo box */
-	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
-	gtk_combo_box_set_model (params, model);
-	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(params), 0);
-	g_list_foreach (this->recent_args, on_add_string_in_model, model);
-	if (this->recent_args != NULL)
-	{
-		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (params)->child), (const char *)this->recent_args->data);
-	}
-	g_object_unref (model);
-
-	/* Fill target combo box */
-	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
-	gtk_combo_box_set_model (target, model);
-	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(target), 0);
-	g_list_foreach (this->recent_target, on_add_uri_in_model, model);
-
-    anjuta_shell_get_value (this->plugin->shell, "project_root_uri", &value, NULL);
-	project_root_uri = G_VALUE_HOLDS_STRING (&value) ? g_value_get_string (&value) : NULL;
-	if (project_root_uri != NULL)
-	{
-		/* One project loaded, get all executable target */
-		IAnjutaProjectManager *pm;
-		GList *exec_targets = NULL;
-			
-		pm = anjuta_shell_get_interface (this->plugin->shell,
-										 IAnjutaProjectManager, NULL);
-		if (pm != NULL)
-		{
-			exec_targets = ianjuta_project_manager_get_targets (pm,
-							 IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE,
-							 NULL);
-		}
-		if (exec_targets != NULL)
-		{
-			GList *node;
-
-			for (node = exec_targets; node; node = g_list_next (node))
-			{
-				GList *target;
-				for (target = this->recent_target; target; target = g_list_next (target))
-				{
-					if (strcmp ((const gchar *)target->data, node->data) == 0) break;
-				}
-				if (target == NULL)
-				{
-					on_add_uri_in_model (node->data, model);
-					/*gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-					gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, node->data, -1);*/
-				}
-				g_free (node->data);
-			}
-			g_list_free (exec_targets);
-		}
-	}
-	g_object_unref (model);
-
-	if (this->recent_target != NULL)
-	{
-		gchar *local;
-		
-		local = gnome_vfs_get_local_path_from_uri ((const char *)this->recent_target->data);
-		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), local);
-		g_free (local);
-	}
-	/* Fill working directory list */
-	g_list_foreach (this->recent_dirs, on_add_directory_in_chooser, dirs);	
-	
-	/* Fill environment variable list */
-	model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); 
-	gtk_tree_view_set_model (vars, model);
-	g_list_foreach (this->environment_vars, on_add_variable_in_model, model);
-	g_object_unref (model);
-	
-	renderer = gtk_cell_renderer_text_new ();
-	g_object_set(renderer, "editable", TRUE, NULL);	
-	g_signal_connect(renderer, "edited", (GCallback) on_environment_variable_edited, vars);
-	column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", 0, NULL);
-	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-	gtk_tree_view_append_column (vars, column);
-	renderer = gtk_cell_renderer_text_new ();
-	g_object_set(renderer, "editable", TRUE, NULL);	
-	g_signal_connect(renderer, "edited", (GCallback) on_environment_value_edited, vars);
-	column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer, "text", 1, NULL);
-	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-	gtk_tree_view_append_column (vars, column);
-	
-	/* Set terminal option */	
-	if (this->run_in_terminal) gtk_toggle_button_set_active (term, TRUE);
-	if (this->stop_at_beginning) gtk_toggle_button_set_active (stop_at_beginning, TRUE);
-	
-	gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
-	
-	/* Run dialog */
-	for (;;)
-	{
-		response = gtk_dialog_run (GTK_DIALOG (dlg));
-		switch (response)
-		{
-		case GTK_RESPONSE_OK:
-		case GTK_RESPONSE_APPLY:
-		{
-			const gchar *arg;
-			const gchar *filename;
-			gchar *uri;
-			GList *find;
-			
-			arg = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (params)->child));
-			if (arg != NULL)
-			{
-				find = g_list_find_custom(this->recent_args, arg, (GCompareFunc)strcmp);
-				if (find)
-				{
-					g_free (find->data);
-					this->recent_args = g_list_delete_link (this->recent_args, find);
-				}
-				this->recent_args = g_list_prepend (this->recent_args, g_strdup (arg));
-			}	
-			
-			filename = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (target)->child));
-			if (filename != NULL)
-			{
-				uri = gnome_vfs_get_uri_from_local_path (filename);
-				if (uri != NULL)
-				{
-					find = g_list_find_custom (this->recent_target, uri, (GCompareFunc)strcmp);
-					if (find)
-					{
-						g_free (find->data);
-						this->recent_target = g_list_delete_link (this->recent_target, find);
-					}
-					this->recent_target = g_list_prepend (this->recent_target, uri);
-				}
-			}
-
-			uri = gtk_file_chooser_get_uri (dirs);
-			if (uri != NULL)
-			{
-				find = g_list_find_custom(this->recent_dirs, uri, (GCompareFunc)strcmp);
-				if (find)
-				{
-					g_free (find->data);
-					this->recent_dirs = g_list_delete_link (this->recent_dirs, find);
-				}
-				this->recent_dirs = g_list_prepend (this->recent_dirs, uri);
-			}
-			
-			g_list_foreach (this->environment_vars, (GFunc)g_free, NULL);
-			g_list_free (this->environment_vars);
-			this->environment_vars = NULL;
-			model = gtk_tree_view_get_model (vars);			
-			gtk_tree_model_foreach (GTK_TREE_MODEL (model), on_add_variable_in_list, &this->environment_vars);
-			this->environment_vars = g_list_reverse (this->environment_vars);
-			
-			this->run_in_terminal = gtk_toggle_button_get_active (term);
-			this->stop_at_beginning = gtk_toggle_button_get_active (stop_at_beginning);
-			break;
-		}
-		case ANJUTA_RESPONSE_SELECT_TARGET:
-		{
-			GtkWidget *sel_dlg = gtk_file_chooser_dialog_new (
-				_("Load Target to debug"), GTK_WINDOW (dlg),
-				 GTK_FILE_CHOOSER_ACTION_OPEN,
-				 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
-				 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
-			gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(sel_dlg), FALSE);
-			gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (sel_dlg), TRUE);
-
-			GtkFileFilter *filter = gtk_file_filter_new ();
-			gtk_file_filter_set_name (filter, _("All files"));
-			gtk_file_filter_add_pattern (filter, "*");
-			gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (sel_dlg), filter);
-
-			//gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
-			
-			response = gtk_dialog_run (GTK_DIALOG (sel_dlg));
-
-			if (response == GTK_RESPONSE_OK)
-			{
-				gchar* filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (sel_dlg));
-
-				gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), filename);
-				g_free (filename);
-			}
-			gtk_widget_destroy (GTK_WIDGET (sel_dlg));
-
-			continue;
-		}
-		default:
-			break;
-		}
-		break;
-	}
-	gtk_widget_destroy (dlg);
-	
-	return response == GTK_RESPONSE_OK;
-}
-
-/* Add source dialog
- *---------------------------------------------------------------------------*/
-
 static gboolean
 on_add_source_in_list (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
 {
@@ -1576,31 +1133,54 @@
 gboolean
 dma_run_target (DmaStart *this)
 {
-	if (!dma_set_parameters (this)) return FALSE;
-    
-	return dma_rerun_target (this);
-}
-
-gboolean
-dma_rerun_target (DmaStart *this)
-{
+	gchar *dir_uri;
 	gchar *dir;
+	gchar *target;
+	gchar **env;
+	gchar *args;
+	gboolean run_in_terminal;
+
+	anjuta_shell_get (ANJUTA_PLUGIN (this->plugin)->shell,
+	 				  RUN_PROGRAM_URI, G_TYPE_STRING, &target, NULL);	
 	
-	if (!dma_start_load_uri (this)) return FALSE;
+	if (target == NULL)
+	{
+		/* Launch parameter dialog to get a target name */
+		show_parameters_dialog (this);
+		anjuta_shell_get (ANJUTA_PLUGIN (this->plugin)->shell,
+	 				  RUN_PROGRAM_URI, G_TYPE_STRING, &target, NULL);
+		/* No target set by user */
+		if (target == NULL) return FALSE;
+	}
+	
+	if (!dma_start_load_uri (this, target)) return FALSE;
+	g_free (target);
 
-	if (this->recent_dirs != NULL)
+	anjuta_shell_get (ANJUTA_PLUGIN (this->plugin)->shell,
+	 				  RUN_PROGRAM_DIR, G_TYPE_STRING, &dir_uri,
+					  RUN_PROGRAM_ARGS, G_TYPE_STRING, &args,
+					  RUN_PROGRAM_ENV, G_TYPE_STRV, &env,
+					  RUN_PROGRAM_NEED_TERM, G_TYPE_BOOLEAN, &run_in_terminal,
+					  NULL);	
+	
+	if (dir_uri != NULL)
 	{
-		dir = gnome_vfs_get_local_path_from_uri ((const gchar *)(this->recent_dirs->data));
+		dir = gnome_vfs_get_local_path_from_uri (dir_uri);
+		g_free (dir_uri);
 	}
 	else
 	{
 		dir = NULL;
 	}
+	
 	dma_queue_set_working_directory (this->debugger, dir);
 	g_free (dir);
-	dma_queue_set_environment (this->debugger, this->environment_vars);
 	
-	dma_queue_start (this->debugger, this->recent_args == NULL ? "" : (const char *)this->recent_args->data,this->run_in_terminal, this->stop_at_beginning);
+	dma_queue_set_environment (this->debugger, env);
+	g_strfreev (env);
+	
+	dma_queue_start (this->debugger, args, run_in_terminal, FALSE);
+	g_free (args);
 	
 	return TRUE;
 }
@@ -1634,16 +1214,6 @@
     g_signal_handlers_disconnect_by_func (this->plugin->shell, G_CALLBACK (on_session_load), this);
 	g_list_foreach (this->source_dirs, (GFunc)g_free, NULL);
 	g_list_free (this->source_dirs);
-	g_list_foreach (this->recent_target, (GFunc)g_free, NULL);
-	g_list_free (this->recent_target);
-	g_list_foreach (this->recent_args, (GFunc)g_free, NULL);
-	g_list_free (this->recent_args);
-	g_list_foreach (this->recent_args, (GFunc)g_free, NULL);
-	g_list_free (this->recent_args);
-	g_list_foreach (this->recent_dirs, (GFunc)g_free, NULL);
-	g_list_free (this->recent_dirs);
-	g_list_foreach (this->environment_vars, (GFunc)g_free, NULL);
-	g_list_free (this->environment_vars);
 	g_free (this);
 }
 

Modified: trunk/plugins/gdb/debugger.c
==============================================================================
--- trunk/plugins/gdb/debugger.c	(original)
+++ trunk/plugins/gdb/debugger.c	Mon Apr 28 19:49:42 2008
@@ -746,7 +746,7 @@
 }
 
 gboolean
-debugger_set_environment (Debugger *debugger, const GList *variables)
+debugger_set_environment (Debugger *debugger, gchar **variables)
 {
 	gchar *buff;
 	GList *node;
@@ -755,11 +755,14 @@
 
 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
 
-	for (node = variables; node != NULL; node = g_list_next (node))
+	if (variables != NULL)
 	{
-		buff = g_strdup_printf("set environment %s", (const char *)node->data);
-		debugger_queue_command (debugger, buff, FALSE, FALSE, NULL, NULL, NULL);
-		g_free (buff);
+		for (; *variables != NULL; variables++)
+		{
+			buff = g_strdup_printf("set environment %s", *variables);
+			debugger_queue_command (debugger, buff, FALSE, FALSE, NULL, NULL, NULL);
+			g_free (buff);
+		}
 	}
 	
 	return TRUE;

Modified: trunk/plugins/gdb/debugger.h
==============================================================================
--- trunk/plugins/gdb/debugger.h	(original)
+++ trunk/plugins/gdb/debugger.h	Mon Apr 28 19:49:42 2008
@@ -109,7 +109,7 @@
 
 /* Environment */
 gboolean debugger_set_working_directory (Debugger *debugger, const gchar *directory);
-gboolean debugger_set_environment (Debugger *debugger, const GList *variables);
+gboolean debugger_set_environment (Debugger *debugger, gchar **variables);
 
 /* Execution */
 void debugger_start_program (Debugger *debugger, const gchar* args, const gchar* tty, gboolean stop);

Modified: trunk/plugins/gdb/plugin.c
==============================================================================
--- trunk/plugins/gdb/plugin.c	(original)
+++ trunk/plugins/gdb/plugin.c	Mon Apr 28 19:49:42 2008
@@ -360,7 +360,7 @@
 }
 
 static gboolean
-idebugger_set_environment (IAnjutaDebugger *plugin, const GList *variables, GError **err)
+idebugger_set_environment (IAnjutaDebugger *plugin, gchar **variables, GError **err)
 {
 	GdbPlugin *self = ANJUTA_PLUGIN_GDB (plugin);
 

Added: trunk/plugins/run-program/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/Makefile.am	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,51 @@
+# Plugin glade file
+anjuta_gladedir = $(anjuta_glade_dir)
+anjuta_glade_DATA = anjuta-run-program.glade
+
+# Plugin UI file
+anjuta_uidir = $(anjuta_ui_dir)
+anjuta_ui_DATA =  anjuta-run-program.ui
+
+# Plugin Icon file
+anjuta_pixmapsdir = $(anjuta_image_dir)
+anjuta_pixmaps_DATA = \
+        anjuta-run-program-48.png
+
+# Plugin description file
+plugin_in_files = anjuta-run-program.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+anjuta_plugindir = $(anjuta_plugin_dir)
+anjuta_plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+plugindir = $(anjuta_plugin_dir)
+plugin_LTLIBRARIES = libanjuta-run-program.la
+
+AM_CPPFLAGS= \
+	$(WARN_CFLAGS) \
+	$(DEPRECATED_FLAGS) \
+	$(LIBANJUTA_CFLAGS)
+
+libanjuta_run_program_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
+
+libanjuta_run_program_la_LIBADD = \
+	$(GNOME_UI_LIBS) \
+	$(GLADE_LIBS) \
+	$(LIBANJUTA_LIBS)
+
+libanjuta_run_program_la_SOURCES = \
+	plugin.c \
+	plugin.h \
+	parameters.c \
+	parameters.h \
+	execute.c \
+	execute.h \
+	utils.c \
+	utils.h
+
+EXTRA_DIST = \
+	$(plugin_in_files) \
+	$(anjuta_pixmaps_DATA) \
+	$(anjuta_plugin_DATA) \
+	$(anjuta_ui_DATA) \
+	$(anjuta_glade_DATA)

Added: trunk/plugins/run-program/anjuta-run-program-48.png
==============================================================================
Binary file. No diff available.

Added: trunk/plugins/run-program/anjuta-run-program.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/anjuta-run-program.glade	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
+<glade-interface>
+  <widget class="GtkDialog" id="parameters_dialog">
+    <property name="title" translatable="yes">Program Parameters</property>
+    <property name="modal">True</property>
+    <property name="default_width">400</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox7">
+        <property name="visible">True</property>
+        <property name="spacing">6</property>
+        <child>
+          <widget class="GtkTable" id="table34">
+            <property name="visible">True</property>
+            <property name="border_width">6</property>
+            <property name="n_rows">5</property>
+            <property name="n_columns">3</property>
+            <property name="column_spacing">6</property>
+            <property name="row_spacing">6</property>
+            <child>
+              <widget class="GtkCheckButton" id="parameter_run_in_term_check">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label" translatable="yes">Run In Terminal</property>
+                <property name="use_underline">True</property>
+                <property name="response_id">0</property>
+                <property name="draw_indicator">True</property>
+              </widget>
+              <packing>
+                <property name="right_attach">3</property>
+                <property name="top_attach">4</property>
+                <property name="bottom_attach">5</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkComboBoxEntry" id="parameter_combo">
+                <property name="visible">True</property>
+                <child internal-child="entry">
+                  <widget class="GtkEntry" id="comboboxentry-entry2">
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label12354">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Arguments:</property>
+              </widget>
+              <packing>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkComboBoxEntry" id="target_combo">
+                <property name="visible">True</property>
+                <child internal-child="entry">
+                  <widget class="GtkEntry" id="comboboxentry-entry1">
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="y_options"></property>
+                <property name="y_padding">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="target_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="label">gtk-open</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label12353">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Program:</property>
+              </widget>
+              <packing>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="events"></property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Working Directory:</property>
+              </widget>
+              <packing>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkFileChooserButton" id="working_dir_chooser">
+                <property name="visible">True</property>
+                <property name="events"></property>
+                <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+                <property name="title" translatable="yes">Choose a working directory</property>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <child>
+                  <widget class="GtkHBox" id="hbox6">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">5</property>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="scrolledwindow3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="shadow_type">GTK_SHADOW_OUT</property>
+                        <child>
+                          <widget class="GtkTreeView" id="environment_treeview">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkVButtonBox" id="vbuttonbox2">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="spacing">5</property>
+                        <property name="layout_style">GTK_BUTTONBOX_START</property>
+                        <child>
+                          <widget class="GtkButton" id="add_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-new</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="edit_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-edit</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="remove_button">
+                            <property name="visible">True</property>
+                            <property name="sensitive">False</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-delete</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="label" translatable="yes">Environment Variables:</property>
+                  </widget>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="right_attach">3</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="padding">5</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area7">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="cancel_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="ok_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-apply</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-10</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/plugins/run-program/anjuta-run-program.plugin.in
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/anjuta-run-program.plugin.in	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,5 @@
+[Anjuta Plugin]
+_Name=Run Program
+_Description=Allow to execute program without debugger.
+Location=anjuta-run-program:RunProgramPlugin
+Icon=anjuta-run-program-48.png

Added: trunk/plugins/run-program/anjuta-run-program.ui
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/anjuta-run-program.ui	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,18 @@
+<!--*- xml -*-->
+<ui>
+	<menubar name="MenuMain">
+		<placeholder name="PlaceHolderRunMenus">
+			<menu name="MenuRun" action="ActionMenuRun">
+				<placeholder name="PlaceHolderRunCommands">
+					<menuitem name="RunProgram" action="ActionRunProgram" />
+				</placeholder>
+				<separator name="separator2"/>
+				<placeholder name="PlaceHolderStopCommands">
+					<menuitem name="StopProgram" action="ActionStopProgram" />
+				</placeholder>
+				<separator name="separator1"/>
+				<menuitem name="ProgramParameters" action="ActionProgramParameters" />
+			</menu>
+		</placeholder>
+	</menubar>
+</ui>

Added: trunk/plugins/run-program/execute.c
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/execute.c	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,425 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    execute.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/*
+ * Run and Stop program
+ *---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "execute.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/interfaces/ianjuta-terminal.h>
+
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+#include <signal.h>
+
+/* Constants
+ *---------------------------------------------------------------------------*/
+
+#define PREF_USE_SB "build.use_scratchbox"
+#define PREF_SB_PATH "build.scratchbox.path"
+
+
+/*----------------------------------------------------------------------------
+ * Type definitions
+ */
+
+struct _RunProgramChild
+{
+	GPid pid;
+	guint source;
+	gboolean use_signal;
+	gboolean terminated;
+};
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_child_terminated (GPid pid, gint status, gpointer user_data);
+
+static void
+run_plugin_child_free (RunProgramPlugin *plugin, GPid pid)
+{
+	GList *child;
+	
+	for (child = g_list_first (plugin->child); child != NULL; child = g_list_next (child))
+	{
+		if (((RunProgramChild *)child->data)->pid == pid)
+		{
+			if (((RunProgramChild *)child->data)->use_signal)
+			{
+				g_return_if_fail (plugin->child_exited_connection > 0);
+				plugin->child_exited_connection--;
+				if (plugin->child_exited_connection == 0)
+				{
+					IAnjutaTerminal *term;
+		
+					term = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+													   IAnjutaTerminal, NULL);
+					g_signal_handlers_disconnect_by_func (term, on_child_terminated, plugin);
+				}
+			}
+			else if (((RunProgramChild *)child->data)->source)
+			{
+				g_source_remove (((RunProgramChild *)child->data)->source);
+			}
+			g_free (child->data);
+			plugin->child = g_list_delete_link (plugin->child, child);
+			break;
+		}
+	}
+
+	run_plugin_update_menu_sensitivity (plugin);
+}
+
+static void
+on_child_terminated (GPid pid, gint status, gpointer user_data)
+{
+	RunProgramPlugin *plugin = (RunProgramPlugin *)user_data;
+	
+	run_plugin_child_free (plugin, pid);
+}
+
+
+static void
+on_child_terminated_signal (IAnjutaTerminal *term, GPid pid, gint status, gpointer user_data)
+{
+	on_child_terminated (pid, status, user_data);
+}
+
+static gboolean
+get_local_executable_and_directory (RunProgramPlugin *plugin, gchar **local, gchar **dir)
+{
+	gchar *target = NULL;
+	gchar *dir_uri = NULL;
+	const gchar *err_msg;
+	
+	anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
+	 				  RUN_PROGRAM_DIR, G_TYPE_STRING, &dir_uri,
+					  RUN_PROGRAM_URI, G_TYPE_STRING, &target, NULL);
+	
+	if (target == NULL)
+	{
+		g_free (target);
+		g_free (dir_uri);
+		return FALSE;
+	}
+	else if ((*local = gnome_vfs_get_local_path_from_uri (target)) == NULL)
+	{
+		/* Only local program are supported */
+		err_msg = _("Program '%s' is not a local file");
+	}
+	else if ((dir_uri != NULL) && ((*dir = gnome_vfs_get_local_path_from_uri (dir_uri)) == NULL))
+	{
+		gchar *tmp;	
+		/* Only local directory are supported */
+		err_msg = _("Program directory '%s' is not local");
+		tmp = target;
+		target = dir_uri;
+		dir_uri = tmp;
+		g_free (*local);
+	}
+	else
+	{
+		g_free (target);
+		g_free (dir_uri);
+		target = *local;	
+
+		if (g_file_test (*local, G_FILE_TEST_EXISTS) == FALSE)
+		{
+			err_msg = _("Program '%s' does not exists");
+		}
+		else if (g_file_test (*local, G_FILE_TEST_IS_EXECUTABLE) == FALSE)
+		{
+			err_msg = _("Program '%s' does not have execution permission");
+		}
+		else
+		{
+			/* Return local executable */
+			return TRUE;
+		}
+	}
+			
+	anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), err_msg, target);
+	g_free (target);
+	g_free (dir_uri);
+	
+	return FALSE;
+}
+
+static GPid
+execute_with_terminal (RunProgramPlugin *plugin,
+					   const gchar *dir, const gchar *cmd, gchar **env)
+{
+	IAnjutaTerminal *term;
+	GPid pid = 0;
+		
+	term = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+										   IAnjutaTerminal, NULL);
+	if (term)
+	{
+		gchar* launcher_path = g_find_program_in_path("anjuta_launcher");
+		gchar *new_cmd;
+		RunProgramChild *child;
+	
+		if (launcher_path != NULL)
+		{
+			new_cmd = g_strconcat ("anjuta_launcher ", cmd, NULL);
+			g_free (launcher_path);
+		}
+		else
+		{
+			DEBUG_PRINT("Missing anjuta_launcher");
+			new_cmd = g_strdup (cmd);
+		}
+
+		if (plugin->child_exited_connection == 0)
+		{
+			g_signal_connect (term, "child-exited", G_CALLBACK (on_child_terminated_signal), plugin);
+		}
+		plugin->child_exited_connection++;
+		child = g_new0 (RunProgramChild, 1);
+		child->use_signal = TRUE;
+		plugin->child = g_list_prepend (plugin->child, child);
+		
+		pid = ianjuta_terminal_execute_command (term, dir, new_cmd, env, NULL);
+		child->pid = pid;
+		g_free (new_cmd);
+	}
+	
+	return pid;
+}
+
+static GPid
+execute_without_terminal (RunProgramPlugin *plugin,
+					   const gchar *dir, gchar *cmd, gchar **env)
+{
+	char *user_shell;
+	char * argv[4];
+	GPid pid;
+	RunProgramChild *child;
+	gsize len;
+	gchar **new_env;
+	gchar **old_env;
+	gchar **p;	
+	gint i;
+
+	/* Create environment variable array */
+	old_env = g_listenv();
+	len = old_env ? g_strv_length (old_env) : 0;
+	len += env ? g_strv_length (env) : 0;
+	len ++;	
+	new_env = g_new (char *, len);
+	
+	/* Remove some environment variables, Move other in new_env */
+	i = 0;
+	for (p = old_env; *p; p++)
+	{
+		const gchar *value;
+		
+		value = g_getenv (*p);
+		if (env != NULL)
+		{
+			gchar **q;
+		
+			for (q = env; *q; q++)
+			{
+				gsize len;
+				
+				len = strlen (*p);
+				if ((strlen (*q) > len + 1) &&
+					(strncmp (*q, *p, len) == 0) &&
+					(*q[len] == '='))
+				{
+					value = *q + len + 1;
+					break;
+				}
+			}
+		}
+		
+		new_env[i++] = g_strconcat (*p, "=", value, NULL);
+	}
+	g_strfreev (old_env);
+	
+	/* Add new user variable */
+	for (p = env; *p; p++)
+	{
+		new_env[i++] = g_strdup (*p);
+	}
+	new_env[i] = NULL;
+	
+	/* Run user program using in a shell */
+	user_shell = gnome_util_user_shell ();
+	argv[0] = user_shell;
+	argv[1] = "-c";
+	argv[2] = cmd;
+	argv[3] = NULL;
+
+	child = g_new0 (RunProgramChild, 1);
+	plugin->child = g_list_prepend (plugin->child, child);
+	
+	if (g_spawn_async_with_pipes (dir, argv, new_env, G_SPAWN_DO_NOT_REAP_CHILD,
+									NULL, NULL, &pid, NULL, NULL, NULL, NULL))
+	{
+		child->pid = pid;
+		child->source = g_child_watch_add (pid, on_child_terminated, plugin);
+	}
+	else
+	{
+		pid = 0;
+	}
+	
+	g_free (user_shell);
+	g_strfreev (new_env);
+	
+	return pid;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+run_plugin_run_program (RunProgramPlugin *plugin)
+{
+	gchar *target;
+	gchar *dir = NULL;
+	gchar *args = NULL;
+	gchar **env = NULL;
+	gchar *cmd;
+	gboolean run_in_terminal = 0;
+	AnjutaPreferences *prefs;
+	GPid pid;
+	
+	if (!get_local_executable_and_directory (plugin, &target, &dir))
+		return FALSE;
+	
+	/* Get other parameters from shell */
+	anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
+					RUN_PROGRAM_ARGS, G_TYPE_STRING, &args,
+					RUN_PROGRAM_ENV, G_TYPE_STRV, &env,
+					RUN_PROGRAM_NEED_TERM, G_TYPE_BOOLEAN, &run_in_terminal,
+					NULL);
+	
+	/* TODO: Check if target is up to date */
+
+	if (dir == NULL)
+		dir = g_path_get_dirname (target);
+	
+	if (args && strlen (args) > 0)
+		cmd = g_strconcat (target, " ", args, NULL);
+	else
+		cmd = g_strdup (target);
+	g_free (args);
+	g_free (target);
+
+	/* Take care of scratchbox */
+	prefs = anjuta_shell_get_preferences (ANJUTA_PLUGIN(plugin)->shell, NULL);
+	if (anjuta_preferences_get_int (prefs , PREF_USE_SB))
+	{
+		const gchar* sb_path = anjuta_preferences_get(prefs, PREF_SB_PATH);
+		/* we need to skip the /scratchbox/users part, maybe could be done more clever */
+		const gchar* real_dir = strstr(dir, "/home");
+		gchar* oldcmd = cmd;
+		gchar* olddir = dir;
+		
+		cmd = g_strdup_printf("%s/login -d %s \"%s\"", sb_path,
+									  real_dir, oldcmd);
+		g_free(oldcmd);
+		dir = g_strdup(real_dir);
+		g_free (olddir);
+	}
+	
+	if (run_in_terminal)
+	{
+		pid = execute_with_terminal (plugin, dir, cmd, env);
+		if (!pid)
+		{
+			pid = execute_without_terminal (plugin, dir, cmd, env);
+		}
+	}
+	else
+	{
+		pid = execute_without_terminal (plugin, dir, cmd, env);
+	}
+	
+	if (pid == 0)
+	{
+		anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
+								  "Unable to execute %s", cmd);
+	}
+	run_plugin_update_menu_sensitivity (plugin);
+	
+	g_free (dir);
+	g_strfreev (env);
+	g_free (cmd);
+
+	return TRUE;
+}
+
+gboolean
+run_plugin_kill_program (RunProgramPlugin *plugin, gboolean terminate)
+{
+	if (plugin->child != NULL)
+	{
+		RunProgramChild *child = (RunProgramChild *)plugin->child->data;
+		
+		if (!child->terminated && terminate)
+		{
+			kill (child->pid, SIGTERM);
+			child->terminated = TRUE;
+		}
+		else
+		{
+			kill (child->pid, SIGKILL);
+			run_plugin_child_free (plugin, child->pid);
+		}
+	}
+	
+	return TRUE;
+}
+
+void
+run_free_all_children (RunProgramPlugin *plugin)
+{
+	GList *child;
+	IAnjutaTerminal *term;
+
+	/* Remove terminal child-exited handle */
+	term = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+										IAnjutaTerminal, NULL);
+	g_signal_handlers_disconnect_by_func (term, on_child_terminated, plugin);
+	plugin->child_exited_connection = 0;
+
+	/* Remove all child-exited source */
+	for (child = g_list_first (plugin->child); child != NULL; child = g_list_next (child))
+	{
+		if (!((RunProgramChild *)child->data)->use_signal)
+		{
+			g_source_remove (((RunProgramChild *)child->data)->source);
+		}
+		g_free (child->data);
+	}
+	g_list_free (plugin->child);
+	plugin->child = NULL;
+}

Added: trunk/plugins/run-program/execute.h
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/execute.h	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,31 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    execute.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _EXECUTE_H_
+#define _EXECUTE_H_
+
+#include "plugin.h"
+
+gboolean run_plugin_run_program (RunProgramPlugin *plugin);
+gboolean run_plugin_kill_program (RunProgramPlugin *plugin, gboolean terminate);
+
+void run_free_all_children (RunProgramPlugin *plugin);
+
+#endif

Added: trunk/plugins/run-program/parameters.c
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/parameters.c	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,764 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    parameters.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/*
+ * Display and run program parameters dialog
+ *---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "parameters.h"
+
+#include "utils.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/interfaces/ianjuta-project-manager.h>
+
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+/*---------------------------------------------------------------------------*/
+
+#define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-run-program.ui"
+#define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-run-program.glade"
+
+#define PARAMETERS_DIALOG "parameters_dialog"
+#define TERMINAL_CHECK_BUTTON "parameter_run_in_term_check"
+#define PARAMETER_COMBO "parameter_combo"
+#define TARGET_COMBO "target_combo"
+#define VAR_TREEVIEW "environment_treeview"
+#define DIR_CHOOSER "working_dir_chooser"
+#define TARGET_BUTTON "target_button"
+#define ADD_VAR_BUTTON "add_button"
+#define REMOVE_VAR_BUTTON "remove_button"
+#define EDIT_VAR_BUTTON "edit_button"
+
+enum {
+	ENV_NAME_COLUMN = 0,
+	ENV_VALUE_COLUMN,
+	ENV_DEFAULT_VALUE_COLUMN,
+	ENV_COLOR_COLUMN,
+	ENV_N_COLUMNS
+};
+
+#define ENV_USER_COLOR	"black"
+#define ENV_DEFAULT_COLOR "gray"
+
+/* Type defintions
+ *---------------------------------------------------------------------------*/
+
+typedef struct _RunDialog RunDialog;
+
+struct _RunDialog
+{
+ 	GtkWidget *win;
+	
+	/* Child widgets */
+	GtkToggleButton *term;
+	GtkComboBox *args;
+	GtkComboBox *target;
+	GtkFileChooser *dirs;
+	GtkTreeView *vars;
+	GtkTreeModel* model;
+	GtkWidget *remove_button;
+	GtkWidget *edit_button;
+		
+	/* Plugin */
+	RunProgramPlugin *plugin;
+};
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_add_string_in_model (gpointer data, gpointer user_data)
+{
+	GtkListStore* model = (GtkListStore *)user_data;
+	GtkTreeIter iter;
+	
+	gtk_list_store_append (model, &iter);
+	gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, (const gchar *)data, -1);
+}
+
+static void
+on_add_uri_in_model (gpointer data, gpointer user_data)
+{
+	GtkListStore* model = (GtkListStore *)user_data;
+	GtkTreeIter iter;
+	gchar *local;
+	
+	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
+	gtk_list_store_append (model, &iter);
+	gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, local, -1);
+	g_free (local);
+}
+
+static void
+on_add_directory_in_chooser (gpointer data, gpointer user_data)
+{
+	GtkFileChooser* chooser = (GtkFileChooser *)user_data;
+	gchar *local;
+
+	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
+	gtk_file_chooser_add_shortcut_folder (chooser, (const gchar *)local, NULL);
+	g_free (local);
+}
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static void
+load_environment_variables (RunProgramPlugin *plugin, GtkListStore *store)
+{
+	GtkTreeIter iter;
+	gchar **var;
+	gchar **list;
+	
+	/* Load current environment variables */
+	list = g_listenv();
+	var = list;
+	if (var)
+	{
+		for (; *var != NULL; var++)
+		{
+			const gchar *value = g_getenv (*var);
+			gtk_list_store_prepend (store, &iter);
+			gtk_list_store_set (store, &iter,
+								ENV_NAME_COLUMN, *var,
+								ENV_VALUE_COLUMN, value,
+								ENV_DEFAULT_VALUE_COLUMN, value,
+								ENV_COLOR_COLUMN, ENV_DEFAULT_COLOR,
+								-1);
+		}
+	}
+	g_strfreev (list);
+	
+	/* Load user environment variables */
+	var = plugin->environment_vars;
+	if (var)
+	{
+		for (; *var != NULL; var++)
+		{
+			gchar ** value;
+			
+			value = g_strsplit (*var, "=", 2);
+			if (value)
+			{
+				if (run_plugin_gtk_tree_model_find_string (GTK_TREE_MODEL (store), 
+													NULL, &iter, ENV_NAME_COLUMN,
+													value[0]))
+				{
+					gtk_list_store_set (store, &iter,
+									ENV_VALUE_COLUMN, value[1],
+									ENV_COLOR_COLUMN, ENV_USER_COLOR,
+									-1);
+				}
+				else
+				{
+					gtk_list_store_prepend (store, &iter);
+					gtk_list_store_set (store, &iter,
+										ENV_NAME_COLUMN, value[0],
+										ENV_VALUE_COLUMN, value[1],
+										ENV_DEFAULT_VALUE_COLUMN, NULL,
+										ENV_COLOR_COLUMN, ENV_USER_COLOR,
+										-1);
+				}
+				g_strfreev (value);
+			}
+		}
+	}
+}
+
+static void
+save_environment_variables (RunProgramPlugin *plugin, GtkTreeModel *model)
+{
+	gchar **vars;
+	gboolean valid;
+	GtkTreeIter iter;
+	
+	/* Remove previous variables */
+	g_strfreev (plugin->environment_vars);
+	
+	/* Allocated a too big array: able to save all environment variables
+	 * while we need to save only variables modified by user but it
+	 * shouldn't be that big anyway and checking exactly which variable
+	 * need to be saved will take more time */
+	vars = g_new (gchar *,
+							gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) + 1);
+	plugin->environment_vars = vars;
+	
+	for (valid = gtk_tree_model_get_iter_first (model, &iter); valid; valid = gtk_tree_model_iter_next (model, &iter))
+	{
+		gchar *name;
+		gchar *value;
+		gchar *color;
+		
+		gtk_tree_model_get (model, &iter,
+							ENV_NAME_COLUMN, &name,
+							ENV_VALUE_COLUMN, &value,
+							ENV_COLOR_COLUMN, &color,
+							-1);
+		
+		/* Save only variables modified by user */
+		if (strcmp(color, ENV_USER_COLOR) == 0)
+		{
+			*vars = g_strconcat(name, "=", value, NULL);
+			vars++;
+		}
+		g_free (name);
+		g_free (value);
+		g_free (color);
+	}
+	*vars = NULL;
+}
+
+static void
+save_dialog_data (RunDialog* dlg)
+{
+	const gchar *arg;
+	const gchar *filename;
+	gchar *uri;
+	GList *find;
+	GtkTreeModel* model;
+	RunProgramPlugin *plugin = dlg->plugin;
+
+	/* Save arguments */
+	arg = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (dlg->args)->child));
+	if (arg != NULL)
+	{
+		find = g_list_find_custom(plugin->recent_args, arg, (GCompareFunc)strcmp);
+		if (find)
+		{
+			g_free (find->data);
+			plugin->recent_args = g_list_delete_link (plugin->recent_args, find);
+		}
+		plugin->recent_args = g_list_prepend (plugin->recent_args, g_strdup (arg));
+	}	
+
+	/* Save target */
+	filename = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (dlg->target)->child));
+	if ((filename != NULL) && (*filename != '\0'))
+	{
+		if (!g_path_is_absolute (filename))
+		{
+			gchar *abs_filename;
+			gchar *current_dir;
+			
+			current_dir = g_get_current_dir ();
+			abs_filename = g_build_filename (current_dir, filename, NULL);
+			g_free (current_dir);
+			uri = gnome_vfs_get_uri_from_local_path (abs_filename);
+			g_free (abs_filename);
+		}
+		else
+		{
+			uri = gnome_vfs_get_uri_from_local_path (filename);
+		}
+		if (uri != NULL)
+		{
+			find = g_list_find_custom (plugin->recent_target, uri, (GCompareFunc)strcmp);
+			if (find)
+			{
+				g_free (find->data);
+				plugin->recent_target = g_list_delete_link (plugin->recent_target, find);
+			}
+			plugin->recent_target = g_list_prepend (plugin->recent_target, uri);
+		}
+	}
+
+	/* Save working dir */
+	uri = gtk_file_chooser_get_uri (dlg->dirs);
+	if (uri != NULL)
+	{
+		find = g_list_find_custom(plugin->recent_dirs, uri, (GCompareFunc)strcmp);
+		if (find)
+		{
+			g_free (find->data);
+			plugin->recent_dirs = g_list_delete_link (plugin->recent_dirs, find);
+		}
+		plugin->recent_dirs = g_list_prepend (plugin->recent_dirs, uri);
+	}
+			
+	/* Save all environment variables */
+	model = gtk_tree_view_get_model (dlg->vars);
+	save_environment_variables (plugin, model);
+			
+	plugin->run_in_terminal = gtk_toggle_button_get_active (dlg->term);
+
+	run_plugin_update_shell_value (plugin);
+}
+
+static void
+on_select_target (RunDialog* dlg)
+{
+	GtkWidget *sel_dlg = gtk_file_chooser_dialog_new (
+			_("Load Target to run"), GTK_WINDOW (dlg->win),
+			 GTK_FILE_CHOOSER_ACTION_OPEN,
+			 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+			 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(sel_dlg), FALSE);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (sel_dlg), TRUE);
+
+	GtkFileFilter *filter = gtk_file_filter_new ();
+	gtk_file_filter_set_name (filter, _("All files"));
+	gtk_file_filter_add_pattern (filter, "*");
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (sel_dlg), filter);
+
+	if (gtk_dialog_run (GTK_DIALOG (sel_dlg)) == GTK_RESPONSE_ACCEPT)
+	{
+		gchar* filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (sel_dlg));
+
+		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (dlg->target)->child), filename);
+		g_free (filename);
+	}		
+	gtk_widget_destroy (GTK_WIDGET (sel_dlg));
+}
+
+static void
+on_environment_selection_changed (GtkTreeSelection *selection, RunDialog *dlg)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gboolean selected;
+
+	if (selection == NULL)
+	{
+		selection = gtk_tree_view_get_selection (dlg->vars);
+	}
+	
+	selected = gtk_tree_selection_get_selected (selection, &model, &iter);
+	if (selected)
+	{
+		gchar *color;
+		gchar *value;
+		gboolean restore;
+		
+		gtk_tree_model_get (model, &iter,
+							ENV_DEFAULT_VALUE_COLUMN, &value,
+							ENV_COLOR_COLUMN, &color,
+							-1);
+		
+		restore = (strcmp (color, ENV_USER_COLOR) == 0) && (value != NULL);
+		gtk_button_set_label (GTK_BUTTON (dlg->remove_button), restore ? GTK_STOCK_REVERT_TO_SAVED : GTK_STOCK_DELETE);
+		g_free (color);
+		g_free (value);
+	}
+	gtk_widget_set_sensitive (dlg->remove_button, selected);
+	gtk_widget_set_sensitive (dlg->edit_button, selected);
+}
+
+static void
+on_environment_add_button (GtkButton *button, GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	GtkTreeViewColumn *column;
+	GtkTreePath *path;
+	GtkTreeSelection* sel;
+		
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+	
+	sel = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (sel, NULL, &iter))
+	{
+		GtkTreeIter niter;
+		gtk_list_store_insert_after	(model, &niter, &iter);
+		iter = niter;
+	}
+	else
+	{
+		gtk_list_store_prepend (model, &iter);
+	}
+	
+	gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, "",
+								ENV_VALUE_COLUMN, "",
+								ENV_DEFAULT_VALUE_COLUMN, NULL,
+								ENV_COLOR_COLUMN, ENV_USER_COLOR,
+								-1);
+		
+	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+	column = gtk_tree_view_get_column (view, ENV_NAME_COLUMN);
+	gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
+	gtk_tree_view_set_cursor (view, path, column ,TRUE);
+	gtk_tree_path_free (path);
+}
+
+static void
+on_environment_edit_button (GtkButton *button, GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection* sel;
+
+	sel = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (sel, NULL, &iter))
+	{
+		GtkListStore *model;
+		GtkTreePath *path;
+		GtkTreeViewColumn *column;
+		
+		model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+		path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+		column = gtk_tree_view_get_column (view, ENV_VALUE_COLUMN);
+		gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
+		gtk_tree_view_set_cursor (view, path, column ,TRUE);
+		gtk_tree_path_free (path);
+	}
+}
+
+static void
+on_environment_remove_button (GtkButton *button, RunDialog *dlg)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection* sel;
+	GtkTreeView *view = dlg->vars;
+
+	sel = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (sel, NULL, &iter))
+	{
+		GtkListStore *model;
+		GtkTreeViewColumn *column;
+		GtkTreePath *path;
+		gchar *color;
+		
+		model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+
+		/* Display variable */
+		path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+		column = gtk_tree_view_get_column (view, ENV_NAME_COLUMN);
+		gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
+		gtk_tree_path_free (path);
+		
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+							ENV_COLOR_COLUMN, &color,
+							-1);
+		if (strcmp(color, ENV_USER_COLOR) == 0)
+		{
+			/* Remove an user variable */
+			gchar *value;
+			
+			gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+								ENV_DEFAULT_VALUE_COLUMN, &value,
+								-1);
+			
+			if (value != NULL)
+			{
+				/* Restore default environment variable */
+				gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, value,
+									ENV_COLOR_COLUMN, ENV_DEFAULT_COLOR,
+									-1);
+			}
+			else
+			{
+				gtk_list_store_remove (model, &iter);
+			}
+			g_free (value);
+		}				
+		else
+		{
+			/* Replace value with an empty one */
+			gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, NULL,
+								ENV_COLOR_COLUMN, ENV_USER_COLOR,
+								-1);
+		}
+		on_environment_selection_changed (sel, dlg);
+	}
+}
+
+static void
+on_environment_variable_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          RunDialog *dlg)
+{
+	GtkTreeIter iter;
+	GtkTreeIter niter;
+	GtkListStore *model;
+	gboolean valid;
+	GtkTreeView *view = dlg->vars;
+	
+	text = g_strstrip (text);
+	
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+	
+	valid = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path);
+	if (valid)
+	{
+		gchar *name;
+		gchar *value;
+		gchar *def_value;
+			
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+							ENV_NAME_COLUMN, &name,
+							ENV_VALUE_COLUMN, &value,
+							ENV_DEFAULT_VALUE_COLUMN, &def_value,
+							-1);
+		
+		if (strcmp(name, text) != 0)
+		{
+			GtkTreeSelection* sel;
+			GtkTreePath *path;
+			GtkTreeViewColumn *column;
+			
+			if (def_value != NULL)
+			{
+				/* Remove current variable */
+				gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, NULL,
+									ENV_COLOR_COLUMN, ENV_USER_COLOR,
+									-1);
+			}
+			
+			/* Search variable with new name */
+			if (run_plugin_gtk_tree_model_find_string (GTK_TREE_MODEL (model), 
+												NULL, &niter, ENV_NAME_COLUMN,
+												text))
+			{
+					if (def_value == NULL)
+					{
+						gtk_list_store_remove (model, &iter);
+					}
+					gtk_list_store_set (model, &niter, 
+										ENV_VALUE_COLUMN, value,
+										ENV_COLOR_COLUMN, ENV_USER_COLOR,
+										-1);
+			}
+			else
+			{
+				if (def_value != NULL)
+				{
+					gtk_list_store_insert_after	(model, &niter, &iter);
+					gtk_list_store_set (model, &niter, ENV_NAME_COLUMN, text,
+										ENV_VALUE_COLUMN, value,
+										ENV_DEFAULT_VALUE_COLUMN, NULL,
+										ENV_COLOR_COLUMN, ENV_USER_COLOR,
+										-1);
+				}
+				else
+				{
+					gtk_list_store_set (model, &iter, ENV_NAME_COLUMN, text,
+										-1);
+					niter = iter;
+				}
+			}
+			sel = gtk_tree_view_get_selection (view);
+			gtk_tree_selection_select_iter (sel, &niter);
+			path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &niter);
+			column = gtk_tree_view_get_column (view, ENV_VALUE_COLUMN);
+			gtk_tree_view_scroll_to_cell (view, path, column, FALSE, 0, 0);
+			gtk_tree_view_set_cursor (view, path, column ,TRUE);
+			gtk_tree_path_free (path);
+		}
+		g_free (name);
+		g_free (def_value);
+		g_free (value);
+	}
+}
+
+static void
+on_environment_value_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          RunDialog *dlg)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	GtkTreeView *view = dlg->vars;
+
+	text = g_strstrip (text);
+	
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));	
+	if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
+	{
+		gtk_list_store_set (model, &iter, ENV_VALUE_COLUMN, text, 
+										ENV_COLOR_COLUMN, ENV_USER_COLOR,
+										-1);
+		on_environment_selection_changed (NULL, dlg);
+	}
+}
+
+static RunDialog*
+run_dialog_init (RunDialog *dlg, RunProgramPlugin *plugin)
+{
+	GladeXML *gxml;
+	GtkWindow *parent;
+	GtkCellRenderer *renderer;	
+	GtkTreeModel* model;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *selection;
+	GObject *button;
+	GValue value = {0,};
+	const gchar *project_root_uri;
+	
+	parent = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);
+	gxml = glade_xml_new (GLADE_FILE, PARAMETERS_DIALOG, NULL);
+	if (gxml == NULL)
+	{
+		anjuta_util_dialog_error(parent, _("Missing file %s"), GLADE_FILE);
+		return NULL;
+	}
+	
+	dlg->plugin = plugin;
+		
+	dlg->win = glade_xml_get_widget (gxml, PARAMETERS_DIALOG);
+	dlg->term = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gxml, TERMINAL_CHECK_BUTTON));
+	dlg->args = GTK_COMBO_BOX (glade_xml_get_widget (gxml, PARAMETER_COMBO));
+	dlg->target = GTK_COMBO_BOX (glade_xml_get_widget (gxml, TARGET_COMBO));
+	dlg->vars = GTK_TREE_VIEW (glade_xml_get_widget (gxml, VAR_TREEVIEW));
+	dlg->dirs = GTK_FILE_CHOOSER (glade_xml_get_widget (gxml, DIR_CHOOSER));
+	dlg->remove_button = glade_xml_get_widget (gxml, REMOVE_VAR_BUTTON);
+	dlg->edit_button = glade_xml_get_widget (gxml, EDIT_VAR_BUTTON);
+
+	/* Connect signals */	
+	button = G_OBJECT (glade_xml_get_widget (gxml, TARGET_BUTTON));
+	g_signal_connect_swapped (button, "clicked", G_CALLBACK (on_select_target), dlg);
+	button = G_OBJECT (glade_xml_get_widget (gxml, ADD_VAR_BUTTON));
+	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_add_button), dlg->vars);
+	button = G_OBJECT (glade_xml_get_widget (gxml, EDIT_VAR_BUTTON));
+	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_edit_button), dlg->vars);
+	button = G_OBJECT (glade_xml_get_widget (gxml, REMOVE_VAR_BUTTON));
+	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_remove_button), dlg);
+	selection = gtk_tree_view_get_selection (dlg->vars);
+	g_signal_connect (selection, "changed", G_CALLBACK (on_environment_selection_changed), dlg);
+	
+	g_object_unref (gxml);
+
+	/* Fill parameter combo box */
+	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
+	gtk_combo_box_set_model (dlg->args, model);
+	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(dlg->args), 0);
+	g_list_foreach (plugin->recent_args, on_add_string_in_model, model);
+	if (plugin->recent_args != NULL)
+	{
+		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (dlg->args)->child), (const char *)plugin->recent_args->data);
+	}
+	g_object_unref (model);
+
+	/* Fill target combo box */
+	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
+	gtk_combo_box_set_model (dlg->target, model);
+	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(dlg->target), 0);
+	g_list_foreach (plugin->recent_target, on_add_uri_in_model, model);
+
+    anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell, "project_root_uri", &value, NULL);
+	project_root_uri = G_VALUE_HOLDS_STRING (&value) ? g_value_get_string (&value) : NULL;
+	if (project_root_uri != NULL)
+	{
+		/* One project loaded, get all executable target */
+		IAnjutaProjectManager *pm;
+		GList *exec_targets = NULL;
+			
+		pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+										 IAnjutaProjectManager, NULL);
+		if (pm != NULL)
+		{
+			exec_targets = ianjuta_project_manager_get_targets (pm,
+							 IANJUTA_PROJECT_MANAGER_TARGET_EXECUTABLE,
+							 NULL);
+		}
+		if (exec_targets != NULL)
+		{
+			GList *node;
+
+			for (node = exec_targets; node; node = g_list_next (node))
+			{
+				GList *target;
+				for (target = plugin->recent_target; target; target = g_list_next (target))
+				{
+					if (strcmp ((const gchar *)target->data, node->data) == 0) break;
+				}
+				if (target == NULL)
+				{
+					on_add_uri_in_model (node->data, model);
+				}
+				g_free (node->data);
+			}
+			g_list_free (exec_targets);
+		}
+	}
+	g_object_unref (model);
+
+	if (plugin->recent_target != NULL)
+	{
+		gchar *local;
+		
+		local = gnome_vfs_get_local_path_from_uri ((const char *)plugin->recent_target->data);
+		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (dlg->target)->child), local);
+		g_free (local);
+	}
+	/* Fill working directory list */
+	g_list_foreach (plugin->recent_dirs, on_add_directory_in_chooser, dlg->dirs);	
+	
+	/* Fill environment variable list */
+	model = GTK_TREE_MODEL (gtk_list_store_new (ENV_N_COLUMNS,
+												G_TYPE_STRING,
+												G_TYPE_STRING,
+												G_TYPE_STRING,
+												G_TYPE_STRING,
+												G_TYPE_BOOLEAN));
+	gtk_tree_view_set_model (dlg->vars, model);
+	load_environment_variables (plugin, GTK_LIST_STORE (model));
+	g_object_unref (model);
+	
+	renderer = gtk_cell_renderer_text_new ();
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_variable_edited, dlg);
+	g_object_set(renderer, "editable", TRUE, NULL);	
+	column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer,
+													   "text", ENV_NAME_COLUMN,
+													   "foreground", ENV_COLOR_COLUMN,
+													   NULL);
+	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+	gtk_tree_view_append_column (dlg->vars, column);
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set(renderer, "editable", TRUE, NULL);	
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_value_edited, dlg);
+	column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer,
+													   "text", ENV_VALUE_COLUMN,
+													   "foreground", ENV_COLOR_COLUMN,
+													   NULL);
+	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+	gtk_tree_view_append_column (dlg->vars, column);
+	
+	/* Set terminal option */	
+	if (plugin->run_in_terminal) gtk_toggle_button_set_active (dlg->term, TRUE);
+	
+	gtk_window_set_transient_for (GTK_WINDOW (dlg->win), parent);
+	
+	return dlg;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gint
+run_parameters_dialog_run (RunProgramPlugin *plugin)
+{
+	RunDialog dlg;
+	gint response;
+	
+	run_dialog_init (&dlg, plugin);
+	
+	response = gtk_dialog_run (GTK_DIALOG (dlg.win));
+	if (response == GTK_RESPONSE_APPLY)
+	{
+		save_dialog_data (&dlg);
+	}
+	gtk_widget_destroy (dlg.win);
+	
+	return response;
+}
+

Added: trunk/plugins/run-program/parameters.h
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/parameters.h	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,28 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    parameters.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _PARAMETERS_H_
+#define _PARAMETERS_H_
+
+#include "plugin.h"
+
+gint run_parameters_dialog_run (RunProgramPlugin *plugin);
+
+#endif

Added: trunk/plugins/run-program/plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/plugin.c	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,406 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    plugin.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/*
+ * Plugins functions
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "plugin.h"
+
+#include "execute.h"
+#include "parameters.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/interfaces/ianjuta-project-manager.h>
+
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+#include <signal.h>
+
+/*---------------------------------------------------------------------------*/
+
+#define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-run-program.ui"
+
+#define MAX_RECENT_ITEM	10
+
+/* Type defintions
+ *---------------------------------------------------------------------------*/
+
+struct _RunProgramPluginClass
+{
+	AnjutaPluginClass parent_class;
+};
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+anjuta_session_set_limited_string_list (AnjutaSession *session, const gchar *section, const gchar *key, GList **value)
+{
+	GList *node;
+	
+	while ((node = g_list_nth (*value, MAX_RECENT_ITEM)) != NULL)
+	{
+		g_free (node->data);
+		*value = g_list_delete_link (*value, node);
+	}
+	anjuta_session_set_string_list (session, section, key, *value);
+}
+
+static void
+anjuta_session_set_strv (AnjutaSession *session, const gchar *section, const gchar *key, gchar **value)
+{
+	GList *list = NULL;
+	
+	if (value != NULL)
+	{
+		for (; *value != NULL; value++)
+		{
+			list = g_list_append (list, *value);
+		}
+		list = g_list_reverse (list);
+	}
+	
+	anjuta_session_set_string_list (session, section, key, list);
+	g_list_free (list);
+}
+
+static gchar**
+anjuta_session_get_strv (AnjutaSession *session, const gchar *section, const gchar *key)
+{
+	GList *list;
+	gchar **value = NULL;
+	
+	list = anjuta_session_get_string_list (session, section, key);
+	
+	if (list != NULL)
+	{
+		gchar **var;
+		GList *node;
+
+		value = g_new (gchar *, g_list_length (list) + 1);
+		var = value;
+		for (node = g_list_first (list); node != NULL; node = g_list_next (node))
+		{
+			*var = (gchar *)node->data;
+			++var;
+		}
+		*var = NULL;
+	}
+			
+	return value;
+}
+
+/* Callback for saving session
+ *---------------------------------------------------------------------------*/
+
+static void
+on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, RunProgramPlugin *self)
+{
+	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
+		return;
+
+	anjuta_session_set_limited_string_list (session, "Debugger", "Program arguments", &self->recent_args);
+	anjuta_session_set_limited_string_list (session, "Debugger", "Program uri", &self->recent_target);
+	anjuta_session_set_int (session, "Execution", "Run in terminal", self->run_in_terminal + 1);
+	anjuta_session_set_string_list (session, "Debugger", "Source directories", self->source_dirs);
+	anjuta_session_set_string_list (session, "Debugger", "Working directories", self->recent_dirs);
+	anjuta_session_set_strv (session, "Debugger", "Environment variables", self->environment_vars);
+}
+
+static void on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, RunProgramPlugin *self)
+{
+    gint run_in_terminal;
+
+	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
+		return;
+
+ 	if (self->recent_args != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_args, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_args);
+ 	}
+ 	self->recent_args = anjuta_session_get_string_list (session, "Debugger", "Program arguments");
+
+ 	if (self->recent_target != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_target, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_target);
+ 	}
+ 	self->recent_target = anjuta_session_get_string_list (session, "Debugger", "Program uri");
+	
+	/* The flag is store as 1 == FALSE, 2 == TRUE */
+	run_in_terminal = anjuta_session_get_int (session, "Execution", "Run in terminal");
+	if (run_in_terminal == 0)
+		self->run_in_terminal = TRUE;	/* Default value */
+	else
+		self->run_in_terminal = run_in_terminal - 1;
+	
+	/* Initialize source_dirs */
+ 	if (self->source_dirs != NULL)
+ 	{		
+ 		g_list_foreach (self->source_dirs, (GFunc)g_free, NULL);
+ 		g_list_free (self->source_dirs);
+ 	}
+ 	self->source_dirs = anjuta_session_get_string_list (session, "Debugger", "Source directories");
+	
+ 	if (self->recent_dirs != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_dirs, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_dirs);
+ 	}
+ 	self->recent_dirs = anjuta_session_get_string_list (session, "Debugger", "Working directories");
+
+	g_strfreev (self->environment_vars);
+ 	self->environment_vars = anjuta_session_get_strv (session, "Debugger", "Environment variables");
+	
+	run_plugin_update_shell_value (self);
+}
+
+/* Callbacks
+ *---------------------------------------------------------------------------*/
+
+static void
+on_run_program_activate (GtkAction* action, RunProgramPlugin* plugin)
+{
+	if (plugin->child != NULL)
+	{
+       gchar *msg = _("The program is running.\n"
+                      	"Do you want to restart it?");
+		if (anjuta_util_dialog_boolean_question (GTK_WINDOW ( ANJUTA_PLUGIN (plugin)->shell), msg))
+		{
+			run_plugin_kill_program (plugin, FALSE);
+		}
+	}
+	if (plugin->recent_target == NULL)
+	{
+		run_parameters_dialog_run (plugin);
+	}
+	
+	run_plugin_run_program(plugin);
+}
+
+static void
+on_kill_program_activate (GtkAction* action, RunProgramPlugin* plugin)
+{
+	run_plugin_kill_program (plugin, TRUE);
+}
+
+static void
+on_program_parameters_activate (GtkAction* action, RunProgramPlugin* plugin)
+{
+	/* Run as a modal dialog */
+	run_parameters_dialog_run (plugin);
+}
+
+/* Actions table
+ *---------------------------------------------------------------------------*/
+
+static GtkActionEntry actions_run[] = {
+	{
+		"ActionMenuRun",	/* Action name */
+		NULL,				/* Stock icon, if any */
+		N_("_Run"),		    /* Display label */
+		NULL,				/* short-cut */
+		NULL,				/* Tooltip */
+		NULL				/* action callback */
+	},
+	{
+		"ActionRunProgram",
+		GTK_STOCK_EXECUTE,
+		N_("Execute Program"),
+		"F3",
+		N_("Run program without debugger"),
+		G_CALLBACK (on_run_program_activate)
+	},
+	{
+		"ActionStopProgram",
+		GTK_STOCK_STOP,
+		N_("Stop Program"),
+		NULL,
+		N_("Kill program"),
+		G_CALLBACK (on_kill_program_activate)
+	},
+	{
+		"ActionProgramParameters",
+		NULL,
+		N_("Program Parameters..."),
+		NULL,
+		N_("Set current program, arguments and so on"),
+		G_CALLBACK (on_program_parameters_activate)
+	},
+};
+
+/* AnjutaPlugin functions
+ *---------------------------------------------------------------------------*/
+
+static gboolean
+run_plugin_activate (AnjutaPlugin *plugin)
+{
+	RunProgramPlugin *self = ANJUTA_PLUGIN_RUN_PROGRAM (plugin);
+	AnjutaUI *ui;
+	
+	DEBUG_PRINT ("Run Program Plugin: Activating plugin...");
+
+	/* Connect to session signal */
+	g_signal_connect (plugin->shell, "save-session",
+					  G_CALLBACK (on_session_save), self);
+    g_signal_connect (plugin->shell, "load-session",
+					  G_CALLBACK (on_session_load), self);
+	
+	/* Add actions */
+	ui = anjuta_shell_get_ui (plugin->shell, NULL);
+	self->action_group = anjuta_ui_add_action_group_entries (ui,
+									"ActionGroupRun", _("Run operations"),
+									actions_run, G_N_ELEMENTS (actions_run),
+									GETTEXT_PACKAGE, TRUE, self);
+	
+	self->uiid = anjuta_ui_merge (ui, UI_FILE);
+
+	run_plugin_update_menu_sensitivity (self);
+	
+	return TRUE;
+}
+
+static gboolean
+run_plugin_deactivate (AnjutaPlugin *plugin)
+{
+	RunProgramPlugin *self = ANJUTA_PLUGIN_RUN_PROGRAM (plugin);
+	AnjutaUI *ui;
+
+	DEBUG_PRINT ("Run Program Plugin: Deactivating plugin...");
+	
+	ui = anjuta_shell_get_ui (plugin->shell, NULL);
+	anjuta_ui_remove_action_group (ui, self->action_group);
+	
+	anjuta_ui_unmerge (ui, self->uiid);
+	
+	g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK (on_session_save), self);
+    g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK (on_session_load), self);
+	
+	
+	return TRUE;
+}
+
+/* GObject functions
+ *---------------------------------------------------------------------------*/
+
+/* Used in dispose and finalize */
+static gpointer parent_class;
+
+static void
+run_plugin_instance_init (GObject *obj)
+{
+	RunProgramPlugin *self = ANJUTA_PLUGIN_RUN_PROGRAM (obj);
+	
+	self->source_dirs = NULL;
+	self->recent_target = NULL;
+	self->recent_args = NULL;
+	self->recent_dirs = NULL;
+	self->environment_vars = NULL;
+	
+	self->child = NULL;
+}
+
+/* dispose is used to unref object created with instance_init */
+
+static void
+run_plugin_dispose (GObject *obj)
+{
+	RunProgramPlugin *plugin = ANJUTA_PLUGIN_RUN_PROGRAM (obj);
+	
+	/* Warning this function could be called several times */
+
+	run_free_all_children (plugin);
+	
+	G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+run_plugin_finalize (GObject *obj)
+{
+	RunProgramPlugin *self = ANJUTA_PLUGIN_RUN_PROGRAM (obj);
+	
+	g_list_foreach (self->source_dirs, (GFunc)g_free, NULL);
+	g_list_free (self->source_dirs);
+	g_list_foreach (self->recent_target, (GFunc)g_free, NULL);
+	g_list_free (self->recent_target);
+	g_list_foreach (self->recent_args, (GFunc)g_free, NULL);
+	g_list_free (self->recent_args);
+	g_list_foreach (self->recent_args, (GFunc)g_free, NULL);
+	g_list_free (self->recent_args);
+	g_list_foreach (self->recent_dirs, (GFunc)g_free, NULL);
+	g_list_free (self->recent_dirs);
+	g_strfreev (self->environment_vars);
+	
+	G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+/* finalize used to free object created with instance init is not used */
+
+static void
+run_plugin_class_init (GObjectClass *klass) 
+{
+	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	plugin_class->activate = run_plugin_activate;
+	plugin_class->deactivate = run_plugin_deactivate;
+	klass->dispose = run_plugin_dispose;
+	klass->finalize = run_plugin_finalize;
+}
+
+/* AnjutaPlugin declaration
+ *---------------------------------------------------------------------------*/
+
+ANJUTA_PLUGIN_BEGIN (RunProgramPlugin, run_plugin);
+ANJUTA_PLUGIN_END;
+					 
+ANJUTA_SIMPLE_PLUGIN (RunProgramPlugin, run_plugin);
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+void
+run_plugin_update_shell_value (RunProgramPlugin *plugin)
+{
+	/* Update Anjuta shell value */
+	anjuta_shell_add (ANJUTA_PLUGIN (plugin)->shell,
+					 	RUN_PROGRAM_URI, G_TYPE_STRING, plugin->recent_target == NULL ? NULL : plugin->recent_target->data,
+						RUN_PROGRAM_ARGS, G_TYPE_STRING, plugin->recent_args == NULL ? NULL : plugin->recent_args->data,
+					    RUN_PROGRAM_DIR, G_TYPE_STRING, plugin->recent_dirs == NULL ? NULL : plugin->recent_dirs->data,
+					  	RUN_PROGRAM_ENV, G_TYPE_STRV, plugin->environment_vars == NULL ? NULL : plugin->environment_vars,
+						RUN_PROGRAM_NEED_TERM, G_TYPE_BOOLEAN, plugin->run_in_terminal,
+					  	NULL);
+}
+
+void
+run_plugin_update_menu_sensitivity (RunProgramPlugin *plugin)
+{
+	GtkAction *action;
+	action = gtk_action_group_get_action (plugin->action_group, "ActionStopProgram");
+	
+	gtk_action_set_sensitive (action, plugin->child != NULL);
+}
+

Added: trunk/plugins/run-program/plugin.h
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/plugin.h	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,70 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    plugin.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <libanjuta/anjuta-plugin.h>
+
+/* Anjuta Shell value set by this plugin */
+
+#define RUN_PROGRAM_URI	"run_program_uri"
+#define RUN_PROGRAM_ARGS "run_program_args"
+#define RUN_PROGRAM_DIR	"run_program_directory"
+#define RUN_PROGRAM_ENV	"run_program_environment"
+#define RUN_PROGRAM_NEED_TERM	"run_program_need_terminal"
+
+extern GType run_plugin_get_type 				(GTypeModule *module);
+#define ANJUTA_TYPE_PLUGIN_RUN_PROGRAM			(run_plugin_get_type (NULL))
+#define ANJUTA_PLUGIN_RUN_PROGRAM(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), ANJUTA_TYPE_PLUGIN_RUN_PROGRAM, RunProgramPlugin))
+#define ANJUTA_PLUGIN_RUN_PROGRAM_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), ANJUTA_TYPE_PLUGIN_RUN_PROGRAM, RunProgramPluginClass))
+#define ANJUTA_IS_PLUGIN_RUN_PROGRAM(o)			(G_TYPE_CHECK_INSTANCE_TYPE ((o), ANJUTA_TYPE_PLUGIN_RUN_PROGRAM))
+#define ANJUTA_IS_PLUGIN_RUN_PROGRAM_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), ANJUTA_TYPE_PLUGIN_RUN_PROGRAM))
+#define ANJUTA_PLUGIN_RUN_PROGRAM_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), ANJUTA_TYPE_PLUGIN_RUN_PROGRAM, RunProgramPluginClass))
+
+typedef struct _RunProgramPlugin RunProgramPlugin;
+typedef struct _RunProgramPluginClass RunProgramPluginClass;
+typedef struct _RunProgramChild RunProgramChild;
+
+struct _RunProgramPlugin
+{
+	AnjutaPlugin parent;
+	
+	/* Menu item */
+	gint uiid;
+	GtkActionGroup *action_group;
+	
+	/* Save data */
+	gboolean run_in_terminal;
+ 	GList *source_dirs;
+	gchar **environment_vars;
+	GList *recent_target;
+	GList *recent_dirs;
+	GList *recent_args;	
+	
+	/* Child watches */
+	GList *child;
+	guint child_exited_connection;
+};
+
+void run_plugin_update_shell_value (RunProgramPlugin *plugin);
+void run_plugin_update_menu_sensitivity (RunProgramPlugin *plugin);
+
+#endif

Added: trunk/plugins/run-program/utils.c
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/utils.c	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,83 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    utils.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/*
+ * Miscellaneous utilities functions
+ *---------------------------------------------------------------------------*/
+
+#include <config.h>
+
+#include "utils.h"
+
+/* Constants
+ *---------------------------------------------------------------------------*/
+
+/* Helpers functions
+ *---------------------------------------------------------------------------*/
+
+#include <string.h>
+
+gboolean
+run_plugin_gtk_tree_model_find_string (GtkTreeModel *model, GtkTreeIter *parent,
+		GtkTreeIter *iter, guint col, const gchar *value)
+
+{
+	gboolean valid;
+	gboolean found = FALSE;
+
+	g_return_val_if_fail (GTK_IS_TREE_MODEL (model), FALSE);
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+
+	if (!parent)
+	{
+		valid = gtk_tree_model_get_iter_first (model, iter);
+	}
+	else 
+	{
+		valid = gtk_tree_model_iter_children (model, iter, parent);
+	}
+
+	while (valid)
+	{
+		gchar *mvalue;
+		
+		gtk_tree_model_get (model, iter, col, &mvalue, -1);
+		found = (mvalue != NULL) && (strcmp (mvalue, value) == 0);
+		g_free (mvalue);
+		if (found) break;						   
+
+		if (gtk_tree_model_iter_has_child (model, iter))
+		{
+			GtkTreeIter citer;
+			
+			found = run_plugin_gtk_tree_model_find_string (model, iter,
+														   &citer, col, value);
+			if (found)
+			{
+				*iter = citer;
+				break;
+			}
+		}
+		valid = gtk_tree_model_iter_next (model, iter);
+	}
+
+	return found;
+}

Added: trunk/plugins/run-program/utils.h
==============================================================================
--- (empty file)
+++ trunk/plugins/run-program/utils.h	Mon Apr 28 19:49:42 2008
@@ -0,0 +1,29 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    utils.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include <gtk/gtk.h>
+
+gboolean run_plugin_gtk_tree_model_find_string (GtkTreeModel *model, GtkTreeIter *parent,
+					GtkTreeIter *iter, guint col, const gchar *value);
+
+#endif

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Mon Apr 28 19:49:42 2008
@@ -145,6 +145,9 @@
 plugins/project-wizard/plugin.c
 plugins/project-wizard/property.c
 plugins/project-wizard/templates/translatable-strings.h
+plugins/run-program/execute.c
+plugins/run-program/parameters.c
+plugins/run-program/plugin.c
 plugins/sample1/plugin.c
 plugins/search/anjuta-search.glade
 plugins/search/plugin.c

Modified: trunk/src/anjuta.ui
==============================================================================
--- trunk/src/anjuta.ui	(original)
+++ trunk/src/anjuta.ui	Mon Apr 28 19:49:42 2008
@@ -29,9 +29,10 @@
 		<placeholder name="PlaceHolderProjectMenus"/>
 		<placeholder name="PlaceHolderFormatMenus"/>
 		<placeholder name="PlaceHolderBuildMenus"/>
-		<placeholder name="PlaceHolderToolMenus"/>
 		<placeholder name="PlaceHolderDesignerMenus"/>
+		<placeholder name="PlaceHolderRunMenus"/>
 		<placeholder name="PlaceHolderDebugMenus"/>
+		<placeholder name="PlaceHolderToolMenus"/>
 		<placeholder name="PlaceHolderVersionControlMenus"/>
 		<placeholder name="PlaceHolderBookmarkMenus"/>
 		<placeholder name="PlaceHolderHelpMenus" >



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]