[anjuta] build-basic-autotools: bgo #566704 - Better UI for environment variables



commit cde7bb25db93960fd3f70769a10e8d7ded9d6da9
Author: SÃbastien Granjoux <seb sfo free fr>
Date:   Wed Aug 17 20:45:33 2011 +0200

    build-basic-autotools: bgo #566704 - Better UI for environment variables

 libanjuta/Makefile.am                              |    4 +-
 libanjuta/anjuta-environment-editor.c              |  800 ++++++++++++++++++++
 libanjuta/anjuta-environment-editor.h              |   55 ++
 libanjuta/anjuta-glade-catalog.c                   |    1 +
 libanjuta/anjuta-glade.xml                         |    4 +
 .../anjuta-build-basic-autotools-plugin.ui         |  656 +++++++++-------
 plugins/build-basic-autotools/build-options.c      |   28 +-
 plugins/build-basic-autotools/build.c              |  103 +++-
 plugins/build-basic-autotools/configuration-list.c |   61 ++-
 plugins/build-basic-autotools/configuration-list.h |    3 +
 plugins/build-basic-autotools/plugin.c             |   40 +-
 plugins/build-basic-autotools/program.c            |   31 +
 plugins/build-basic-autotools/program.h            |    1 +
 13 files changed, 1475 insertions(+), 312 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index 76a361e..3a65b97 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -125,7 +125,9 @@ libanjuta_3_la_SOURCES= \
 	anjuta-file-drop-entry.h \
 	anjuta-file-drop-entry.c \
 	anjuta-entry.h \
-	anjuta-entry.c
+	anjuta-entry.c \
+	anjuta-environment-editor.h \
+	anjuta-environment-editor.c
 
 # Glade module
 if HAVE_PLUGIN_GLADE
diff --git a/libanjuta/anjuta-environment-editor.c b/libanjuta/anjuta-environment-editor.c
new file mode 100644
index 0000000..373893e
--- /dev/null
+++ b/libanjuta/anjuta-environment-editor.c
@@ -0,0 +1,800 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-environment-editor.c
+ * Copyright (C) 2011 Sebastien 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
+ */
+
+#include "anjuta-environment-editor.h"
+#include <glib/gi18n.h>
+
+enum
+{
+	CHANGED,
+	LAST_SIGNAL
+};
+
+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"
+
+
+struct _AnjutaEnvironmentEditor
+{
+	GtkBin parent;
+
+	gchar **variables;
+
+	GtkTreeModel *model;
+	
+	GtkTreeView *treeview;
+	GtkWidget *edit_button;
+	GtkWidget *remove_button;
+};
+
+
+G_DEFINE_TYPE (AnjutaEnvironmentEditor, anjuta_environment_editor, GTK_TYPE_BIN);
+
+
+/* Helpers functions
+ *---------------------------------------------------------------------------*/
+
+#include <string.h>
+
+static gboolean
+anjuta_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 = anjuta_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;
+}
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static void
+load_environment_variables (AnjutaEnvironmentEditor *editor, 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 = editor->variables;
+	if (var)
+	{
+		for (; *var != NULL; var++)
+		{
+			gchar ** value;
+			
+			value = g_strsplit (*var, "=", 2);
+			if (value)
+			{
+				if (anjuta_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);
+			}
+		}
+	}
+}
+
+
+/* Implement GtkWidget functions
+ *---------------------------------------------------------------------------*/
+
+static void
+anjuta_environment_editor_size_allocate (GtkWidget     *widget,
+                                         GtkAllocation *allocation)
+{
+	GtkBin *bin;
+	GtkWidget *child;
+
+	bin = GTK_BIN (widget);
+	child = gtk_bin_get_child (bin);
+	if ((child != NULL) && gtk_widget_get_visible (child))
+	{
+		gtk_widget_set_allocation (widget, allocation);
+		gtk_widget_size_allocate (child, allocation);
+	}
+}
+
+static void
+anjuta_environment_editor_get_preferred_width (GtkWidget *widget,
+                               gint      *minimum_size,
+                               gint      *natural_size)
+{
+	GtkBin *bin;
+	GtkWidget *child;
+
+	bin = GTK_BIN (widget);
+	child = gtk_bin_get_child (bin);
+	gtk_widget_get_preferred_width (child, minimum_size, natural_size);
+}
+
+static void
+anjuta_environment_editor_get_preferred_height (GtkWidget *widget,
+                                gint      *minimum_size,
+                                gint      *natural_size)
+{
+	GtkBin *bin;
+	GtkWidget *child;
+
+	bin = GTK_BIN (widget);
+	child = gtk_bin_get_child (bin);
+	gtk_widget_get_preferred_height (child, minimum_size, natural_size);
+}
+
+static void
+on_environment_selection_changed (GtkTreeSelection *selection, AnjutaEnvironmentEditor *editor)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gboolean selected;
+
+	if (selection == NULL)
+	{
+		selection = gtk_tree_view_get_selection (editor->treeview);
+	}
+	
+	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 (editor->remove_button), restore ? GTK_STOCK_REVERT_TO_SAVED : GTK_STOCK_DELETE);
+		g_free (color);
+		g_free (value);
+	}
+	gtk_widget_set_sensitive (editor->remove_button, selected);
+	gtk_widget_set_sensitive (editor->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, AnjutaEnvironmentEditor *editor)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection* sel;
+	GtkTreeView *view = editor->treeview;
+
+	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, editor);
+	}
+}
+
+static gboolean
+move_to_environment_value (gpointer data)
+{
+	GtkTreeView *view = GTK_TREE_VIEW (data);
+	GtkTreeSelection* sel;
+	GtkTreeModel *model;
+	GtkTreeIter iter;	
+	GtkTreeViewColumn *column;
+
+	sel = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (sel, &model, &iter))
+	{
+		GtkTreePath *path;
+		
+		path = gtk_tree_model_get_path (model, &iter);
+		column = gtk_tree_view_get_column (view, ENV_VALUE_COLUMN);
+		gtk_tree_view_set_cursor (view, path, column, TRUE);
+		gtk_tree_path_free (path);
+	}
+
+	return FALSE;
+}
+
+static void
+on_environment_variable_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          AnjutaEnvironmentEditor *editor)
+{
+	GtkTreeIter iter;
+	GtkTreeIter niter;
+	GtkListStore *model;
+	gboolean valid;
+	GtkTreeView *view = editor->treeview;
+	
+	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)
+		{
+			
+			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 (anjuta_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);
+				}
+			}
+			g_idle_add (move_to_environment_value, view);
+		}
+		g_free (name);
+		g_free (def_value);
+		g_free (value);
+	}
+}
+
+static void
+on_environment_value_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          AnjutaEnvironmentEditor *editor)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	GtkTreeView *view = editor->treeview;
+
+	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, editor);
+	}
+}
+
+/* Implement GtkWidget functions
+ *---------------------------------------------------------------------------*/
+
+static void
+anjuta_environment_editor_dispose (GObject *object)
+{
+	AnjutaEnvironmentEditor* editor = ANJUTA_ENVIRONMENT_EDITOR (object);
+
+	if (editor->model != NULL) g_object_unref (editor->model);
+
+	G_OBJECT_CLASS (anjuta_environment_editor_parent_class)->dispose (object);
+}
+
+static void
+anjuta_environment_editor_finalize (GObject *object)
+{
+	AnjutaEnvironmentEditor* editor = ANJUTA_ENVIRONMENT_EDITOR (object);
+	
+	g_strfreev (editor->variables);
+	editor->variables = NULL;
+
+	G_OBJECT_CLASS (anjuta_environment_editor_parent_class)->finalize (object);
+}
+
+static void
+anjuta_environment_editor_init (AnjutaEnvironmentEditor *editor)
+{
+	GtkWidget *expander;
+	GtkWidget *hbox;
+	GtkWidget *scrolled;
+	GtkWidget *treeview;
+	GtkWidget *vbutton;
+	GtkWidget *add_button;
+	GtkWidget *edit_button;
+	GtkWidget *remove_button;
+	GtkTreeModel *model;
+	GtkTreeViewColumn* column;
+	GtkCellRenderer* renderer;
+	GtkTreeSelection *selection;
+
+	editor->variables = NULL;
+	
+	gtk_widget_set_has_window (GTK_WIDGET (editor), FALSE);
+	gtk_widget_set_redraw_on_allocate (GTK_WIDGET (editor), FALSE);
+
+	/* Create all needed widgets */
+	expander = gtk_expander_new (_("Environment Variables:"));
+	gtk_container_add (GTK_CONTAINER (editor), expander);
+	hbox = gtk_hbox_new (FALSE, 6);
+	gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
+	gtk_container_add (GTK_CONTAINER (expander), hbox);
+	scrolled = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_OUT);
+ 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	
+	gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 0);
+	treeview = gtk_tree_view_new ();
+	gtk_container_add (GTK_CONTAINER (scrolled), treeview);
+	editor->treeview = GTK_TREE_VIEW (treeview);
+
+	vbutton = gtk_vbutton_box_new ();
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (vbutton), GTK_BUTTONBOX_START);
+	gtk_box_set_spacing (GTK_BOX (vbutton), 6);
+	gtk_box_pack_start (GTK_BOX (hbox), vbutton, FALSE, FALSE, 0);
+	add_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
+	gtk_container_add (GTK_CONTAINER (vbutton), add_button);
+	edit_button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+	gtk_container_add (GTK_CONTAINER (vbutton), edit_button);
+	editor->edit_button = edit_button;
+	remove_button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+	gtk_container_add (GTK_CONTAINER (vbutton), remove_button);
+	editor->remove_button = remove_button;
+	
+	gtk_widget_show_all (GTK_WIDGET (editor));
+
+	/* 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 (GTK_TREE_VIEW (treeview), model);
+	load_environment_variables (editor, GTK_LIST_STORE (model));
+	editor->model = g_object_ref (model);
+	
+	renderer = gtk_cell_renderer_text_new ();
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_variable_edited, editor);
+	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 (GTK_TREE_VIEW (treeview), column);
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set(renderer, "editable", TRUE, NULL);	
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_value_edited, editor);
+	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 (GTK_TREE_VIEW (treeview), column);
+
+	/* Connect signals */	
+	g_signal_connect (G_OBJECT (add_button), "clicked", G_CALLBACK (on_environment_add_button), editor->treeview);
+	g_signal_connect (G_OBJECT (edit_button), "clicked", G_CALLBACK (on_environment_edit_button), editor->treeview);
+	g_signal_connect (G_OBJECT (remove_button), "clicked", G_CALLBACK (on_environment_remove_button), editor);
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	g_signal_connect (selection, "changed", G_CALLBACK (on_environment_selection_changed), editor);
+
+	on_environment_selection_changed (NULL, editor);
+}
+
+static void
+anjuta_environment_editor_class_init (AnjutaEnvironmentEditorClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ 	
+	/**
+	 * AnjutaEnvironmentEditor::changed:
+	 * @widget: the AnjutaEnvironmentEditor that received the signal
+	 *
+	 * The ::changed signal is emitted when an environment variable
+	 * is changed (include deleted variables)
+	 */
+	g_signal_new ("changed",
+	              G_OBJECT_CLASS_TYPE (klass),
+	              G_SIGNAL_RUN_LAST,
+	              G_STRUCT_OFFSET (AnjutaEnvironmentEditorClass, changed),
+	              NULL, NULL,
+	              g_cclosure_marshal_VOID__VOID,
+	              G_TYPE_NONE, 0);
+
+	object_class->dispose = anjuta_environment_editor_dispose;
+	object_class->finalize = anjuta_environment_editor_finalize;
+	
+	widget_class->size_allocate = anjuta_environment_editor_size_allocate;
+	widget_class->get_preferred_width = anjuta_environment_editor_get_preferred_width;
+	widget_class->get_preferred_height = anjuta_environment_editor_get_preferred_height;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+/*
+ * anjuta_environment_editor_new:
+ * 
+ * Returns: A new AnjutaEnvironmentEditor widget
+ */
+GtkWidget*
+anjuta_environment_editor_new (void)
+{
+	return GTK_WIDGET (g_object_new (ANJUTA_TYPE_ENVIRONMENT_EDITOR, NULL));
+}
+
+/*
+ * anjuta_environment_editor_set_variable:
+ * @editor: A AnjutaEnvironmentEditor widget
+ * @variable: Environment variable name and value
+ *
+ * Set environment variable.
+ */
+void
+anjuta_environment_editor_set_variable (AnjutaEnvironmentEditor *editor, const gchar *variable)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gboolean valid;
+	gchar *name;
+	const gchar *equal;
+	guint len = 0;
+	
+	model = editor->model;
+
+	/* Check is variable is already existing */
+	equal = strchr (variable, '=');
+	if (equal != NULL)
+	{
+		len = equal - variable;
+	}
+		
+	for (valid = gtk_tree_model_get_iter_first (model, &iter); valid; valid = gtk_tree_model_iter_next (model, &iter))
+	{
+		gtk_tree_model_get (editor->model, &iter,
+							ENV_NAME_COLUMN, &name,
+							-1);
+		if (((len == 0) && (strcmp (name, variable) == 0)) ||
+		    ((len != 0) && (strncmp (name, variable, len) == 0) && (name[len] == '=')))
+		{
+			break;
+		}
+		g_free (name);
+		name = NULL;
+	}
+
+	if (!valid) gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, NULL);
+
+	if (name == NULL)
+	{
+		name = g_strdup (variable);
+		if (len != 0) name[len] = '\0';
+	}
+	if (equal != NULL)
+	{
+		equal++;
+	}
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter, ENV_NAME_COLUMN, name,
+								ENV_VALUE_COLUMN, equal,
+								ENV_COLOR_COLUMN, ENV_USER_COLOR,
+								-1);
+	g_free (name);
+}
+
+/*
+ * anjuta_environment_editor_get_all_variables:
+ * @editor: A AnjutaEnvironmentEditor widget
+ *
+ * Returns: A list of all environment variables in a string array.
+ */
+gchar** 
+anjuta_environment_editor_get_all_variables (AnjutaEnvironmentEditor *editor)
+{
+	gchar **all_var;
+	gchar *var;
+	gboolean valid;
+	GtkTreeIter iter;
+	
+	all_var = g_new (gchar *, gtk_tree_model_iter_n_children (editor->model, NULL) + 1);
+	var = all_var;
+	
+	for (valid = gtk_tree_model_get_iter_first (editor->model, &iter); valid; valid = gtk_tree_model_iter_next (editor->model, &iter))
+	{
+		gchar *name;
+		gchar *value;
+		gchar *color;
+		
+		gtk_tree_model_get (editor->model, &iter,
+							ENV_NAME_COLUMN, &name,
+							ENV_VALUE_COLUMN, &value,
+							ENV_COLOR_COLUMN, &color,
+							-1);
+		
+		*var = g_strconcat(name, "=", value, NULL);
+		var++;
+		g_free (name);
+		g_free (value);
+		g_free (color);
+	}
+	*var = NULL;
+
+	return all_var;
+}
+
+/*
+ * anjuta_environment_editor_get_modified_variables:
+ * @editor: A AnjutaEnvironmentEditor widget
+ *
+ * Returns: A list of modified environment variables in a string array.
+ */
+gchar**
+anjuta_environment_editor_get_modified_variables (AnjutaEnvironmentEditor *editor)
+{
+	gchar **mod_var;
+	gchar **var;
+	gboolean valid;
+	GtkTreeIter iter;
+	
+	/* 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 */
+	mod_var = g_new (gchar *, gtk_tree_model_iter_n_children (editor->model, NULL) + 1);
+	var = mod_var;
+	
+	for (valid = gtk_tree_model_get_iter_first (editor->model, &iter); valid; valid = gtk_tree_model_iter_next (editor->model, &iter))
+	{
+		gchar *name;
+		gchar *value;
+		gchar *color;
+		
+		gtk_tree_model_get (editor->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)
+		{
+			*var = g_strconcat(name, "=", value, NULL);
+			var++;
+		}
+		g_free (name);
+		g_free (value);
+		g_free (color);
+	}
+	*var = NULL;
+
+	return mod_var;
+}
diff --git a/libanjuta/anjuta-environment-editor.h b/libanjuta/anjuta-environment-editor.h
new file mode 100644
index 0000000..1da3ad6
--- /dev/null
+++ b/libanjuta/anjuta-environment-editor.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-environment-editor.h
+ * Copyright (C) 2011 Sebastien 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 _ANJUTA_ENVIRONMENT_EDITOR_H_
+#define _ANJUTA_ENVIRONMENT_EDITOR_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define ANJUTA_TYPE_ENVIRONMENT_EDITOR             (anjuta_environment_editor_get_type ())
+#define ANJUTA_ENVIRONMENT_EDITOR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_ENVIRONMENT_EDITOR, AnjutaEnvironmentEditor))
+#define ANJUTA_ENVIRONMENT_EDITOR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), ANJUTA_TYPE_ENVIRONMENT_EDITOR, AnjutaEnvironmentEditorClass))
+#define ANJUTA_IS_ENVIRONMENT_EDITOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANJUTA_TYPE_ENVIRONMENT_EDITOR))
+#define ANJUTA_IS_ENVIRONMENT_EDITOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), ANJUTA_TYPE_ENVIRONMENT_EDITOR))
+#define ANJUTA_ENVIRONMENT_EDITOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), ANJUTA_TYPE_ENVIRONMENT_EDITOR, AnjutaEnvironmentEditorClass))
+
+typedef struct _AnjutaEnvironmentEditorClass AnjutaEnvironmentEditorClass;
+typedef struct _AnjutaEnvironmentEditor AnjutaEnvironmentEditor;
+
+struct _AnjutaEnvironmentEditorClass
+{
+	GtkBinClass parent_class;
+	
+	/* Signals */
+	void(* changed) (AnjutaEnvironmentEditor *self);
+};
+
+GType anjuta_environment_editor_get_type (void) G_GNUC_CONST;
+
+GtkWidget* anjuta_environment_editor_new (void);
+void anjuta_environment_editor_set_variable (AnjutaEnvironmentEditor *editor, const gchar *variable);
+gchar** anjuta_environment_editor_get_all_variables (AnjutaEnvironmentEditor *editor);
+gchar** anjuta_environment_editor_get_modified_variables (AnjutaEnvironmentEditor *editor);
+
+G_END_DECLS
+
+#endif /* _ANJUTA_ENVIRONMENT_EDITOR_H_ */
diff --git a/libanjuta/anjuta-glade-catalog.c b/libanjuta/anjuta-glade-catalog.c
index 3934c94..ff0f15c 100644
--- a/libanjuta/anjuta-glade-catalog.c
+++ b/libanjuta/anjuta-glade-catalog.c
@@ -6,4 +6,5 @@
 #include <libanjuta/anjuta-column-text-view.h>
 #include <libanjuta/anjuta-file-drop-entry.h>
 #include <libanjuta/anjuta-entry.h>
+#include <libanjuta/anjuta-environment-editor.h>
 
diff --git a/libanjuta/anjuta-glade.xml b/libanjuta/anjuta-glade.xml
index b3b176a..5b43cef 100644
--- a/libanjuta/anjuta-glade.xml
+++ b/libanjuta/anjuta-glade.xml
@@ -54,6 +54,9 @@
 		 	</properties>
 		 </glade-widget-class>
 
+		 <glade-widget-class name="AnjutaEnvironmentEditor" title="Environment editor"
+		 generic-name="environment_editor" />
+
 	</glade-widget-classes>
 
 	<glade-widget-group name="Anjuta" title="Anjuta">
@@ -64,5 +67,6 @@
 		<glade-widget-class-ref name="AnjutaColumnTextView" />
 		<glade-widget-class-ref name="AnjutaFileDropEntry" />
 		<glade-widget-class-ref name="AnjutaEntry" />
+		<glade-widget-class-ref name="AnjutaEnvironmentEditor" />
 	</glade-widget-group>
 </glade-catalog>
diff --git a/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui b/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
index 6451f5f..a9c217b 100644
--- a/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
+++ b/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <!-- interface-requires anjuta 0.0 -->
   <object class="GtkAdjustment" id="adjustment1">
     <property name="lower">1</property>
     <property name="upper">30</property>
@@ -9,19 +9,320 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkDialog" id="configure_dialog">
+    <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="border_width">5</property>
+    <property name="title" translatable="yes">Configure Project</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="default_width">450</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area2">
+            <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="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button2">
+                <property name="label">gtk-cancel</property>
+                <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="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="ok_button">
+                <property name="label">gtk-execute</property>
+                <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="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox4">
+            <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="spacing">18</property>
+            <child>
+              <object class="GtkCheckButton" id="force_autogen_check">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">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="use_action_appearance">False</property>
+                <property name="draw_indicator">True</property>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <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="label" translatable="yes">Regenerate project</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox6">
+                <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>
+                <child>
+                  <object class="GtkHBox" id="hbox1">
+                    <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="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="label1">
+                        <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="xalign">0</property>
+                        <property name="label" translatable="yes">Configuration:</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="configuration_combo_entry">
+                        <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="has_entry">True</property>
+                        <child internal-child="entry">
+                          <object class="GtkEntry" id="comboboxentry-entry2">
+                            <property name="can_focus">False</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="top_padding">6</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkTable" id="table1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="n_rows">4</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkEntry" id="configure_args_entry">
+                            <property name="visible">True</property>
+                            <property name="app_paintable">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>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label6">
+                            <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="xalign">0</property>
+                            <property name="label" translatable="yes">Configure Options:</property>
+                          </object>
+                          <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>
+                          <object class="GtkFileChooserButton" id="build_dir_chooser">
+                            <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="action">select-folder</property>
+                            <property name="title" translatable="yes">Select a build directory</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <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="xalign">0</property>
+                            <property name="label" translatable="yes">Build Directory:</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="AnjutaEnvironmentEditor" id="environment_editor">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">button2</action-widget>
+      <action-widget response="-5">ok_button</action-widget>
+    </action-widgets>
+  </object>
   <object class="GtkDialog" id="execute_dialog">
+    <property name="can_focus">False</property>
     <property name="title" translatable="yes">Select Program</property>
     <property name="window_position">center-on-parent</property>
     <property name="default_width">400</property>
     <property name="default_height">300</property>
     <property name="type_hint">normal</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox5">
+      <object class="GtkBox" id="dialog-vbox5">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="spacing">5</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area5">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancelbutton2">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="okbutton3">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
         <child>
           <object class="GtkFrame" id="frame1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="border_width">5</property>
             <property name="label_xalign">0</property>
             <property name="label_yalign">0</property>
@@ -29,36 +330,43 @@
             <child>
               <object class="GtkVBox" id="vbox1">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkScrolledWindow" id="treeview_frame">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="border_width">5</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
                     <property name="shadow_type">in</property>
                     <child>
                       <object class="GtkTreeView" id="programs_treeview">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection1"/>
+                        </child>
                       </object>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkHBox" id="hbox27">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <child>
                       <object class="GtkLabel" id="label3">
                         <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="label" translatable="yes">Arguments:</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
@@ -69,6 +377,8 @@
                         <property name="activates_default">True</property>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="padding">5</property>
                         <property name="position">1</property>
                       </packing>
@@ -76,6 +386,7 @@
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -86,6 +397,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
                     <property name="border_width">5</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="use_underline">True</property>
                     <property name="draw_indicator">True</property>
                   </object>
@@ -95,99 +407,79 @@
                     <property name="position">2</property>
                   </packing>
                 </child>
-              </object>
-            </child>
-            <child type="label">
-              <object class="GtkLabel" id="label105">
-                <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0</property>
-                <property name="label" translatable="yes">Select Program to run:</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                </attributes>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area5">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="cancelbutton2">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="okbutton3">
-                <property name="label">gtk-ok</property>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="label105">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="has_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="label" translatable="yes">Select Program to run:</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
     </child>
     <action-widgets>
-      <action-widget response="-6">cancelbutton2</action-widget>
-      <action-widget response="-5">okbutton3</action-widget>
+      <action-widget response="0">cancelbutton2</action-widget>
+      <action-widget response="0">okbutton3</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkListStore" id="install_list">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">sudo</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">su -c</col>
+      </row>
+    </data>
+  </object>
   <object class="GtkWindow" id="preferences-dialog-build">
+    <property name="can_focus">False</property>
     <property name="title" translatable="yes">window1</property>
     <child>
       <object class="GtkVBox" id="preferences-build-container">
         <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>
         <child>
           <object class="GtkFrame" id="frame3">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="border_width">10</property>
             <property name="label_xalign">0</property>
             <property name="shadow_type">none</property>
             <child>
               <object class="GtkAlignment" id="alignment1">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
                 <property name="left_padding">12</property>
                 <child>
                   <object class="GtkVBox" id="vbox3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkHBox" id="hbox2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkCheckButton" id="preferences_toggle:bool:0:0:build-parallel-make">
@@ -195,6 +487,7 @@
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
@@ -232,6 +525,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -247,9 +541,12 @@
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="draw_indicator">True</property>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
@@ -259,6 +556,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -275,6 +573,7 @@
             <child type="label">
               <object class="GtkLabel" id="label5">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
                 <property name="label" translatable="yes">Build</property>
@@ -293,22 +592,26 @@
         <child>
           <object class="GtkFrame" id="frame2">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="border_width">10</property>
             <property name="label_xalign">0</property>
             <property name="shadow_type">none</property>
             <child>
               <object class="GtkAlignment" id="alignment4">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
                 <property name="left_padding">12</property>
                 <child>
                   <object class="GtkVBox" id="vbox5">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkHBox" id="hbox3">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkCheckButton" id="preferences_toggle:bool:0:0:build-install-root">
@@ -316,6 +619,7 @@
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="use_underline">True</property>
                             <property name="draw_indicator">True</property>
                           </object>
@@ -328,6 +632,7 @@
                         <child>
                           <object class="GtkComboBox" id="preferences_combo:text:sudo %s, su -c %q:0:build-install-root-command">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="model">install_list</property>
                             <property name="active">0</property>
                             <child>
@@ -338,6 +643,8 @@
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
@@ -355,6 +662,7 @@
             <child type="label">
               <object class="GtkLabel" id="label8">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="xalign">0</property>
                 <property name="yalign">0</property>
                 <property name="label" translatable="yes">Install</property>
@@ -373,232 +681,6 @@
       </object>
     </child>
   </object>
-  <object class="GtkDialog" id="configure_dialog">
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">Configure Project</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="default_width">450</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox2">
-        <property name="visible">True</property>
-        <property name="spacing">2</property>
-        <child>
-          <object class="GtkVBox" id="vbox4">
-            <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">18</property>
-            <child>
-              <object class="GtkCheckButton" id="force_autogen_check">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">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="draw_indicator">True</property>
-                <child>
-                  <object class="GtkLabel" id="label4">
-                    <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">Regenerate project</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkVBox" id="vbox6">
-                <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>
-                <child>
-                  <object class="GtkHBox" id="hbox1">
-                    <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">12</property>
-                    <child>
-                      <object class="GtkLabel" id="label1">
-                        <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="xalign">0</property>
-                        <property name="label" translatable="yes">Configuration:</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="configuration_combo_entry">
-                        <property name="visible">True</property>
-                        <property name="has-entry">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </object>
-                      <packing>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkAlignment" id="alignment2">
-                    <property name="visible">True</property>
-                    <property name="top_padding">6</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <object class="GtkTable" id="table1">
-                        <property name="visible">True</property>
-                        <property name="n_rows">2</property>
-                        <property name="n_columns">2</property>
-                        <property name="column_spacing">12</property>
-                        <property name="row_spacing">6</property>
-                        <child>
-                          <object class="GtkEntry" id="configure_args_entry">
-                            <property name="visible">True</property>
-                            <property name="app_paintable">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>
-                          </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="y_options"></property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label6">
-                            <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="xalign">0</property>
-                            <property name="label" translatable="yes">Configure Options:</property>
-                          </object>
-                          <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>
-                          <object class="GtkFileChooserButton" id="build_dir_chooser">
-                            <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="action">select-folder</property>
-                            <property name="title" translatable="yes">Select a build directory</property>
-                          </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="y_options"></property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label2">
-                            <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="xalign">0</property>
-                            <property name="label" translatable="yes">Build Directory:</property>
-                          </object>
-                          <packing>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
-                          </packing>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area2">
-            <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="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="button2">
-                <property name="label">gtk-cancel</property>
-                <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="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="ok_button">
-                <property name="label">gtk-execute</property>
-                <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="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="-6">button2</action-widget>
-      <action-widget response="-5">ok_button</action-widget>
-    </action-widgets>
-  </object>
-  <object class="GtkListStore" id="install_list">
-    <columns>
-      <!-- column-name gchararray1 -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">sudo</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">su -c</col>
-      </row>
-    </data>
-  </object>
+  <object class="GtkTreeModelFilter" id="treemodelfilter1"/>
+  <object class="GtkTreeModelSort" id="treemodelsort1"/>
 </interface>
diff --git a/plugins/build-basic-autotools/build-options.c b/plugins/build-basic-autotools/build-options.c
index 6ecdaa7..56352eb 100644
--- a/plugins/build-basic-autotools/build-options.c
+++ b/plugins/build-basic-autotools/build-options.c
@@ -25,6 +25,7 @@
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-shell.h>
 #include <libanjuta/anjuta-utils.h>
+#include <libanjuta/anjuta-environment-editor.h>
 #include <string.h>
 
 /* Constants
@@ -37,6 +38,7 @@
 #define CONFIGURATION_COMBO "configuration_combo_entry"
 #define BUILD_DIR_CHOOSER "build_dir_chooser"
 #define CONFIGURE_ARGS_ENTRY "configure_args_entry"
+#define ENVIRONMENT_EDITOR "environment_editor"
 #define OK_BUTTON "ok_button"
 
 #define GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK (build_gtk_file_chooser_create_directory_get_quark ())
@@ -55,6 +57,7 @@ struct _BuildConfigureDialog
 	GtkWidget *autogen;
 	GtkWidget *build_dir_chooser;
 	GtkWidget *args;
+	GtkWidget *env_editor;
 	GtkWidget *ok;
 	
 	BuildConfigurationList *config_list;
@@ -267,6 +270,7 @@ on_select_configuration (GtkComboBox *widget, gpointer user_data)
 		if (cfg != NULL)
 		{
 			const gchar *args;
+			GList *item;
 
 			args = build_configuration_get_args (cfg); 
 			gtk_entry_set_text (GTK_ENTRY (dlg->args), args == NULL ? "" : args);
@@ -274,6 +278,11 @@ on_select_configuration (GtkComboBox *widget, gpointer user_data)
 			uri = build_configuration_list_get_build_uri (dlg->config_list, cfg);
 			build_gtk_file_chooser_create_and_set_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), uri);
 			g_free (uri);
+
+			for (item = build_configuration_get_variables (cfg); item != NULL; item = g_list_next (item))
+			{
+				anjuta_environment_editor_set_variable (ANJUTA_ENVIRONMENT_EDITOR (dlg->env_editor), (gchar *)item->data);
+			}
 		}
 	}
 	g_free (name);
@@ -320,6 +329,7 @@ build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, BuildC
 	    RUN_AUTOGEN_CHECK, &dlg.autogen,
 	    BUILD_DIR_CHOOSER, &dlg.build_dir_chooser,
 	    CONFIGURE_ARGS_ENTRY, &dlg.args,
+	    ENVIRONMENT_EDITOR, &dlg.env_editor,
 	    OK_BUTTON, &dlg.ok,
 	    NULL);
 	g_object_unref (bxml);
@@ -335,13 +345,14 @@ build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, BuildC
 	fill_dialog(&dlg);
 	
 	response = gtk_dialog_run (GTK_DIALOG (dlg.win));
-	
+
 	if (response == GTK_RESPONSE_OK)
 	{
 		gchar *name;
 		gchar *uri;
 		const gchar *args;
 		GtkTreeIter iter;
+		gchar **mod_var;
 
 		*run_autogen = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg.autogen));
 		
@@ -364,6 +375,21 @@ build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, BuildC
 		build_configuration_list_set_build_uri (dlg.config_list, cfg, uri);
 		build_gtk_file_chooser_keep_folder (GTK_FILE_CHOOSER (dlg.build_dir_chooser), uri);
 		g_free (uri);
+
+		mod_var = anjuta_environment_editor_get_modified_variables (ANJUTA_ENVIRONMENT_EDITOR (dlg.env_editor));
+		if (mod_var != NULL)
+		{
+			gchar **var;
+			/* Invert list */
+			for (var = mod_var; *var != NULL; var++);
+			do
+			{
+				var--;
+				build_configuration_set_variable (cfg, *var);
+			}
+			while (var != mod_var);
+			g_strfreev (mod_var);
+		}
 	}
 	gtk_widget_destroy (GTK_WIDGET(dlg.win));
 
diff --git a/plugins/build-basic-autotools/build.c b/plugins/build-basic-autotools/build.c
index 2f47ff9..4a7d5c6 100644
--- a/plugins/build-basic-autotools/build.c
+++ b/plugins/build-basic-autotools/build.c
@@ -437,12 +437,17 @@ build_save_distclean_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildPr
 	BuildContext *context;
 	gchar *root_path;
 	gboolean same;
-
+	BuildConfiguration *config;
+	GList *vars;
+	
 	context = build_get_context (bplugin, prog->work_dir, with_view);
 	root_path = g_file_get_path (bplugin->project_root_dir);
 	same = strcmp (prog->work_dir, root_path) != 0;
 	g_free (root_path);
 	
+	config = build_configuration_list_get_selected (bplugin->configurations);
+	vars = build_configuration_get_variables (config);
+
 	if (!same && directory_has_file (bplugin->project_root_dir, "config.status"))
 	{
 		BuildProgram *new_prog;
@@ -463,6 +468,7 @@ build_save_distclean_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildPr
 		build_program_set_callback (new_prog, build_execute_after_command, prog);
 		prog = new_prog;
 	}
+	build_program_add_env_list (prog, vars);
 	
 	build_set_command_in_context (context, prog);
 
@@ -485,6 +491,12 @@ build_build_file_or_dir (BasicAutotoolsPlugin *plugin,
 	gchar *target;
 	BuildProgram *prog;
 	BuildContext *context;
+	BuildConfiguration *config;
+	GList *vars;
+
+	
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
 	
 	build_dir = build_file_from_file (plugin, file, &target);
 	prog = build_program_new_with_command (build_dir,
@@ -492,6 +504,7 @@ build_build_file_or_dir (BasicAutotoolsPlugin *plugin,
 										   CHOOSE_COMMAND (plugin, BUILD),
 										   target ? target : "");
 	build_program_set_callback (prog, callback, user_data);
+	build_program_add_env_list (prog, vars);
 	
 	context = build_save_and_execute_command (plugin, prog, TRUE, err);
 	g_free (target);
@@ -511,13 +524,20 @@ build_is_file_built (BasicAutotoolsPlugin *plugin, GFile *file,
 	gchar *target;
 	BuildProgram *prog;
 	BuildContext *context;
+	BuildConfiguration *config;
+	GList *vars;
 
+
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
+	
 	build_dir = build_file_from_file (plugin, file, &target);
 	prog = build_program_new_with_command (build_dir,
 										   "%s %s",
 										   CHOOSE_COMMAND (plugin, IS_BUILT),
 										   target ? target : "");
 	build_program_set_callback (prog, callback, user_data);
+	build_program_add_env_list (prog, vars);
 	
 	context = build_save_and_execute_command (plugin, prog, FALSE, err);
 	
@@ -552,6 +572,8 @@ build_install_dir (BasicAutotoolsPlugin *plugin, GFile *dir,
 	GFile *build_dir;
 	BuildProgram *prog;
 	GString *command;
+	BuildConfiguration *config;
+	GList *vars;
 
 	if ((root != NULL) && (*root != '\0'))
 	{
@@ -599,11 +621,16 @@ build_install_dir (BasicAutotoolsPlugin *plugin, GFile *dir,
 		command = g_string_new (CHOOSE_COMMAND (plugin, INSTALL));
 	}
 
+
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
+	
  	build_dir = build_file_from_file (plugin, dir, NULL);	
 	prog = build_program_new_with_command (build_dir,
 		                                   "%s",
         		                           command->str);
 	build_program_set_callback (prog, callback, user_data);	
+	build_program_add_env_list (prog, vars);
 	
 	context = build_save_and_execute_command (plugin, prog, TRUE, err);
 	
@@ -621,14 +648,22 @@ build_clean_dir (BasicAutotoolsPlugin *plugin, GFile *file,
 				 GError **err)
 {
 	BuildContext *context;
+	BuildProgram *prog;
 	GFile *build_dir;
+	BuildConfiguration *config;
+	GList *vars;
 
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
+	
 	build_dir = build_file_from_file (plugin, file, NULL);
-	context = build_execute_command (plugin,
-									 build_program_new_with_command (build_dir,
-																	 "%s",
-																	 CHOOSE_COMMAND (plugin, CLEAN)),
-									 TRUE, err);
+
+	prog = build_program_new_with_command (build_dir,
+	                                       "%s",
+	                                       CHOOSE_COMMAND (plugin, CLEAN)),
+	build_program_add_env_list (prog, vars);
+	
+	context = build_execute_command (plugin, prog, TRUE, err);
 	g_object_unref (build_dir);
 	
 	return context;
@@ -650,12 +685,19 @@ build_distclean (BasicAutotoolsPlugin *plugin)
 {
 	BuildContext *context;
 	BuildProgram *prog;
+	BuildConfiguration *config;
+	GList *vars;
+
+
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
 
 	prog = build_program_new_with_command (plugin->project_build_dir,
 										   "%s",
 										   CHOOSE_COMMAND (plugin, DISTCLEAN));
 	build_program_set_callback (prog, build_remove_build_dir, plugin);
-
+	build_program_add_env_list (prog, vars);
+	
 	context = build_execute_command (plugin, prog, TRUE, NULL);
 	
 	return context;
@@ -667,12 +709,19 @@ BuildContext*
 build_tarball (BasicAutotoolsPlugin *plugin)
 {
 	BuildContext *context;
+	BuildProgram *prog;
+	BuildConfiguration *config;
+	GList *vars;
+
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
 
-	context = build_save_and_execute_command (plugin,
-									 build_program_new_with_command (plugin->project_build_dir,
-																	 "%s",
-																	 CHOOSE_COMMAND (plugin, BUILD_TARBALL)),
-									 TRUE, NULL);
+	prog = build_program_new_with_command (plugin->project_build_dir,
+	                                       "%s",
+	                                       CHOOSE_COMMAND (plugin, BUILD_TARBALL)),
+	build_program_add_env_list (prog, vars);
+	
+	context = build_save_and_execute_command (plugin, prog, TRUE, NULL);
 	
 	return context;
 }
@@ -691,6 +740,11 @@ build_compile_file (BasicAutotoolsPlugin *plugin, GFile *file)
 	if (object != NULL)
 	{
 		GFile *build_dir;
+		BuildConfiguration *config;
+		GList *vars;
+
+		config = build_configuration_list_get_selected (plugin->configurations);
+		vars = build_configuration_get_variables (config);
 		
 		/* Find target directory */
 		build_dir = build_file_from_file (plugin, object, &target_name);
@@ -700,6 +754,9 @@ build_compile_file (BasicAutotoolsPlugin *plugin, GFile *file)
 	        	                               (target_name == NULL) ? "" : target_name);
 		g_free (target_name);
 		g_object_unref (build_dir);
+
+		build_program_add_env_list (prog, vars);
+		
 		context = build_save_and_execute_command (plugin, prog, TRUE, NULL);
 		g_object_unref (object);
 	}
@@ -768,10 +825,15 @@ build_configure_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args
 {
 	BuildContext *context;
 	BuildProgram *prog;
+	BuildConfiguration *config;
+	GList *vars;
 	BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
 	gchar *quote;
 	gchar *root_path;
 
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
+	
 	root_path = g_file_get_path (plugin->project_root_dir);
 	quote = shell_quotef ("%s%s%s",
 		       	root_path,
@@ -784,10 +846,12 @@ build_configure_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args
 										   args);
 	g_free (quote);
 	g_free (root_path);
+	
 	pack->args = NULL;
 	pack->func = func;
 	pack->file = (file != NULL) ? g_object_ref (file) : NULL;
 	build_program_set_callback (prog, build_project_configured, pack);
+	build_program_add_env_list (prog, vars);
 	
 	context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
 	
@@ -807,6 +871,8 @@ build_configure_after_autogen (GObject *sender,
 	if (error == NULL)
 	{
 		BuildContext *context = (BuildContext *)handle;
+		BuildConfiguration *config;
+		GList *vars;
 		BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)build_context_get_plugin (context);
 		struct stat conf_stat, log_stat;
 		gchar *root_path;
@@ -821,6 +887,9 @@ build_configure_after_autogen (GObject *sender,
 		if (has_configure)
 		{
 			gboolean older;
+
+			config = build_configuration_list_get_selected (plugin->configurations);
+			vars = build_configuration_get_variables (config);
 			
 			filename = g_build_filename (build_context_get_work_dir (context), "config.status", NULL);
 			older =(stat (filename, &log_stat) != 0) || (log_stat.st_mtime < conf_stat.st_mtime);
@@ -846,7 +915,8 @@ build_configure_after_autogen (GObject *sender,
 				g_object_unref (work_file);
 				g_free (quote);
 				build_program_set_callback (prog, build_project_configured, pack);
-		
+				build_program_add_env_list (prog, vars);
+				
 				build_set_command_in_context (context, prog);
 				build_execute_command_in_context (context, NULL);
 			}
@@ -880,8 +950,14 @@ build_generate_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
 {
 	BuildContext *context;
 	BuildProgram *prog;
+	BuildConfiguration *config;
+	GList *vars;
 	BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
+	
 
+	config = build_configuration_list_get_selected (plugin->configurations);
+	vars = build_configuration_get_variables (config);
+	
 	if (directory_has_file (plugin->project_root_dir, "autogen.sh"))
 	{
 		gchar *quote;
@@ -909,6 +985,7 @@ build_generate_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
 	pack->func = func;
 	pack->file = (file != NULL) ? g_object_ref (file) : NULL;
 	build_program_set_callback (prog, build_configure_after_autogen, pack);
+	build_program_add_env_list (prog, vars);
 	
 	context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
 	
diff --git a/plugins/build-basic-autotools/configuration-list.c b/plugins/build-basic-autotools/configuration-list.c
index 9039416..513816f 100644
--- a/plugins/build-basic-autotools/configuration-list.c
+++ b/plugins/build-basic-autotools/configuration-list.c
@@ -37,6 +37,7 @@ struct  _BuildConfiguration
 	gchar *name;
 	gchar *build_uri;
 	gchar *args;
+	GList *env;
 	gboolean translate;
 	BuildConfiguration *next;
 	BuildConfiguration *prev;
@@ -56,6 +57,7 @@ struct  _DefaultBuildConfiguration
 	gchar *name;
 	gchar *build_uri;
 	gchar *args;
+	gchar **env;
 };
 
 /* The name value is kept untranslated for saving in the session file or
@@ -65,11 +67,11 @@ struct  _DefaultBuildConfiguration
  * field as we need a translated value, so they are used in build
  * directory instead */
 const DefaultBuildConfiguration default_config[] = {
-	{N_("Default"), NULL, "--enable-maintainer-mode"},
-	{N_("Debug"), IANJUTA_BUILDER_CONFIGURATION_DEBUG, "--enable-maintainer-mode 'CFLAGS=-g -O0' 'CXXFLAGS=-g -O0' 'JFLAGS=-g -O0' 'FFLAGS=-g -O0'"},
-	{N_("Profiling"), IANJUTA_BUILDER_CONFIGURATION_PROFILING, "--enable-maintainer-mode 'CFLAGS=-g -pg' 'CXXFLAGS=-g -pg' 'JFLAGS=-g -pg' 'FFLAGS=-g -pg'"},
-	{N_("Optimized"), IANJUTA_BUILDER_CONFIGURATION_OPTIMIZED, "--enable-maintainer-mode 'CFLAGS=-O2' 'CXXFLAGS=-O2' 'JFLAGS=-O2' 'FFLAGS=-O2'"},
-	{NULL, NULL, NULL}
+	{N_("Default"), NULL, "--enable-maintainer-mode", NULL},
+	{N_("Debug"), IANJUTA_BUILDER_CONFIGURATION_DEBUG, "--enable-maintainer-mode 'CFLAGS=-g -O0' 'CXXFLAGS=-g -O0' 'JFLAGS=-g -O0' 'FFLAGS=-g -O0'", NULL},
+	{N_("Profiling"), IANJUTA_BUILDER_CONFIGURATION_PROFILING, "--enable-maintainer-mode 'CFLAGS=-g -pg' 'CXXFLAGS=-g -pg' 'JFLAGS=-g -pg' 'FFLAGS=-g -pg'", NULL},
+	{N_("Optimized"), IANJUTA_BUILDER_CONFIGURATION_OPTIMIZED, "--enable-maintainer-mode 'CFLAGS=-O2' 'CXXFLAGS=-O2' 'JFLAGS=-O2' 'FFLAGS=-O2'", NULL},
+	{NULL, NULL, NULL, NULL}
 };
 
 /* Helper functions
@@ -147,6 +149,8 @@ build_configuration_list_free_list (BuildConfigurationList *list)
 		BuildConfiguration *next = cfg->next;
 		
 		if (cfg->args) g_free (cfg->args);
+		g_list_foreach (cfg->env, (GFunc)g_free, NULL);
+		g_list_free (cfg->env);
 		if (cfg->build_uri) g_free (cfg->build_uri);
 		if (cfg->name) g_free (cfg->name);
 		g_free (cfg);
@@ -287,6 +291,7 @@ build_configuration_list_from_string_list (BuildConfigurationList *list, GList *
 			cfg->build_uri = *str == '\0' ? NULL : g_strdup (str);
 			
 			cfg->args = NULL;
+			cfg->env = NULL;
 			
 			cfg->next = NULL;
 			cfg->prev = prev;
@@ -320,6 +325,7 @@ build_configuration_list_from_string_list (BuildConfigurationList *list, GList *
 			cfg->name = g_strdup (dcfg->name);
 			cfg->build_uri = g_strdup (dcfg->build_uri);
 			cfg->args = NULL;
+			cfg->env = NULL;
 			cfg->next = NULL;
 			cfg->prev = prev;
 			if (prev == NULL)
@@ -334,7 +340,17 @@ build_configuration_list_from_string_list (BuildConfigurationList *list, GList *
 		}
 		if ((cfg->args == NULL) && (dcfg->args))
 		{
-				cfg->args = g_strdup (dcfg->args);
+			cfg->args = g_strdup (dcfg->args);
+		}
+		if ((cfg->env == NULL) && (dcfg->env))
+		{
+			gchar **item;
+
+			for (item = dcfg->env; *item != NULL; item++)
+			{
+				cfg->env = g_list_prepend (cfg->env, g_strdup (*item));
+			}
+			cfg->env = g_list_reverse (cfg->env);
 		}
 	}	
 }
@@ -444,6 +460,39 @@ build_configuration_get_args (BuildConfiguration *cfg)
 	return cfg->args;
 }
 
+void
+build_configuration_set_variable (BuildConfiguration *cfg, const gchar *var)
+{
+	GList *item;
+	guint len = 0;
+	const gchar *equal;
+
+	equal = strchr (var, '=');
+	if (equal == NULL)
+	{
+		len = equal - var;
+	}
+	
+	/* Check if variable already exist */
+	for (item = cfg->env; item != NULL; item = g_list_next (item))
+	{
+		if (((len == 0) && (strcmp ((gchar *)item->data, var) == 0)) ||
+		    ((len > 0) && (strncmp ((gchar *)item->data, var, len) == 0) && (((gchar *)item->data)[len] == '=')))
+		{
+			g_free (item->data);
+			cfg->env = g_list_delete_link (cfg->env, item);
+		}
+	}
+
+	cfg->env = g_list_append (cfg->env, g_strdup (var));
+}
+
+GList *
+build_configuration_get_variables (BuildConfiguration *cfg)
+{
+	return cfg->env;
+}
+
 /* Constructor & Destructor
  *---------------------------------------------------------------------------*/
 
diff --git a/plugins/build-basic-autotools/configuration-list.h b/plugins/build-basic-autotools/configuration-list.h
index 9f92874..6bfdca5 100644
--- a/plugins/build-basic-autotools/configuration-list.h
+++ b/plugins/build-basic-autotools/configuration-list.h
@@ -48,5 +48,8 @@ gchar *build_configuration_list_get_build_uri (BuildConfigurationList *list, Bui
 const gchar *build_configuration_get_relative_build_uri (BuildConfiguration *cfg);
 void build_configuration_set_args (BuildConfiguration *cfg, const gchar *args);
 const gchar *build_configuration_get_args (BuildConfiguration *cfg);
+void build_configuration_set_variable (BuildConfiguration *cfg, const gchar *var);
+GList *build_configuration_get_variables (BuildConfiguration *cfg);
+
 
 #endif /* CONFIGURATION_LIST_H */
diff --git a/plugins/build-basic-autotools/plugin.c b/plugins/build-basic-autotools/plugin.c
index c242258..4491d80 100644
--- a/plugins/build-basic-autotools/plugin.c
+++ b/plugins/build-basic-autotools/plugin.c
@@ -2067,12 +2067,24 @@ on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
 	}
 	for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
 	{
-		gchar *key = g_strconcat("BuildArgs/", build_configuration_get_name (cfg), NULL);
+		gchar *key;
+		GList *list;
 
+		key = g_strconcat("BuildArgs/", build_configuration_get_name (cfg), NULL);
 		anjuta_session_set_string (session, "Build",
 			       key,
 			       build_configuration_get_args(cfg));
 		g_free (key);
+
+		list = build_configuration_get_variables (cfg);
+		if (list != NULL)
+		{
+			key = g_strconcat("BuildEnv/", build_configuration_get_name (cfg), NULL);
+			anjuta_session_set_string_list (session, "Build",
+				       key,
+			    	   list);
+			g_free (key);
+		}
 	}
 }
 
@@ -2100,15 +2112,35 @@ on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
 
 	for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
 	{
-		gchar *key = g_strconcat("BuildArgs/", build_configuration_get_name (cfg), NULL);
-		gchar *args = anjuta_session_get_string (session, "Build",
-				key);
+		gchar *key;
+		gchar *args;
+		GList *env;
+		
+		key = g_strconcat("BuildArgs/", build_configuration_get_name (cfg), NULL);
+		args = anjuta_session_get_string (session, "Build", key);
 		g_free (key);
 		if (args != NULL)
 		{
 			build_configuration_set_args (cfg, args);
 			g_free (args);
 		}
+
+		key = g_strconcat("BuildEnv/", build_configuration_get_name (cfg), NULL);
+		env = anjuta_session_get_string_list (session, "Build",	key);
+		g_free (key);
+		if (env != NULL)
+		{
+			GList *item;
+
+			/* New variables are added at the beginning of the list */
+			for (item = env; item != NULL; item = g_list_next (item))
+			{
+				build_configuration_set_variable (cfg, (gchar *)item->data);
+				g_free (item->data);
+			}
+			g_list_free (env);
+		}
+
 	}
 
 	build_project_configured (G_OBJECT (plugin), NULL, NULL, NULL);
diff --git a/plugins/build-basic-autotools/program.c b/plugins/build-basic-autotools/program.c
index f9c3319..6599bc3 100644
--- a/plugins/build-basic-autotools/program.c
+++ b/plugins/build-basic-autotools/program.c
@@ -214,6 +214,37 @@ build_program_remove_arg (BuildProgram *prog, gint pos)
 }
 
 
+gboolean
+build_program_add_env_list (BuildProgram *prog, GList *vars)
+{
+	GList *item;
+	gboolean ok = TRUE;
+
+	for (item = vars; item != NULL; item = g_list_next (item))
+	{
+		const gchar *value;
+		gchar *equal;
+		gchar *name;
+
+		name = g_strdup ((gchar *)item->data);
+		equal = strchr (name, '=');
+		if (equal != NULL)
+		{
+			*equal = '\0';
+			value = equal + 1;
+		}
+		else
+		{
+			value = NULL;
+		}
+		
+		ok = ok && build_program_add_env (prog, name, value);
+		g_free (name);
+	}
+
+	return ok;
+}
+
 
 gboolean
 build_program_add_env (BuildProgram *prog, const gchar *name, const gchar *value)
diff --git a/plugins/build-basic-autotools/program.h b/plugins/build-basic-autotools/program.h
index bbdde09..a3caeac 100644
--- a/plugins/build-basic-autotools/program.h
+++ b/plugins/build-basic-autotools/program.h
@@ -51,6 +51,7 @@ gboolean build_program_insert_arg (BuildProgram *proc, gint pos, const gchar *ar
 gboolean build_program_replace_arg (BuildProgram *proc, gint pos, const gchar *arg);
 gboolean build_program_remove_arg (BuildProgram *proc, gint pos);
 
+gboolean build_program_add_env_list (BuildProgram *proc, GList *vars);
 gboolean build_program_add_env (BuildProgram *proc, const gchar *name, const gchar *value);
 gboolean build_program_remove_env (BuildProgram *proc, const gchar *name);
 



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