anjuta r4083 - in trunk: . libanjuta libanjuta/interfaces plugins/build-basic-autotools plugins/debug-manager plugins/project-manager plugins/project-wizard plugins/run-program



Author: sgranjoux
Date: Thu Jul 17 21:09:41 2008
New Revision: 4083
URL: http://svn.gnome.org/viewvc/anjuta?rev=4083&view=rev

Log:
	* plugins/build-basic-autotools/build-basic-autotools.c,
	plugins/build-basic-autotools/build-basic-autotools.h,
	plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.glade,
	plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui,
	plugins/build-basic-autotools/build-options.c,
	plugins/build-basic-autotools/build-options.h,
	plugins/build-basic-autotools/Makefile.am,
	(added) plugins/build-basic-autotools/configuration-list.c,
	(added) plugins/build-basic-autotools/configuration-list.h:
	Allow to build project outside source directory (fix #540782)

	* plugins/project-manager/plugin.c:
	Use IANJUTA_BUILDER_ROOT_URI as parent uri for all targets

	* plugins/debug-manager/start.c,
	plugins/project-wizard/autogen.c,
	plugins/run-program/execute.c,
	libanjuta/interfaces/libanjuta.idl:
	Add a handle argument to IAnjutaBuilder callback

	* libanjuta/anjuta-launcher.c,
	libanjuta/anjuta-launcher.h:
	Set environment variables in anjuta_launcher_execute_v


Added:
   trunk/plugins/build-basic-autotools/configuration-list.c   (contents, props changed)
   trunk/plugins/build-basic-autotools/configuration-list.h   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/libanjuta/anjuta-launcher.c
   trunk/libanjuta/anjuta-launcher.h
   trunk/libanjuta/interfaces/libanjuta.idl
   trunk/plugins/build-basic-autotools/Makefile.am
   trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.glade
   trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
   trunk/plugins/build-basic-autotools/build-basic-autotools.c
   trunk/plugins/build-basic-autotools/build-basic-autotools.h
   trunk/plugins/build-basic-autotools/build-options.c
   trunk/plugins/build-basic-autotools/build-options.h
   trunk/plugins/debug-manager/start.c
   trunk/plugins/project-manager/plugin.c
   trunk/plugins/project-wizard/autogen.c
   trunk/plugins/run-program/execute.c

Modified: trunk/libanjuta/anjuta-launcher.c
==============================================================================
--- trunk/libanjuta/anjuta-launcher.c	(original)
+++ trunk/libanjuta/anjuta-launcher.c	Thu Jul 17 21:09:41 2008
@@ -1089,43 +1089,15 @@
 	  launcher->priv->encoding = NULL;		
 }
 
-/**
- * anjuta_launcher_set_env:
- * @launcher: a #AnjutaLancher object.
- * @name: Name of the environment variable to set
- * @value: Value of the environment variable to set
- * 
- * Set an environment variable for the forked process
- *
- */ 
-void
-anjuta_launcher_set_env (AnjutaLauncher *launcher,
-						 const gchar *name,
-						 const gchar *value)
-{
-	g_return_if_fail (launcher && ANJUTA_IS_LAUNCHER(launcher));
-	g_return_if_fail (name != NULL);
-	g_return_if_fail (value != NULL);
-	
-	g_hash_table_insert (launcher->priv->env,
-						 g_strdup(name),
-						 g_strdup(value));
-}
-
-static void
-anjuta_launcher_fork_setenv (const gchar* name, const gchar* value)
-{
-	setenv (name, value, TRUE);
-}
-
 static pid_t
-anjuta_launcher_fork (AnjutaLauncher *launcher, gchar *const args[])
+anjuta_launcher_fork (AnjutaLauncher *launcher, gchar *const args[], gchar *const envp[])
 {
 	char *working_dir;
 	int pty_master_fd, md;
 	int stdout_pipe[2], stderr_pipe[2];
 	pid_t child_pid;
 	struct termios termios_flags;
+	gchar * const *env;
 	
 	working_dir = g_get_current_dir ();
 	
@@ -1158,10 +1130,26 @@
 			fcntl (stderr_pipe[1], F_SETFL, O_SYNC | md);
 		
 		/* Set up environment */
-		g_hash_table_foreach (launcher->priv->env,
-							  (GHFunc) anjuta_launcher_fork_setenv,
-							  NULL);
-		
+		if (envp != NULL)
+		{
+			GString *variable = g_string_new (NULL);
+			for (env = envp; *env != NULL; env++)
+			{
+				gchar *value = strchr (*env, '=');
+
+				if (value == NULL)
+				{
+					g_setenv (*env, NULL, TRUE);
+				}
+				else
+				{
+					g_string_truncate (variable, 0);
+					g_string_append_len (variable, *env, value - *env);
+					g_setenv (variable->str, value + 1, TRUE);
+				}
+			}
+		}
+	
 		execvp (args[0], args);
 		g_warning (_("Cannot execute command: \"%s\""), args[0]);
 		perror(_("execvp failed"));
@@ -1250,6 +1238,7 @@
  * anjuta_launcher_execute_v:
  * @launcher: a #AnjutaLancher object.
  * @argv: Command args.
+ * @envp: Additional environment variable.
  * @callback: The callback for delivering output from the process.
  * @callback_data: Callback data for the above callback.
  * 
@@ -1260,6 +1249,7 @@
  */
 gboolean
 anjuta_launcher_execute_v (AnjutaLauncher *launcher, gchar *const argv[],
+						   gchar *const envp[],
 						   AnjutaLauncherOutputCallback callback,
 						   gpointer callback_data)
 {
@@ -1278,7 +1268,7 @@
 	launcher->priv->callback_data = callback_data;
 	
 	/* On a fork error perform a cleanup and return */
-	if (anjuta_launcher_fork (launcher, argv) < 0)
+	if (anjuta_launcher_fork (launcher, argv, envp) < 0)
 	{
 		anjuta_launcher_initialize (launcher);
 		return FALSE;
@@ -1324,7 +1314,7 @@
 	}
 	*args_ptr = NULL;
 
-	ret = anjuta_launcher_execute_v (launcher, args, 
+	ret = anjuta_launcher_execute_v (launcher, args, NULL,
 		callback, callback_data);
 	g_free (args);
 	anjuta_util_glist_strings_free (args_list);

Modified: trunk/libanjuta/anjuta-launcher.h
==============================================================================
--- trunk/libanjuta/anjuta-launcher.h	(original)
+++ trunk/libanjuta/anjuta-launcher.h	Thu Jul 17 21:09:41 2008
@@ -85,15 +85,12 @@
 								  gpointer callback_data);
 gboolean anjuta_launcher_execute_v (AnjutaLauncher *launcher,
 									gchar *const argv[],
+									gchar *const envp[],
 									AnjutaLauncherOutputCallback callback,
 									gpointer callback_data);
 void anjuta_launcher_set_encoding (AnjutaLauncher *launcher,
 									   const gchar *charset);
 
-void anjuta_launcher_set_env (AnjutaLauncher *launcher,
-							  const gchar *name,
-							  const gchar *value);
-
 void anjuta_launcher_send_stdin (AnjutaLauncher *launcher,
 								 const gchar *input_str);
 void anjuta_launcher_send_stdin_eof (AnjutaLauncher *launcher);

Modified: trunk/libanjuta/interfaces/libanjuta.idl
==============================================================================
--- trunk/libanjuta/interfaces/libanjuta.idl	(original)
+++ trunk/libanjuta/interfaces/libanjuta.idl	Thu Jul 17 21:09:41 2008
@@ -586,7 +586,15 @@
 
 	typedef gpointer Handle;
 
-	typedef void (*Callback) (GObject *sender, GError* err, gpointer user_data);
+	typedef void (*Callback) (GObject *sender, IAnjutaBuilderHandle command, GError* err, gpointer user_data);
+
+	/**
+	* IANJUTA_BUILDER_ROOT_URI
+	*
+	* Build directory uri. It is the same than the project_root_uri for
+	* in source build.
+	*/
+	#define ROOT_URI		"build_root_uri"
 
 	/** 
 	* ianjuta_builder_is_built:
@@ -702,6 +710,8 @@
 		COMMAND_CLEAN,
 		COMMAND_EXECUTE,
 		COMMAND_IS_BUILT,
+		COMMAND_AUTORECONF,
+		COMMAND_DISTCLEAN,
 		N_COMMANDS
 	}
 	

Modified: trunk/plugins/build-basic-autotools/Makefile.am
==============================================================================
--- trunk/plugins/build-basic-autotools/Makefile.am	(original)
+++ trunk/plugins/build-basic-autotools/Makefile.am	Thu Jul 17 21:09:41 2008
@@ -43,12 +43,15 @@
 	executer.c \
 	executer.h \
 	build-options.c \
-	build-options.h
+	build-options.h \
+	configuration-list.c \
+	configuration-list.h
 
 # Plugin dependencies
 libanjuta_build_basic_autotools_la_LIBADD = \
 	$(GLADE_LIBS) \
 	$(GNOME_LIBS) \
+	$(GIO_LIBS) \
 	$(LIBANJUTA_LIBS)
 
 libanjuta_build_basic_autotools_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)

Modified: trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.glade
==============================================================================
--- trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.glade	(original)
+++ trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.glade	Thu Jul 17 21:09:41 2008
@@ -241,7 +241,7 @@
   <widget 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">configure_dialog</property>
+    <property name="title" translatable="yes">Configure Project</property>
     <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
     <property name="default_width">450</property>
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
@@ -249,80 +249,146 @@
     <child internal-child="vbox">
       <widget class="GtkVBox" id="dialog-vbox2">
         <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">2</property>
         <child>
           <widget 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>
-              <widget class="GtkFrame" id="frame2">
+              <widget class="GtkCheckButton" id="force_autogen_check">
                 <property name="visible">True</property>
+                <property name="can_focus">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">GTK_SHADOW_NONE</property>
+                <property name="response_id">0</property>
+                <property name="draw_indicator">True</property>
                 <child>
-                  <widget class="GtkAlignment" id="alignment3">
+                  <widget 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="left_padding">12</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Regenerate project&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget 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>
+                  <widget 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>
-                      <widget class="GtkComboBoxEntry" id="build_options_combo">
+                      <widget 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">&lt;b&gt;Configuration:&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkComboBoxEntry" id="configuration_combo_entry">
                         <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 internal-child="entry">
-                          <widget class="GtkEntry" id="comboboxentry-entry1">
+                          <widget class="GtkEntry" id="comboboxentry-entry2">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                           </widget>
                         </child>
                       </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
                     </child>
                   </widget>
-                </child>
-                <child>
-                  <widget 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">&lt;b&gt;Build Options:&lt;/b&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
                   <packing>
-                    <property name="type">label_item</property>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
                   </packing>
                 </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkFrame" id="frame3">
-                <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_xalign">0</property>
-                <property name="shadow_type">GTK_SHADOW_NONE</property>
                 <child>
-                  <widget class="GtkAlignment" id="alignment4">
+                  <widget class="GtkAlignment" id="alignment2">
                     <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="top_padding">6</property>
                     <property name="left_padding">12</property>
                     <child>
-                      <widget class="GtkEntry" id="configure_args_entry">
+                      <widget class="GtkTable" id="table1">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <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>
+                          <widget 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>
+                          </widget>
+                          <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>
+                          <widget 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>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="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">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+                            <property name="title" translatable="yes">Select a build directory</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget 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>
+                          </widget>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
                       </widget>
                     </child>
                   </widget>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="label" translatable="yes">&lt;b&gt;Configure Options:&lt;/b&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
                   <packing>
-                    <property name="type">label_item</property>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </widget>
@@ -352,12 +418,12 @@
               </widget>
             </child>
             <child>
-              <widget class="GtkButton" id="button1">
+              <widget class="GtkButton" id="ok_button">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label">gtk-apply</property>
+                <property name="label">gtk-execute</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">-5</property>
               </widget>

Modified: trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui
==============================================================================
--- trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui	(original)
+++ trunk/plugins/build-basic-autotools/anjuta-build-basic-autotools-plugin.ui	Thu Jul 17 21:09:41 2008
@@ -10,12 +10,13 @@
 				<separator name="separator10"/>
 				<menuitem name="InstallModule" action="ActionBuildInstallModule"/>
 				<menuitem name="InstallProject" action="ActionBuildInstallProject"/>
-				<separator name="separator11"/>
-				<menuitem name="Configure" action="ActionBuildConfigure"/>
-				<menuitem name="Autogen" action="ActionBuildAutogen"/>
 				<separator name="separator12"/>
 				<menuitem name="CleanModule" action="ActionBuildCleanModule"/>
 				<menuitem name="CleanProject" action="ActionBuildCleanProject"/>
+				<separator name="separator11"/>
+				<menuitem name="Configure" action="ActionBuildConfigure"/>
+				<menuitem name="SelectConfiguration" action="ActionBuildSelectConfiguration"/>
+				<menuitem name="RemoveConfiguration" action="ActionBuildRemoveConfiguration"/>
 				<separator name="separator13"/>
 			</menu>
 		</placeholder>

Modified: trunk/plugins/build-basic-autotools/build-basic-autotools.c
==============================================================================
--- trunk/plugins/build-basic-autotools/build-basic-autotools.c	(original)
+++ trunk/plugins/build-basic-autotools/build-basic-autotools.c	Thu Jul 17 21:09:41 2008
@@ -21,6 +21,8 @@
 #include <config.h>
 #include <ctype.h>
 
+#include <glib/gstdio.h>
+#include <gio/gio.h>
 #include <libanjuta/anjuta-shell.h>
 #include <libanjuta/anjuta-launcher.h>
 #include <libanjuta/anjuta-utils.h>
@@ -60,9 +62,11 @@
 #define DEFAULT_COMMAND_IS_BUILT "make -q"
 #define DEFAULT_COMMAND_BUILD_TARBALL "make dist"
 #define DEFAULT_COMMAND_INSTALL "make install"
-#define DEFAULT_COMMAND_CONFIGURE "./configure"
-#define DEFAULT_COMMAND_GENERATE "./autogen.sh"
+#define DEFAULT_COMMAND_CONFIGURE "configure"
+#define DEFAULT_COMMAND_GENERATE "autogen.sh"
 #define DEFAULT_COMMAND_CLEAN "make clean"
+#define DEFAULT_COMMAND_DISTCLEAN "make distclean"
+#define DEFAULT_COMMAND_AUTORECONF "autoreconf -i --force"
 
 #define CHOOSE_COMMAND(plugin,command) \
 	((plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) ? \
@@ -82,6 +86,14 @@
 
 typedef struct
 {
+	gchar *project_dir;
+	gchar *build_dir;
+	gchar **argv;
+	GtkWindow *parent;
+} BuildLinkCommand;
+
+typedef struct
+{
 	gchar *pattern;
 	GRegex *regex;
 	GRegex *local_regex;
@@ -100,7 +112,8 @@
 	AnjutaPlugin *plugin;
 	
 	AnjutaLauncher *launcher;
-	gchar *command;
+	gboolean used;
+	
 	IAnjutaBuilderCallback callback;
 	gpointer user_data;
 
@@ -140,7 +153,90 @@
 static MessagePattern patterns_make_leaving[] = {{N_("make(\\[\\d+\\])?:\\s+Leaving\\s+directory\\s+`(.+)'"), NULL, NULL},
 												{N_("make(\\[\\d+\\])?:\\s+Leaving\\s+directory\\s+'(.+)'"), NULL, NULL},
 												{NULL, NULL, NULL}};
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static gchar **
+build_argv_command (const gchar *cmd_dir, const gchar *cmd, gchar **argv)
+{
+	gchar **new_cmd;
+	gchar **split_cmd;
+	guint split_len;
+	
+	split_cmd = g_strsplit (cmd, " ", 2);
+	split_len = g_strv_length (split_cmd);
+	
+	if (argv == NULL)
+	{
+		new_cmd = split_cmd;
+	}
+	else
+	{
+		guint argv_len;
+		
+		argv_len = g_strv_length (argv);
+		new_cmd = g_new (gchar *, split_len + argv_len + 1);
+		memcpy (new_cmd, split_cmd, split_len * sizeof (gchar *));
+		g_free (split_cmd);
+		memcpy (new_cmd + split_len, argv, (argv_len + 1) * sizeof (gchar *));
+		g_free (argv);
+	}
+	
+	if (cmd_dir != NULL)
+	{
+		gchar *cmd = new_cmd[0];
+		
+		new_cmd[0] = g_strconcat (cmd_dir, G_DIR_SEPARATOR_S, cmd, NULL);
+		g_free (cmd);
+	}
+	
+	return new_cmd;
+}
+
+static gchar **
+build_add_env_variable (gchar **envp, const gchar *name, const gchar *value)
+{
+	gchar **var;
+	guint len = 0;
+
+	if (envp != NULL)
+	{
+		/* Look for an already existing variable */
+		for (var = envp; *var != NULL; var++)
+		{
+			if (strcmp (*var, name) == 0)
+			{
+				/* Just update variable */
+				if (value == NULL)
+				{
+					*var[strlen(name)] = '\0';
+				}
+				else
+				{
+					g_free (*var);
+					*var = g_strconcat (name, "=", value, NULL);
+				}
+				
+				return envp;
+			}
+		}
+		len = var - envp;
+	}	
 	
+	/* Need to create a new variable */
+	var = g_new (gchar *, len + 2);
+	*var = g_strconcat (name, value == NULL ? NULL : "=", value, NULL);
+	if (envp != NULL)
+	{
+		memcpy (&var[1], envp, len * sizeof (gchar *));
+		g_free (envp);
+	}
+	var[len + 1] = NULL;
+	
+	return var;
+}
+
 /* Allow installation as root (#321455) */
 static void on_root_check_toggled(GtkWidget* toggle_button, GtkWidget* entry)
 {
@@ -289,6 +385,7 @@
 static gboolean
 build_context_destroy_command (BuildContext *context)
 {
+	if (context->used) return FALSE;
 	if (context->callback)
 	{
 		GError *err;
@@ -297,7 +394,7 @@
 		err = g_error_new_literal (ianjuta_builder_error_quark (),
 								   IANJUTA_BUILDER_ABORTED,
 								   _("Command aborted"));
-		context->callback (G_OBJECT (context->plugin), err, context->user_data);
+		context->callback (G_OBJECT (context->plugin), context, err, context->user_data);
 		g_error_free (err);
 		context->callback = NULL;
 	}
@@ -314,9 +411,6 @@
 		context->environment = NULL;
 	}
 	
-	g_free (context->command);
-	context->command = NULL;
-
 	/* Empty context, remove from pool */
 	if (context->message_view == NULL)
 	{
@@ -387,8 +481,6 @@
 build_context_reset (BuildContext *context)
 {
 	/* Reset context */
-	g_free (context->command);
-	context->command = NULL;
 	
 	ianjuta_message_view_clear (context->message_view, NULL);
 	
@@ -869,7 +961,6 @@
 		
 		/* Full path is detected from parse_error_line() */
 		file = g_file_new_for_path(filename);
-		
 		ianjuta_document_manager_goto_file_line_mark(docman, file, lineno, TRUE, NULL);
 		g_object_unref (file);
 	}
@@ -880,13 +971,11 @@
 					 gint child_pid, gint status, gulong time_taken,
 					 BuildContext *context)
 {
-	g_signal_handlers_disconnect_by_func (context->launcher,
-										  G_CALLBACK (on_build_terminated),
-										  context);
-	
+	context->used = FALSE;
 	if (context->callback != NULL)
 	{
 		GError *err = NULL;
+		IAnjutaBuilderCallback callback;
 		
 		if (WIFEXITED (status))
 		{
@@ -924,10 +1013,16 @@
 							   IANJUTA_BUILDER_TERMINATED,
 							   _("Command terminated for an unknown reason"));
 		}
-		
-		context->callback (G_OBJECT (context->plugin), err, context->user_data);	
+		callback = context->callback;	
 		context->callback = NULL;
+		callback (G_OBJECT (context->plugin), context, err, context->user_data);	
 	}
+	if (context->used)
+		return;	/* Another command is run */
+	
+	g_signal_handlers_disconnect_by_func (context->launcher,
+										  G_CALLBACK (on_build_terminated),
+										  context);
 	
 	/* Message view could have been destroyed before */
 	if (context->message_view)
@@ -1060,8 +1155,7 @@
 	
 static BuildContext*
 build_get_context (BasicAutotoolsPlugin *plugin, const gchar *dir,
-		   gboolean with_view, const gchar *command,
-		  IAnjutaBuilderCallback callback, gpointer user_data)
+		   gboolean with_view)
 {
 	BuildContext *context = NULL;
 	AnjutaPluginManager *plugin_manager;
@@ -1097,14 +1191,13 @@
 		context->environment = NULL;
 	}
 	
-	context->callback = callback;
-	context->user_data = user_data;
-	context->command = g_strdup (command);
+	context->callback = NULL;
 	context->launcher = anjuta_launcher_new ();
 	g_signal_connect (G_OBJECT (context->launcher), "child-exited",
 					  G_CALLBACK (on_build_terminated), context);
 	build_context_push_dir (context, "default", dir);
-	chdir (dir);
+	dir = g_strconcat (dir, "/", NULL);
+	g_chdir (dir);
 	
 	plugin->contexts_pool = g_list_append (plugin->contexts_pool, context);
 	
@@ -1127,98 +1220,99 @@
 	}
 }
 
-static void add_env_var (gpointer key, gpointer value, gpointer user_data)
-{
-	gchar ***var = (gchar ***)user_data;
-	
-	**var = g_strconcat (key, "=", value, NULL);
-	*var = (*var)++;
-}
-
-static BuildContext*
-build_execute_command_full (BasicAutotoolsPlugin* bplugin, const gchar *dir,
-			const gchar *command,
-			gboolean save_file, gboolean with_view, GHashTable* env,
-			IAnjutaBuilderCallback callback, gpointer user_data,
-			GError **err)
+static gboolean
+build_execute_command_in_context (BuildContext* context, const gchar *dir,
+					gchar *argv[],
+								  gchar *envp[],
+								  IAnjutaBuilderCallback callback, gpointer user_data,
+								  GError **err)
 {
-	AnjutaPlugin* plugin = ANJUTA_PLUGIN(bplugin);
-	gchar **argv;
-	gchar **envv;
-	gchar **var;
 	gchar *real_dir;
-	BuildContext *context;
-	
-	g_return_val_if_fail (command != NULL, NULL);
-
-	/* Store args and environment variables as string array */
-	if (!g_shell_parse_argv (command, NULL, &argv, NULL))
-		return NULL;
-
-	if (env)
-	{
-		gchar **var;
 
-		envv = g_new0 (gchar*, g_hash_table_size (env) + 1);
+	g_return_val_if_fail (argv != NULL, FALSE);
 
-		var = envv;
-		g_hash_table_foreach (env, add_env_var, &var);
-	}
-	else
-	{
-		envv = NULL;
-	}
-	
 	real_dir = g_strdup (dir);
 	
-	if (save_file) 
-		save_all_files (ANJUTA_PLUGIN (plugin));
-
-	context = build_get_context (bplugin, dir, with_view, command, callback, user_data);
-
-	if (context->environment)
+	context->callback = callback;
+	context->user_data = user_data;
+	context->used = TRUE;
+	
+	/* Add current directory */
+	envp = build_add_env_variable (envp, "PWD", dir);
+	
+  	if (context->environment)
 	{
-		if (!ianjuta_environment_override (context->environment, &real_dir, &argv, &envv, NULL))
+		if (!ianjuta_environment_override (context->environment, &real_dir, &argv, &envp, NULL))
 		{
 			g_object_unref (context->environment);
 			context->environment = NULL;
 		}
 	}
 	
-	/* Set environment variable */
-	if (envv)
-	{
-		for (var = envv; *var != NULL; var++)
-		{
-			gchar *val = strchr (*var, '=');
-			
-			if (val != NULL) *val++ = '\0';
-			
-			anjuta_launcher_set_env (context->launcher, *var, val);
-		}
-		g_strfreev (envv);
-	}
-	
 	if (context->message_view)
 	{
+		gchar *command;
+		
+		command = g_strjoinv (" ", argv);
 		ianjuta_message_view_buffer_append (context->message_view,
 										"Building in directory: ", NULL);
 		ianjuta_message_view_buffer_append (context->message_view, dir, NULL);
 		ianjuta_message_view_buffer_append (context->message_view, "\n", NULL);
 		ianjuta_message_view_buffer_append (context->message_view, command, NULL);
 		ianjuta_message_view_buffer_append (context->message_view, "\n", NULL);
+		g_free (command);
 	
-		anjuta_launcher_execute_v (context->launcher, argv,
+		anjuta_launcher_execute_v (context->launcher, argv, envp,
 								 on_build_mesg_arrived, context);
 	}
 	else
 	{
-		anjuta_launcher_execute_v (context->launcher, argv,
+		anjuta_launcher_execute_v (context->launcher, argv, envp,
 								 NULL, NULL);
 	}		
-	g_strfreev (argv);
 	
-	return context;
+	return TRUE;
+}	
+
+static gchar *
+target_from_source (BasicAutotoolsPlugin *plugin, const gchar *target)
+{
+	if (strcmp (plugin->project_root_dir, plugin->project_build_dir) == 0)
+	{
+		return g_strdup (target);
+	}
+	else
+	{
+		return g_strconcat (plugin->project_build_dir, target + strlen (plugin->project_root_dir), NULL);
+	}
+}
+
+static BuildContext*
+build_execute_command_full (BasicAutotoolsPlugin* bplugin, const gchar *dir,
+			gchar *argv[],
+			gboolean save_file, gboolean with_view, gchar *envp[],
+			IAnjutaBuilderCallback callback, gpointer user_data,
+			GError **err)
+{
+	AnjutaPlugin* plugin = ANJUTA_PLUGIN(bplugin);
+	BuildContext *context;
+	
+	if (save_file) 
+		save_all_files (ANJUTA_PLUGIN (plugin));
+
+	context = build_get_context (bplugin, dir, with_view);
+
+	if (build_execute_command_in_context (context, dir, argv, envp, callback, user_data, NULL))
+	{
+		
+		return context;
+	}
+	else
+	{
+		build_context_destroy (context);
+		
+		return NULL;
+	}
 }
 
 
@@ -1226,7 +1320,18 @@
 build_execute_command (BasicAutotoolsPlugin* bplugin, const gchar *dir,
 		   const gchar *command, gboolean save_file, GError **err)
 {
-	return build_execute_command_full (bplugin, dir, command, save_file, TRUE, NULL, NULL, NULL, NULL) != NULL;
+	gchar **argv;
+	gboolean ok;
+
+	/* Store args and environment variables as string array */
+	if (!g_shell_parse_argv (command, NULL, &argv, NULL))
+		return FALSE;
+	
+	ok = build_execute_command_full (bplugin, dir, argv, save_file, TRUE, NULL, NULL, NULL, NULL) != NULL;
+
+	g_strfreev (argv);
+
+	return ok;
 }
 
 static void
@@ -1256,8 +1361,9 @@
 static gboolean
 build_compile_file_real (BasicAutotoolsPlugin *plugin, const gchar *file)
 {
-	gchar *file_basename;
-	gchar *file_dirname;
+	gchar *target;
+	gchar *target_basename;
+	gchar *target_dirname;
 	gchar *ext_ptr;
 	gboolean ret;
 	
@@ -1281,10 +1387,11 @@
 	
 	g_return_val_if_fail (file != NULL, FALSE);
 	ret = FALSE;
-	
-	file_basename = g_path_get_basename (file);
-	file_dirname = g_path_get_dirname (file);
-	ext_ptr = strrchr (file_basename, '.');
+
+	target = target_from_source (plugin, file);
+	target_basename = g_path_get_basename (target);
+	target_dirname = g_path_get_dirname (target);
+	ext_ptr = strrchr (target_basename, '.');
 	if (ext_ptr)
 	{
 		const gchar *new_ext;
@@ -1295,8 +1402,8 @@
 			
 			*ext_ptr = '\0';
 			command = g_strconcat (CHOOSE_COMMAND (plugin, COMPILE), " ",
-								   file_basename, new_ext, NULL);
-			build_execute_command (plugin, file_dirname, command, TRUE, NULL);
+								   target_basename, new_ext, NULL);
+			build_execute_command (plugin, target_dirname, command, TRUE, NULL);
 			g_free (command);
 			ret = TRUE;
 		}
@@ -1304,13 +1411,14 @@
 		/* If file has no extension, take it as target itself */
 		gchar *command;
 		command = g_strconcat (CHOOSE_COMMAND(plugin, COMPILE), " ",
-							   file_basename, NULL);
-		build_execute_command (plugin, file_dirname, command, TRUE, NULL);
+							   target_basename, NULL);
+		build_execute_command (plugin, target_dirname, command, TRUE, NULL);
 		g_free (command);
 		ret = TRUE;
 	}
-	g_free (file_basename);
-	g_free (file_dirname);
+	g_free (target_basename);
+	g_free (target_dirname);
+	g_free (target);
 	if (ret == FALSE)
 	{
 		/* FIXME: Prompt the user to create a Makefile with a wizard
@@ -1329,7 +1437,7 @@
 static void
 build_build_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
-	build_execute_command (plugin, plugin->project_root_dir,
+	build_execute_command (plugin, plugin->project_build_dir,
 						   CHOOSE_COMMAND (plugin, BUILD), TRUE, NULL);
 }
 
@@ -1340,7 +1448,7 @@
 	gchar* command = g_strdup_printf("%s %s", root,
 									 CHOOSE_COMMAND (plugin, INSTALL));
 	g_free(root);
-	build_execute_command (plugin, plugin->project_root_dir,
+	build_execute_command (plugin, plugin->project_build_dir,
 						   command, TRUE, NULL);
 	g_free(command);
 }
@@ -1348,94 +1456,225 @@
 static void
 build_clean_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
-	build_execute_command (plugin, plugin->project_root_dir,
+	build_execute_command (plugin, plugin->project_build_dir,
 						   CHOOSE_COMMAND (plugin, CLEAN), FALSE, NULL);
 }
 
 static void
-build_configure_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
+build_remove_build_dir (GObject *sender,
+						IAnjutaBuilderHandle context,
+						GError *error,
+						gpointer user_data)
 {
-	gint response;
-	GtkWindow *parent;
-	gchar *input = NULL;
-	GHashTable* build_options = NULL;
 	
-	parent = GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell);
-	/* Configure = ./configure script */
-	response = build_dialog_configure (parent, _("Configure"),
-									   &build_options, 
-									   plugin->configure_args, 
-									   &input);
-	if (response)
-	{
-		gchar *cmd;
-		if (input)
-		{
-			cmd = g_strdup_printf ("%s %s", CHOOSE_COMMAND (plugin, CONFIGURE),
-								   input);
-			g_free (plugin->configure_args);
-			plugin->configure_args = input;
+}
+
+static void
+build_distclean_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
+{
+	gchar **argv;
+
+	if (!g_shell_parse_argv (CHOOSE_COMMAND (plugin, DISTCLEAN), NULL, &argv, NULL))
+		return;
+	
+	build_execute_command_full (plugin, plugin->project_build_dir, argv, TRUE, TRUE, NULL, build_remove_build_dir, plugin, NULL);
+
+	g_strfreev (argv);
+}
+
+static void
+on_select_configuration (GtkRadioMenuItem *item, gpointer user_data)
+{
+	if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
+	{
+		BasicAutotoolsPlugin *plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (user_data);
+		gchar *name;
+		GValue *value;
+		gchar *uri;	
+
+		name = g_object_get_data (G_OBJECT (item), "untranslated_name");
+
+		build_configuration_list_select (plugin->configurations, name);
+
+		value = g_new0 (GValue, 1);
+		g_value_init (value, G_TYPE_STRING);
+	
+		uri = build_configuration_list_get_build_uri (plugin->configurations, build_configuration_list_get_selected (plugin->configurations));
+		g_value_set_string (value, uri);
+		g_free (uri);
+	
+		anjuta_shell_add_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_BUILDER_ROOT_URI, value, NULL);	
+	}
+}
+
+static void
+build_update_configuration_menu (BasicAutotoolsPlugin *plugin)
+{
+	GtkWidget *submenu = NULL;
+	BuildConfiguration *cfg;
+	BuildConfiguration *selected;
+	GSList *group = NULL;
+	
+	submenu = gtk_menu_new ();
+	selected = build_configuration_list_get_selected (plugin->configurations);
+	for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
+	{
+		GtkWidget *item;
+		
+		item = gtk_radio_menu_item_new_with_mnemonic (group, build_configuration_get_translated_name (cfg));
+		group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
+		if (cfg == selected)
+		{
+			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
+		}
+		g_object_set_data_full (G_OBJECT (item), "untranslated_name", g_strdup (build_configuration_get_name (cfg)), g_free);
+		g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (on_select_configuration), plugin);
+		gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
+	}
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (plugin->configuration_menu), submenu);
+	gtk_widget_show_all (submenu);
+}
+
+static void
+build_project_configured (GObject *sender,
+							IAnjutaBuilderHandle context,
+							GError *error,
+							gpointer user_data)
+{
+	BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)sender;
+	GValue *value;
+	gchar *uri;
+	
+	value = g_new0 (GValue, 1);
+	g_value_init (value, G_TYPE_STRING);
+	
+	uri = build_configuration_list_get_build_uri (plugin->configurations, build_configuration_list_get_selected (plugin->configurations));
+	g_value_set_string (value, uri);
+	g_free (uri);
+	
+	anjuta_shell_add_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_BUILDER_ROOT_URI, value, NULL);
+	
+	build_update_configuration_menu (plugin);
+}
+
+static void
+build_configure_project_after_autogen (GObject *sender,
+									   IAnjutaBuilderHandle context,
+									   GError *error,
+									   gpointer user_data)
+{
+	BuildLinkCommand *link = (BuildLinkCommand *)user_data;
+	BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)sender;
+	
+	if (error == NULL)
+	{
+		struct stat conf_stat, log_stat;
+		gchar *filename;
+		
+		filename = g_build_filename (link->project_dir, "configure", NULL);
+		if (stat (filename, &conf_stat) != 0)
+		{
+			anjuta_util_dialog_error (link->parent, _("Can not configure project: Missing configure script in %s."), link->project_dir);
 		}
 		else
 		{
-			cmd = g_strdup (CHOOSE_COMMAND (plugin, CONFIGURE));
+			g_free (filename);
+			filename = g_build_filename (link->build_dir, "config.log", NULL);
+			stat (filename, &log_stat);
+			DEBUG_PRINT("log %d conf %d", log_stat.st_mtime, conf_stat.st_mtime);
+			if ((stat (filename, &log_stat) != 0) ||
+				(log_stat.st_mtime < conf_stat.st_mtime))
+			{
+				link->argv = build_argv_command (link->project_dir,
+												 CHOOSE_COMMAND (plugin, CONFIGURE),
+												 link->argv);
+				build_execute_command_in_context ((BuildContext *)context, link->build_dir, link->argv, 
+												  NULL, build_project_configured, NULL, NULL);
+			}
 		}
-		build_execute_command_full (plugin, plugin->project_root_dir, 
-					   cmd, TRUE, TRUE, build_options,
-					   NULL, NULL, NULL);
-		g_free (cmd);
-		g_hash_table_destroy (build_options);
+		g_free (filename);
 	}
+	
+	g_free (link->project_dir);
+	g_free (link->build_dir);
+	g_strfreev (link->argv);
+	g_free (link);
 }
 
 static void
-build_autogen_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
+build_configure_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
-	gint response;
 	GtkWindow *parent;
-	gchar *input = NULL;
-	GHashTable* build_options = NULL;
+	gboolean run_autogen = FALSE;
+	const gchar *project_root;
+	GValue value = {0,};
+
+	run_autogen = !directory_has_file (plugin->project_root_dir, "configure");
 	
+	anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, &value, NULL);
+	project_root = g_value_get_string (&value);
 	parent = GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell);
-	response = build_dialog_configure (parent, _("Autogenerate"),
-									   &build_options, 
-									   plugin->configure_args, 
-									   &input);
-	if (response)
-	{
-		gboolean has_autogen = directory_has_file (plugin->project_root_dir,
-												   "autogen.sh");
-		gchar *cmd;
-		if (input)
-		{
-			if (has_autogen)
-				cmd = g_strdup_printf ("%s %s",
-									   CHOOSE_COMMAND (plugin, GENERATE),
-									   input);
-			else /* FIXME: Get override command for this too */
-				cmd = g_strconcat ("autoreconf -i --force ", input, NULL);
-			g_free (plugin->configure_args);
-			plugin->configure_args = input;
+	if (build_dialog_configure (parent, project_root, plugin->configurations, &run_autogen))
+	{
+		BuildConfiguration *config;
+		gchar **argv;
+		GFile *build_file;
+		gchar *build_dir;
+		gchar *uri;
+
+		config = build_configuration_list_get_selected (plugin->configurations);
+		uri = build_configuration_list_get_build_uri (plugin->configurations, config);
+		build_file = g_file_new_for_uri (uri);
+		g_free (uri);
+		build_dir = g_file_get_path (build_file);
+		g_object_unref (build_file);
+		
+		IAnjutaBuilderCallback callback = NULL;
+		BuildLinkCommand* user_data = NULL;
+
+		if (run_autogen)
+		{
+			gboolean has_autogen = directory_has_file (plugin->project_root_dir,
+													   "autogen.sh");
+			
+			gchar **args = g_strdupv (build_configuration_get_args (config));
+			argv = build_argv_command (plugin->project_root_dir,
+									   has_autogen ? CHOOSE_COMMAND (plugin, GENERATE) : CHOOSE_COMMAND (plugin, AUTORECONF),
+									   args);
+									   
+			
+			/* Plan to run configure afterward */
+			user_data = g_new (BuildLinkCommand, 1);
+			user_data->project_dir = g_strdup (plugin->project_root_dir);
+			user_data->build_dir = g_strdup (build_dir);
+		    /* Remove command name from argument array */
+			user_data->argv = g_strdupv (&argv[1]); 
+			user_data->parent = parent;
+		
+			callback = build_configure_project_after_autogen;
 		}
 		else
 		{
-			if (has_autogen)
-				cmd = g_strdup (CHOOSE_COMMAND (plugin, GENERATE));
-			else /* FIXME: Get override command for this too */
-				cmd = g_strdup ("autoreconf -i --force");
-		}
-		build_execute_command_full (plugin, plugin->project_root_dir, 
-					cmd, TRUE, TRUE, build_options,
-		 			NULL, NULL, NULL);
-		g_free (cmd);
-		g_hash_table_destroy (build_options);
+			/* Run configure only */
+			gchar **args = g_strdupv (build_configuration_get_args (config));
+			
+			argv = build_argv_command (plugin->project_root_dir,
+									   CHOOSE_COMMAND (plugin, CONFIGURE),
+									   args);
+			callback = build_project_configured;
+		}
+		build_execute_command_full (plugin, build_dir, 
+					   argv, TRUE, TRUE, NULL,
+					   callback, user_data, NULL);
+		g_strfreev (argv);
+		g_free (build_dir);
 	}
 }
 
 static void
 build_distribution_project (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
-	build_execute_command (plugin, plugin->project_root_dir,
+	build_execute_command (plugin, plugin->project_build_dir,
 			   CHOOSE_COMMAND (plugin, BUILD_TARBALL),
 			   FALSE, NULL);
 }
@@ -1444,9 +1683,12 @@
 build_build_module (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dirname = g_dirname (plugin->current_editor_filename);
-	build_execute_command (plugin, dirname,
+	gchar *target = target_from_source (plugin, dirname);
+
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, BUILD),
 			   TRUE, NULL);
+	g_free (target);
 	g_free (dirname);
 }
 
@@ -1455,11 +1697,13 @@
 {
 	gchar *dirname = g_dirname (plugin->current_editor_filename);
 	gchar* root = get_root_install_command(plugin);
+	gchar *target = target_from_source (plugin, dirname);
 	gchar* command = g_strdup_printf ("%s %s", root,
 									  CHOOSE_COMMAND (plugin, INSTALL));
 	g_free(root);
-	build_execute_command (plugin, dirname, command, TRUE, NULL);
+	build_execute_command (plugin, target, command, TRUE, NULL);
 	g_free(command);
+	g_free (target);
 	g_free (dirname);
 }
 
@@ -1467,9 +1711,11 @@
 build_clean_module (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dirname = g_dirname (plugin->current_editor_filename);
-	build_execute_command (plugin, dirname,
+	gchar *target = target_from_source (plugin, dirname);
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, CLEAN),
 			   FALSE, NULL);
+	g_free (target);
 	g_free (dirname);
 }
 
@@ -1496,6 +1742,7 @@
 fm_build (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dir;
+	gchar *target;
 	
 	g_return_if_fail (plugin->fm_current_filename != NULL);
 	
@@ -1503,9 +1750,12 @@
 		dir = g_strdup (plugin->fm_current_filename);
 	else
 		dir = g_path_get_dirname (plugin->fm_current_filename);
-	build_execute_command (plugin, dir,
+	target = target_from_source (plugin, dir);
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, BUILD),
 			   TRUE, NULL);
+	g_free (target);
+	g_free (dir);
 }
 
 static void
@@ -1514,6 +1764,7 @@
 	gchar *dir;
 	gchar* root; 
 	gchar* command; 
+	gchar *target;
 	
 	g_return_if_fail (plugin->fm_current_filename != NULL);
 	
@@ -1526,13 +1777,16 @@
 	command = g_strdup_printf ("%s %s", root,
 							   CHOOSE_COMMAND (plugin, INSTALL));
 	g_free(root);
+	target = target_from_source (plugin, dir);
 	build_execute_command (plugin, dir, command, TRUE, NULL);
+	g_free (target);
 }
 
 static void
 fm_clean (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dir;
+	gchar *target;
 	
 	g_return_if_fail (plugin->fm_current_filename != NULL);
 	
@@ -1540,9 +1794,12 @@
 		dir = g_strdup (plugin->fm_current_filename);
 	else
 		dir = g_path_get_dirname (plugin->fm_current_filename);
-	build_execute_command (plugin, dir,
+	
+	target = target_from_source (plugin, dir);
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, CLEAN),
 			   FALSE, NULL);
+	g_free (target);
 }
 
 /* Project manager context menu */
@@ -1559,6 +1816,7 @@
 pm_build (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dir;
+	gchar *target;
 	
 	g_return_if_fail (plugin->pm_current_filename != NULL);
 	
@@ -1566,15 +1824,19 @@
 		dir = g_strdup (plugin->pm_current_filename);
 	else
 		dir = g_path_get_dirname (plugin->pm_current_filename);
-	build_execute_command (plugin, dir,
+	target = target_from_source (plugin, dir);
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, BUILD),
 			   TRUE, NULL);
+	g_free (target);
+	g_free (dir);
 }
 
 static void
 pm_install (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dir;
+	gchar *target;
 	gchar* root; 
 	gchar* command; 
 	
@@ -1589,14 +1851,18 @@
 		dir = g_strdup (plugin->pm_current_filename);
 	else
 		dir = g_path_get_dirname (plugin->pm_current_filename);
-	build_execute_command (plugin, dir, command, TRUE, NULL);
+	target = target_from_source (plugin, dir);
+	build_execute_command (plugin, target, command, TRUE, NULL);
 	g_free(command);
+	g_free (target);
+	g_free (dir);
 }
 
 static void
 pm_clean (GtkAction *action, BasicAutotoolsPlugin *plugin)
 {
 	gchar *dir;
+	gchar *target;
 	
 	g_return_if_fail (plugin->pm_current_filename != NULL);
 	
@@ -1604,9 +1870,12 @@
 		dir = g_strdup (plugin->pm_current_filename);
 	else
 		dir = g_path_get_dirname (plugin->pm_current_filename);
-	build_execute_command (plugin, dir,
+	target = target_from_source (plugin, dir);
+	build_execute_command (plugin, target,
 			   CHOOSE_COMMAND (plugin, CLEAN),
 			   FALSE, NULL);
+	g_free (dir);
+	g_free (target);
 }
 
 static GtkActionEntry build_actions[] = 
@@ -1635,17 +1904,11 @@
 	},
 	{
 		"ActionBuildConfigure", NULL,
-		N_("Run C_onfigure..."), NULL,
+		N_("C_onfigure Project..."), NULL,
 		N_("Configure project"),
 		G_CALLBACK (build_configure_project)
 	},
 	{
-		"ActionBuildAutogen", NULL,
-		N_("Run _Autogenerate..."), NULL,
-		N_("Autogenerate project files"),
-		G_CALLBACK (build_autogen_project)
-	},
-	{
 		"ActionBuildDistribution", NULL,
 		N_("Build _Tarball"), NULL,
 		N_("Build project tarball distribution"),
@@ -1674,6 +1937,18 @@
 		N_("Co_mpile File"), "F9",
 		N_("Compile current editor file"),
 		G_CALLBACK (build_compile_file)
+	},
+	{
+		"ActionBuildSelectConfiguration", NULL,
+		N_("Select Configuration"), NULL,
+		N_("Select current configuration"),
+		NULL
+	},
+	{
+		"ActionBuildRemoveConfiguration", NULL,
+		N_("Remove Configuration"), NULL,
+		N_("Clean project (distclean) and remove configuration directory if possible"),
+		G_CALLBACK (build_distclean_project)
 	}
 };
 
@@ -1778,64 +2053,6 @@
 	return exists;
 }
 
-static void
-update_project_ui (BasicAutotoolsPlugin *bb_plugin)
-{
-	AnjutaUI *ui;
-	GtkAction *action;
-	
-	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin)->shell, NULL);
-	
-	DEBUG_PRINT ("Updateing project UI");
-	
-	if (!bb_plugin->project_root_dir)
-	{
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildBuildProject");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildInstallProject");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildCleanProject");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildDistribution");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildConfigure");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildAutogen");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-		return;
-	}
-	if (directory_has_makefile (bb_plugin->project_root_dir))
-	{
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildBuildProject");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildInstallProject");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildCleanProject");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildDistribution");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-	}			
-	if (directory_has_file (bb_plugin->project_root_dir, "configure"))
-	{
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildConfigure");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-	}
-	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-								   "ActionBuildAutogen");
-	g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
-}
-
 static gchar*
 escape_label (const gchar *str)
 {
@@ -1871,102 +2088,150 @@
 {
 	AnjutaUI *ui;
 	GtkAction *action;
-	gchar *dirname;
-	gchar *module;
-	gchar *filename;
+	gchar *filename= NULL;
+	gchar *module = NULL;
 	gchar *label;
+	gboolean has_makefile= FALSE;
 
 	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin)->shell, NULL);
 	
-	DEBUG_PRINT ("Updateing module UI");
+	DEBUG_PRINT ("Updating module UI");
 	
-	if (!bb_plugin->current_editor_filename)
+	if (bb_plugin->current_editor_filename != NULL)
 	{
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildBuildModule");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE,
-					  "label", _("_Build"), NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildInstallModule");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE,
-					  "label", _("_Install"), NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildCleanModule");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE,
-					  "label", _("_Clean"), NULL);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildCompileFile");
-		g_object_set (G_OBJECT (action), "sensitive", FALSE,
-					  "label", _("Co_mpile"), NULL);
-		return;
+		gchar *dirname;
+		gchar *build_dirname;
+
+		dirname = g_dirname (bb_plugin->current_editor_filename);
+		build_dirname = target_from_source (bb_plugin, dirname);
+		
+		module = escape_label (g_basename (dirname));
+		filename = escape_label (g_basename (bb_plugin->current_editor_filename));
+		has_makefile = directory_has_makefile (build_dirname);
+		g_free (build_dirname);
+		g_free (dirname);
 	}
+
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildBuildModule");
+	label = g_strdup_printf (module ? _("_Build (%s)") : _("_Build"), module);
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile,
+					  "label", label, NULL);
+	g_free (label);
+
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildInstallModule");
+	label = g_strdup_printf (module ? _("_Install (%s)") : _("_Install"), module);
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile,
+					  "label", label, NULL);
+	g_free (label);
+
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildCleanModule");
+	label = g_strdup_printf (module ? _("_Clean (%s)") : _("_Clean"), module);
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile,
+					  "label", label, NULL);
+	g_free (label);
+	
 	
-	dirname = g_dirname (bb_plugin->current_editor_filename);
-	module = escape_label (g_basename (dirname));
-	filename = escape_label (g_basename (bb_plugin->current_editor_filename));
-	if (directory_has_makefile (dirname))
-	{
-		label = g_strdup_printf (_("_Build (%s)"), module);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildBuildModule");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE,
-					  /*"label", label, */NULL);
-		g_free (label);
-		
-		label = g_strdup_printf (_("_Install (%s)"), module);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildInstallModule");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE,
-					  /* "label", label, */NULL);
-		g_free (label);
-		
-		label = g_strdup_printf (_("_Clean (%s)"), module);
-		action = anjuta_ui_get_action (ui, "ActionGroupBuild",
-									   "ActionBuildCleanModule");
-		g_object_set (G_OBJECT (action), "sensitive", TRUE,
-					  /* "label", label,*/ NULL);
-		g_free (label);
-	}
-	label = g_strdup_printf (_("Co_mpile (%s)"), filename);
 	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
 								   "ActionBuildCompileFile");
-	g_object_set (G_OBJECT (action), "sensitive", TRUE,
-				  /* "label", label, */ NULL);
+	label = g_strdup_printf (filename ? _("Co_mpile (%s)") : _("Co_mpile"), filename);
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile,
+					  "label", label, NULL);
 	g_free (label);
+	
 	g_free (module);
 	g_free (filename);
-	g_free (dirname);
+}
+
+static void
+update_project_ui (BasicAutotoolsPlugin *bb_plugin)
+{
+	AnjutaUI *ui;
+	GtkAction *action;
+	gboolean has_makefile;
+	gboolean has_project;
+	
+	DEBUG_PRINT ("Updating project UI");
+	
+	has_project = bb_plugin->project_root_dir != NULL;
+	has_makefile = has_project && directory_has_makefile (bb_plugin->project_build_dir);
+
+	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin)->shell, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildBuildProject");
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildInstallProject");
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildCleanProject");
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildDistribution");
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildConfigure");
+	g_object_set (G_OBJECT (action), "sensitive", has_project, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildSelectConfiguration");
+	g_object_set (G_OBJECT (action), "sensitive", has_project, NULL);
+	action = anjuta_ui_get_action (ui, "ActionGroupBuild",
+								   "ActionBuildRemoveConfiguration");
+	g_object_set (G_OBJECT (action), "sensitive", has_makefile, NULL);
+	
+	update_module_ui (bb_plugin);
 }
 
 static void
 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
 				 AnjutaSession *session, BasicAutotoolsPlugin *plugin)
 {
+	GList *configurations;
+	BuildConfiguration *cfg;
+	const gchar *name;
+	
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 	
-	if (plugin->configure_args)
-		anjuta_session_set_string (session, "Build",
-								   "Configure parameters",
-								   plugin->configure_args);
+	configurations = build_configuration_list_to_string_list (plugin->configurations);
+	anjuta_session_set_string_list (session, "Build",
+									"Configuration list",
+									configurations);
+	g_list_foreach (configurations, (GFunc)g_free, NULL);
+	g_list_free (configurations);
+	
+	cfg = build_configuration_list_get_selected (plugin->configurations);
+	if (cfg != NULL)
+	{
+		name = build_configuration_get_name (cfg);
+		anjuta_session_set_string (session, "Build", "Selected Configuration", name);
+	}
 }
 
 static void
 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
 				 AnjutaSession *session, BasicAutotoolsPlugin *plugin)
 {
-	gchar *configure_args;
+	GList *configurations;
+	gchar *selected;
 				
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 	
-	configure_args = anjuta_session_get_string (session, "Build",
-											  "Configure parameters");
-	if (configure_args)
-	{
-		g_free (plugin->configure_args);
-		plugin->configure_args = configure_args;
-	}
+	configurations = anjuta_session_get_string_list (session, "Build",
+											  "Configuration list");
+	
+	build_configuration_list_from_string_list (plugin->configurations, configurations);
+	g_list_foreach (configurations, (GFunc)g_free, NULL);
+	g_list_free (configurations);
+	
+	selected = anjuta_session_get_string (session, "Build", "Selected Configuration");
+	build_configuration_list_select (plugin->configurations, selected);
+	g_free (selected);
+
+	build_project_configured (G_OBJECT (plugin), NULL, NULL, NULL);
 }
 
 static void
@@ -2108,8 +2373,6 @@
 
 	bb_plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin);
 	
-	DEBUG_PRINT ("Project added");
-	
 	g_free (bb_plugin->project_root_dir);
 	bb_plugin->project_root_dir = NULL;
 	
@@ -2120,11 +2383,16 @@
 		bb_plugin->project_root_dir =
 			g_file_get_path(file);
 		g_object_unref (file);
-		if (bb_plugin->project_root_dir)
-		{
-			update_project_ui (bb_plugin);
-		}
 	}
+	
+	build_configuration_list_set_project_uri (bb_plugin->configurations, root_uri);
+	
+	/* Export project build uri */
+	anjuta_shell_add_value (ANJUTA_PLUGIN(plugin)->shell,
+							IANJUTA_BUILDER_ROOT_URI,
+							value, NULL);	
+	
+	update_project_ui (bb_plugin);
 }
 
 static void
@@ -2136,13 +2404,44 @@
 	bb_plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin);
 	
 	g_free (bb_plugin->project_root_dir);
+	g_free (bb_plugin->project_build_dir);
 	g_free (bb_plugin->program_args);
-	g_free (bb_plugin->configure_args);
 	
 	bb_plugin->run_in_terminal = TRUE;
 	bb_plugin->program_args = NULL;
-	bb_plugin->configure_args = NULL;
+	bb_plugin->configurations = NULL;
+	bb_plugin->project_build_dir = NULL;
 	bb_plugin->project_root_dir = NULL;
+
+	build_configuration_list_set_project_uri (bb_plugin->configurations, NULL);
+	
+	/* Export project build uri */
+	anjuta_shell_remove_value (ANJUTA_PLUGIN (plugin)->shell,
+							   IANJUTA_BUILDER_ROOT_URI, NULL);
+	
+	update_project_ui (bb_plugin);
+}
+
+static void
+value_added_project_build_uri (AnjutaPlugin *plugin, const gchar *name,
+							  const GValue *value, gpointer user_data)
+{
+	BasicAutotoolsPlugin *bb_plugin;
+	const gchar *build_uri;
+
+	bb_plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin);
+	
+	g_free (bb_plugin->project_build_dir);
+	bb_plugin->project_build_dir = NULL;
+	
+	build_uri = g_value_get_string (value);
+	if (build_uri)
+	{
+		GFile* file = g_file_new_for_uri (build_uri);
+		bb_plugin->project_build_dir =
+			g_file_get_path(file);
+		g_object_unref (file);
+	}
 	update_project_ui (bb_plugin);
 }
 
@@ -2322,8 +2621,9 @@
 	/* Add UI */
 	ba_plugin->build_merge_id = anjuta_ui_merge (ui, UI_FILE);
 
+	ba_plugin->configuration_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui),
+                                        "/MenuMain/PlaceHolderBuildMenus/MenuBuild/SelectConfiguration");
 	update_project_ui (ba_plugin);
-	update_module_ui (ba_plugin);
 	
 	/* Add watches */
 	ba_plugin->fm_watch_id = 
@@ -2334,14 +2634,19 @@
 		anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_CURRENT_URI,
 								 value_added_pm_current_uri,
 								 value_removed_pm_current_uri, NULL);
-	ba_plugin->project_watch_id = 
+	ba_plugin->project_root_watch_id = 
 		anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
 								 value_added_project_root_uri,
 								 value_removed_project_root_uri, NULL);
+	ba_plugin->project_build_watch_id = 
+		anjuta_plugin_add_watch (plugin, IANJUTA_BUILDER_ROOT_URI,
+								 value_added_project_build_uri,
+								 NULL, NULL);
 	ba_plugin->editor_watch_id = 
 		anjuta_plugin_add_watch (plugin,  IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
 								 value_added_current_editor,
 								 value_removed_current_editor, NULL);
+	
 	initialized = TRUE;
 	return TRUE;
 }
@@ -2364,7 +2669,8 @@
 	/* Remove watches */
 	anjuta_plugin_remove_watch (plugin, ba_plugin->fm_watch_id, TRUE);
 	anjuta_plugin_remove_watch (plugin, ba_plugin->pm_watch_id, TRUE);
-	anjuta_plugin_remove_watch (plugin, ba_plugin->project_watch_id, TRUE);
+	anjuta_plugin_remove_watch (plugin, ba_plugin->project_root_watch_id, TRUE);
+	anjuta_plugin_remove_watch (plugin, ba_plugin->project_build_watch_id, TRUE);
 	anjuta_plugin_remove_watch (plugin, ba_plugin->editor_watch_id, TRUE);
 	
 	/* Remove UI */
@@ -2397,16 +2703,18 @@
 	g_free (ba_plugin->fm_current_filename);
 	g_free (ba_plugin->pm_current_filename);
 	g_free (ba_plugin->project_root_dir);
+	g_free (ba_plugin->project_build_dir);
 	g_free (ba_plugin->current_editor_filename);
 	g_free (ba_plugin->program_args);
-	g_free (ba_plugin->configure_args);
+	build_configuration_list_free (ba_plugin->configurations);
 	
 	ba_plugin->fm_current_filename = NULL;
 	ba_plugin->pm_current_filename = NULL;
 	ba_plugin->project_root_dir = NULL;
+	ba_plugin->project_build_dir = NULL;
 	ba_plugin->current_editor_filename = NULL;
 	ba_plugin->program_args = NULL;
-	ba_plugin->configure_args = NULL;
+	ba_plugin->configurations = NULL;
 	
 	G_OBJECT_CLASS (parent_class)->finalize (obj);
 }
@@ -2423,10 +2731,11 @@
 	ba_plugin->fm_current_filename = NULL;
 	ba_plugin->pm_current_filename = NULL;
 	ba_plugin->project_root_dir = NULL;
+	ba_plugin->project_build_dir = NULL;
 	ba_plugin->current_editor = NULL;
 	ba_plugin->current_editor_filename = NULL;
 	ba_plugin->contexts_pool = NULL;
-	ba_plugin->configure_args = NULL;
+	ba_plugin->configurations = build_configuration_list_new ();
 	ba_plugin->program_args = NULL;
 	ba_plugin->run_in_terminal = TRUE;
 	ba_plugin->last_exec_uri = NULL;
@@ -2614,24 +2923,23 @@
 	BasicAutotoolsPlugin *plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder);
 	BuildContext *context;
 	gchar *filename;
-	gchar *target;
 	gchar *dirname;
-	gchar *cmd;
+	gchar **argv;
+	gchar **args = g_new0 (gchar *, 2);
 	GFile* file = g_file_new_for_uri (uri);
 	
 	filename = g_file_get_path (file);
 	g_object_unref (file);
 	if (filename == NULL) return NULL;
-	target = g_path_get_basename (filename);
+	args[0] = g_path_get_basename (filename);
 	dirname = g_path_get_dirname (filename);
 	g_free (filename);	
-	cmd = g_strconcat (CHOOSE_COMMAND (plugin, IS_BUILT), " ", target, NULL);
-	g_free (target);
+	argv = build_argv_command (NULL, CHOOSE_COMMAND (plugin, IS_BUILT), args);
 	
-	context = build_execute_command_full (plugin, dirname, cmd,
+	context = build_execute_command_full (plugin, dirname, argv,
 			       			TRUE, FALSE, NULL,
 			       			callback, user_data, err);
-	g_free (cmd);
+	g_strfreev (argv);
 	g_free (dirname);
 	
 	return (IAnjutaBuilderHandle)context;
@@ -2645,25 +2953,24 @@
 	BasicAutotoolsPlugin *plugin = ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder);
 	BuildContext *context;
 	gchar *filename;
-	gchar *target;
 	gchar *dirname;
-	gchar *cmd;
+	gchar **argv;
+	gchar **args = g_new0 (gchar *, 2);
 	GFile* file = g_file_new_for_uri (uri);
 
 	filename = g_file_get_path (file);
 	g_object_unref (file);
 	if (filename == NULL) return NULL;
-	target = g_path_get_basename (filename);
+	args[0] = g_path_get_basename (filename);
 	dirname = g_path_get_dirname (filename);
 	g_free (filename);	
-	cmd = g_strconcat (CHOOSE_COMMAND (plugin, BUILD), " ", target, NULL);
-	g_free (target);
+	argv = build_argv_command (NULL, CHOOSE_COMMAND (plugin, BUILD), args);
 
-	context = build_execute_command_full (plugin, dirname, cmd,
+	context = build_execute_command_full (plugin, dirname, argv,
 		       				TRUE, TRUE, NULL,
 						callback, user_data, err);
 
-	g_free (cmd);
+	g_strfreev (argv);
 	g_free (dirname);
 	
 	return (IAnjutaBuilderHandle)context;

Modified: trunk/plugins/build-basic-autotools/build-basic-autotools.h
==============================================================================
--- trunk/plugins/build-basic-autotools/build-basic-autotools.h	(original)
+++ trunk/plugins/build-basic-autotools/build-basic-autotools.h	Thu Jul 17 21:09:41 2008
@@ -24,6 +24,8 @@
 #include <libanjuta/anjuta-plugin.h>
 #include <libanjuta/interfaces/ianjuta-buildable.h>
 
+#include "configuration-list.h"
+
 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-build-basic-autotools-plugin.glade"
 
 extern GType basic_autotools_plugin_get_type (GTypeModule *module);
@@ -46,13 +48,15 @@
 	/* Watch IDs */
 	gint fm_watch_id;
 	gint pm_watch_id;
-	gint project_watch_id;
+	gint project_root_watch_id;
+	gint project_build_watch_id;
 	gint editor_watch_id;
 	
 	/* Watched values */
 	gchar *fm_current_filename;
 	gchar *pm_current_filename;
 	gchar *project_root_dir;
+	gchar *project_build_dir;
 	gchar *current_editor_filename;
 	IAnjutaEditor *current_editor;
 	
@@ -60,13 +64,13 @@
 	gint build_merge_id;
 	GtkActionGroup *build_action_group;
 	GtkActionGroup *build_popup_action_group;
+	GtkWidget *configuration_menu;
 	
 	/* commands overrides */
 	gchar *commands[IANJUTA_BUILDABLE_N_COMMANDS];
 	
 	/* Build parameters */
-	gchar *configure_args;
-	gchar *build_options;
+	BuildConfigurationList *configurations;
 	
 	/* Execution parameters */
 	gchar *program_args;

Modified: trunk/plugins/build-basic-autotools/build-options.c
==============================================================================
--- trunk/plugins/build-basic-autotools/build-options.c	(original)
+++ trunk/plugins/build-basic-autotools/build-options.c	Thu Jul 17 21:09:41 2008
@@ -1,132 +1,377 @@
-/***************************************************************************
- *            build-options.c
- *
- *  Sat Mar  1 20:47:23 2008
- *  Copyright  2008  Johannes Schmid
- *  <jhs gnome org>
- ****************************************************************************/
-
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * 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 Library 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
- */
- 
+    build-options.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
 
 #include "build-options.h"
+
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <glade/glade-xml.h>
 #include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-shell.h>
 #include <string.h>
 
+/* Constants
+ *---------------------------------------------------------------------------*/
+
 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-build-basic-autotools-plugin.glade"
 
-typedef struct
+#define CONFIGURE_DIALOG "configure_dialog"
+#define RUN_AUTOGEN_CHECK "force_autogen_check"
+#define CONFIGURATION_COMBO "configuration_combo_entry"
+#define BUILD_DIR_CHOOSER "build_dir_chooser"
+#define CONFIGURE_ARGS_ENTRY "configure_args_entry"
+#define OK_BUTTON "ok_button"
+
+#define GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK (build_gtk_file_chooser_create_directory_get_quark ())
+
+
+/* Type defintions
+ *---------------------------------------------------------------------------*/
+
+typedef struct _BuildConfigureDialog BuildConfigureDialog;
+
+struct _BuildConfigureDialog
 {
-	gchar* label;
-	gchar* options;
-} Options;
-
-const Options gcc[] = {
-	{N_("Default"), ""},
-	{N_("Debug"), "-g -O0"},
-	{N_("Profiling"), "-g -pg"},
-	{N_("Optimized"), "-O2"}
+ 	GtkWidget *win;
+	
+	GtkWidget *combo;
+	GtkWidget *autogen;
+	GtkWidget *build_dir_chooser;
+	GtkWidget *args;
+	GtkWidget *ok;
+	
+	BuildConfigurationList *config_list;
+	
+	const gchar *project_uri;
 };
 
-enum
+typedef struct _BuildMissingDirectory BuildMissingDirectory;
+
+struct _BuildMissingDirectory
 {
-	COLUMN_LABEL,
-	COLUMN_OPTIONS,
-	N_COLUMNS
+	gsize exist;
+	gchar uri[0];
 };
 
-static void 
-fill_options_combo (GtkComboBoxEntry* combo)
+
+/* Create directory at run time for GtkFileChooserButton
+ *---------------------------------------------------------------------------*/
+
+/* Create a directories, including parents if necessary, return 
+ * */
+
+static GFile*
+build_make_directories (GFile *file,
+							   GCancellable *cancellable,
+							   GError **error)
+{
+	GError *path_error = NULL;
+	GList *children = NULL;
+	GFile *parent;
+	
+	parent = g_file_get_parent(file);
+
+	for (;;)
+	{
+		if (g_file_make_directory (file, NULL, &path_error))
+		{
+			/* Making child directory succeed */
+			if (children == NULL)
+			{
+				/* All directories have been created */
+				return parent;
+			}
+			else
+			{
+				/* Get next child directory */
+				g_object_unref (file);
+				file = (GFile *)children->data;
+				children = g_list_delete_link (children, children);
+			}
+		}
+		else if (path_error->code == G_IO_ERROR_NOT_FOUND)
+		{
+			g_clear_error (&path_error);
+			children = g_list_prepend (children, file);
+			file = parent;
+			parent = g_file_get_parent(file);
+		}
+		else
+		{
+			g_object_unref (parent);
+			g_propagate_error (error, path_error);
+			
+			return NULL;
+		}
+	}				
+}
+
+static GQuark
+build_gtk_file_chooser_create_directory_get_quark (void)
+{
+  static GQuark quark = 0;
+
+  if (quark == 0)
+    quark = g_quark_from_static_string ("gtk-file-chooser-create-directory");
+  
+  return quark;
+}
+
+/* Remove created directory */
+static void
+on_build_missing_directory_destroyed (BuildMissingDirectory* dir)
+{
+	/* Remove previously created directories */
+	GFile* created_dir;
+	GFile* existing_dir;
+		
+	created_dir = g_file_new_for_uri (dir->uri);
+	dir->uri[dir->exist] = '\0';
+	existing_dir = g_file_new_for_uri (dir->uri);
+
+	for (;!g_file_equal (created_dir, existing_dir);)
+	{
+		GFile *parent_dir;
+			
+		if (!g_file_delete (created_dir, NULL, NULL)) break;
+		parent_dir = g_file_get_parent (created_dir);
+		g_object_unref (created_dir);
+		created_dir = parent_dir;
+	}
+	g_object_unref (created_dir);
+	g_object_unref (existing_dir);
+	g_free (dir);
+}
+
+/* If the folder is missing created it before setting it */
+
+static gboolean
+build_gtk_file_chooser_create_and_set_current_folder_uri (GtkFileChooser *chooser, const gchar *uri)
+{
+	GFile *dir;
+	GError *error = NULL;
+	GFile *parent;
+	
+	dir = g_file_new_for_uri (uri);
+	parent = build_make_directories (dir, NULL, &error);
+	if (parent != NULL)
+	{
+		BuildMissingDirectory* dir;
+		gchar *last;
+		gsize len;
+
+		len = strlen (uri);
+		dir = (BuildMissingDirectory *)g_new (char, sizeof (BuildMissingDirectory) + len + 1);
+		
+		memcpy (dir->uri, uri, len + 1);
+		last = g_file_get_uri (parent);
+		dir->exist = strlen (last);
+		
+		g_object_set_qdata_full (G_OBJECT (chooser),
+								 GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK,
+								 dir,
+								 (GDestroyNotify)on_build_missing_directory_destroyed);		
+	}
+	else
+	{
+		g_object_set_qdata (G_OBJECT (chooser), 
+							GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK,
+							NULL);
+		g_error_free (error);
+	}
+	g_object_unref (dir);
+	
+	return gtk_file_chooser_set_current_folder_uri (chooser, uri);
+}
+
+/* Do not delete the automatically created folder */
+static void
+build_gtk_file_chooser_keep_folder (GtkFileChooser *chooser, const char *uri)
+{
+	BuildMissingDirectory* dir;
+
+	dir = g_object_steal_qdata (G_OBJECT (chooser), GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK);	
+	if (dir != NULL)
+	{
+		GFile *created_dir;
+		GFile *needed_dir;
+	
+		needed_dir = g_file_new_for_uri (uri);
+		created_dir = g_file_new_for_uri (dir->uri);
+		if (!g_file_equal (created_dir, needed_dir))
+		{
+			/* Need to delete created directory */
+			on_build_missing_directory_destroyed (dir);
+		}
+		else
+		{
+			g_free (dir);
+		}
+		g_object_unref (created_dir);
+		g_object_unref (needed_dir);
+	}
+}
+
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_select_configuration (GtkComboBox *widget, gpointer user_data)
 {
-	GtkCellRenderer* renderer_label = gtk_cell_renderer_text_new ();
-	GtkCellRenderer* renderer_options = gtk_cell_renderer_text_new ();
+	BuildConfigureDialog *dlg = (BuildConfigureDialog *)user_data;
+	gchar *name;
+	GtkTreeIter iter;
+
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dlg->combo), &iter))
+	{
+		gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dlg->combo)), &iter, 1, &name, -1);			
+	}
+	else
+	{
+		name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg->combo));
+	}
+	
+	if (*name == '\0')
+	{
+		/* Configuration name is mandatory disable Ok button */
+		gtk_widget_set_sensitive (dlg->ok, FALSE);
+	}
+	else
+	{
+		BuildConfiguration *cfg;
+		GString* args_str;
+		gchar **arg;
+		gchar *uri;
+		
+		gtk_widget_set_sensitive (dlg->ok, TRUE);
 	
-	GtkListStore* store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
-	gint i;
+		cfg = build_configuration_list_select (dlg->config_list, name);
 		
-	for (i = 0; i < G_N_ELEMENTS(gcc); i++)
+		args_str = g_string_new (NULL);
+		arg = build_configuration_get_args (cfg);
+		if (arg)
+		{
+			for (; *arg != NULL; arg++)
+			{
+				gchar *quoted_arg = g_shell_quote (*arg);
+						
+				g_string_append (args_str, quoted_arg);
+				g_free (quoted_arg);
+				g_string_append_c (args_str, ' ');
+			}
+		}
+		gtk_entry_set_text (GTK_ENTRY (dlg->args), args_str->str);
+		g_string_free (args_str, TRUE);
+		
+		uri = build_configuration_list_get_build_uri (dlg->config_list, cfg);
+		build_gtk_file_chooser_create_and_set_current_folder_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), uri);
+		g_free (uri);
+	}
+	g_free (name);
+}
+
+static void 
+fill_dialog (BuildConfigureDialog *dlg)
+{
+	GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+	BuildConfiguration *cfg;
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX(dlg->combo), GTK_TREE_MODEL(store));
+	gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (dlg->combo), 0);
+	
+	for (cfg = build_configuration_list_get_first (dlg->config_list); cfg != NULL; cfg = build_configuration_next (cfg))
 	{
 		GtkTreeIter iter;
+		
 		gtk_list_store_append (store, &iter);
-		gtk_list_store_set (store, &iter, 
-												COLUMN_LABEL, gcc[i].label,
-												COLUMN_OPTIONS, gcc[i].options, -1);
-	}
-	gtk_combo_box_set_model (GTK_COMBO_BOX(combo), GTK_TREE_MODEL(store));
-	gtk_combo_box_entry_set_text_column (combo, 1);
-
-	gtk_cell_layout_clear (GTK_CELL_LAYOUT(combo));
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), renderer_label, TRUE);
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), renderer_options, FALSE);
-	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combo), renderer_label,
-																 "text", COLUMN_LABEL);
-	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combo), renderer_options,
-																 "text", COLUMN_OPTIONS);
-	g_object_set (renderer_label,
-								"style", PANGO_STYLE_ITALIC, NULL);
+		gtk_list_store_set (store, &iter, 0, build_configuration_get_translated_name (cfg), 1, build_configuration_get_name (cfg), -1);
+	}
+	gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->combo),
+							  build_configuration_list_get_position (dlg->config_list,
+																	 build_configuration_list_get_selected (dlg->config_list)));
 }
 
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
 gboolean
-build_dialog_configure (GtkWindow* parent, const gchar* dialog_title,
-												GHashTable** build_options,
-												const gchar* default_args, gchar** args)
-{
-	GladeXML* gxml = glade_xml_new (GLADE_FILE, "configure_dialog", NULL);
-	GtkDialog* dialog = GTK_DIALOG (glade_xml_get_widget (gxml, "configure_dialog"));
-	GtkComboBoxEntry* combo
-		= GTK_COMBO_BOX_ENTRY (glade_xml_get_widget(gxml, "build_options_combo"));
-	GtkEntry* entry_args = GTK_ENTRY (glade_xml_get_widget (gxml, "configure_args_entry"));
-	
-	gtk_window_set_title (GTK_WINDOW(dialog), dialog_title);
-	
-	if (default_args)
-		gtk_entry_set_text (entry_args, default_args);
-	fill_options_combo(combo);
-	
-	int response = gtk_dialog_run (dialog);
-	if (response != GTK_RESPONSE_OK)
-	{
-		*build_options = NULL;
-		*args = NULL;
-		gtk_widget_destroy (GTK_WIDGET(dialog));
-		return FALSE;
-	}
-	else
+build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, BuildConfigurationList *config_list, gboolean *run_autogen)
+{
+	GladeXML* gxml;
+	BuildConfigureDialog dlg;
+	BuildConfiguration *cfg = NULL;
+	gint response;
+	
+	/* Get all dialog widgets */
+	gxml = glade_xml_new (GLADE_FILE, CONFIGURE_DIALOG, NULL);
+	dlg.win = glade_xml_get_widget (gxml, CONFIGURE_DIALOG);
+	dlg.combo = glade_xml_get_widget(gxml, CONFIGURATION_COMBO);
+	dlg.autogen = glade_xml_get_widget(gxml, RUN_AUTOGEN_CHECK);
+	dlg.build_dir_chooser = glade_xml_get_widget(gxml, BUILD_DIR_CHOOSER);
+	dlg.args = glade_xml_get_widget(gxml, CONFIGURE_ARGS_ENTRY);
+	dlg.ok = glade_xml_get_widget(gxml, OK_BUTTON);
+	g_object_unref (gxml);
+	
+	dlg.config_list = config_list;
+	dlg.project_uri = project_root_uri;
+
+	/* Set run autogen option */	
+	if (*run_autogen) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg.autogen), TRUE);
+
+	g_signal_connect (dlg.combo, "changed", G_CALLBACK (on_select_configuration), &dlg);
+	
+	fill_dialog(&dlg);
+	
+	response = gtk_dialog_run (GTK_DIALOG (dlg.win));
+	
+	if (response == GTK_RESPONSE_OK)
 	{
-		GtkEntry* build_options_entry = GTK_ENTRY(gtk_bin_get_child (GTK_BIN(combo)));
-		const gchar* options = gtk_entry_get_text (build_options_entry);
-		*args = g_strdup (gtk_entry_get_text (entry_args));
-		*build_options = g_hash_table_new_full (g_str_hash, g_str_equal,
-																						NULL, g_free);
-		if (strlen(options))
-		{
-			/* set options for all languages */
-			g_hash_table_insert (*build_options,
-								 "CFLAGS", g_strdup(options));
-			g_hash_table_insert (*build_options,
-								 "CXXFLAGS", g_strdup(options));
-			g_hash_table_insert (*build_options,
-								 "JFLAGS", g_strdup(options));
-			g_hash_table_insert (*build_options,
-								 "FFLAGS", g_strdup(options));
+		gchar *name;
+		gchar *uri;
+		const gchar *args;
+		GtkTreeIter iter;
+
+		*run_autogen = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg.autogen));
+		
+		if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dlg.combo), &iter))
+		{
+			gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dlg.combo)), &iter, 1, &name, -1);			
+		}
+		else
+		{
+			name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg.combo));
 		}
-		gtk_widget_destroy (GTK_WIDGET(dialog));
-		return TRUE;
+		cfg = build_configuration_list_select (config_list, name);
+		g_free (name);
+		
+		args = gtk_entry_get_text (GTK_ENTRY (dlg.args));
+		build_configuration_set_args (cfg, args);
+		
+		uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg.build_dir_chooser));
+		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);
 	}
+	gtk_widget_destroy (GTK_WIDGET(dlg.win));
+
+	return cfg != NULL;
 }
+

Modified: trunk/plugins/build-basic-autotools/build-options.h
==============================================================================
--- trunk/plugins/build-basic-autotools/build-options.h	(original)
+++ trunk/plugins/build-basic-autotools/build-options.h	Thu Jul 17 21:09:41 2008
@@ -1,35 +1,33 @@
-/***************************************************************************
- *            build-options.h
- *
- *  Sat Mar  1 20:47:23 2008
- *  Copyright  2008  Johannes Schmid
- *  <jhs gnome org>
- ****************************************************************************/
-
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * 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 Library 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
- */
+    build-options.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
  
 #ifndef BUILD_OPTIONS_H
 #define BUILD_OPTIONS_H
 
 #include <gtk/gtk.h>
 
-gboolean build_dialog_configure (GtkWindow* parent, const gchar* dialog_title,
-																 GHashTable** build_options,
-																 const gchar* default_args, gchar** args);
+#include "configuration-list.h"
 
+gboolean build_dialog_configure (GtkWindow* parent,
+								 const gchar *project_root_uri,
+								 BuildConfigurationList *configs,
+								 gboolean *run_autogen);
 
 #endif /* BUILD_OPTIONS_H */

Added: trunk/plugins/build-basic-autotools/configuration-list.c
==============================================================================
--- (empty file)
+++ trunk/plugins/build-basic-autotools/configuration-list.c	Thu Jul 17 21:09:41 2008
@@ -0,0 +1,666 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    configuration-list.c
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "configuration-list.h"
+
+#include <libanjuta/anjuta-debug.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <string.h>
+
+/* Constants
+ *---------------------------------------------------------------------------*/
+
+/* Type defintions
+ *---------------------------------------------------------------------------*/
+
+struct  _BuildConfiguration
+{
+	gchar *name;
+	gchar *build_uri;
+	gchar **args;
+	gboolean translate;
+	BuildConfiguration *next;
+	BuildConfiguration *prev;
+};
+
+struct _BuildConfigurationList
+{
+	BuildConfiguration *cfg;
+	gchar *project_root_uri;
+	BuildConfiguration *selected;
+};
+
+typedef struct _DefaultBuildConfiguration DefaultBuildConfiguration;
+
+struct  _DefaultBuildConfiguration
+{
+	gchar *name;
+	gchar *build_uri;
+	gchar *args;
+};
+
+const DefaultBuildConfiguration default_config[] = {
+	{N_("Default"), NULL, NULL},
+	{N_("Debug"), "Debug", "'CFLAGS=-g -O0' 'CXXFLAGS=-g -O0' 'JFLAGS=-g -O0' 'FFLAGS=-g -O0'"},
+	{N_("Profiling"), "Profiling", "'CFLAGS=-g -pg' 'CXXFLAGS=-g -pg' 'JFLAGS=-g -pg' 'FFLAGS=-g -pg'"},
+	{N_("Optimized"), "Optimized", "'CFLAGS=-O2' 'CXXFLAGS=-O2' 'JFLAGS=-O2' 'FFLAGS=-O2'"},
+	{NULL, NULL, NULL}
+};
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static gchar*
+build_escape_string (const char *unescaped)
+{
+ 	static const gchar hex[16] = "0123456789ABCDEF";
+	GString *esc;
+	
+ 	g_return_val_if_fail (unescaped != NULL, NULL);
+
+	esc = g_string_sized_new (strlen (unescaped) + 16);	
+  
+	for (; *unescaped != '\0'; unescaped++)
+	{
+		guchar c = *unescaped;
+		
+		if (g_ascii_isalnum (c) || (c == '_') || (c == '-') || (c == '.'))
+		{
+			g_string_append_c (esc, c);
+		}
+		else
+		{
+			g_string_append_c (esc, '%');
+			g_string_append_c (esc, hex[c >> 4]);
+	  		g_string_append_c (esc, hex[c & 0xf]);
+		}
+	}
+	
+	return g_string_free (esc, FALSE);
+}
+
+static gchar *
+build_unescape_string (const gchar *escaped)
+{
+	gchar *unesc;
+	gchar *end;
+  
+ 	if (escaped == NULL)
+		return NULL;
+  
+	unesc = g_new (gchar, strlen (escaped) + 1);
+	end = unesc;
+
+	for (; *escaped != '\0'; escaped++)
+	{
+
+		if (*escaped == '%')
+		{
+			*end++ = (g_ascii_xdigit_value (escaped[1]) << 4) | g_ascii_xdigit_value (escaped[0]);
+			escaped += 2;
+		}
+		else
+		{
+			*end++ = *escaped;
+		}
+	}
+	*end = '\0';
+	
+	return unesc;
+}
+
+#if 0
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_select_configuration (GtkComboBox *widget, gpointer user_data)
+{
+	BuildConfigureDialog *dlg = (BuildConfigureDialog *)user_data;
+	gchar *name;
+	
+	name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg->combo));
+	
+	if (*name == '\0')
+	{
+		/* Configuration name is mandatory disable Ok button */
+		gtk_widget_set_sensitive (dlg->ok, FALSE);
+	}
+	else
+	{
+		GList *node;
+		
+		gtk_widget_set_sensitive (dlg->ok, TRUE);
+		
+		for (node = dlg->config_list; node != NULL; node = g_list_next (node))
+		{
+			BuildConfiguration *cfg = (BuildConfiguration *)node->data;
+		
+			if (strcmp (name, cfg->name) == 0)
+			{
+				/* Find existing configuration */
+				if (cfg->args == NULL)
+				{
+					gtk_entry_set_text (GTK_ENTRY (dlg->args), "");
+				}
+				else
+				{
+					GString* args_str;
+					gchar **arg;
+				
+					args_str = g_string_new (NULL);
+					for (arg = cfg->args; *arg != NULL; arg++)
+					{
+						gchar *quoted_arg = g_shell_quote (*arg);
+						
+						g_string_append (args_str, quoted_arg);
+						g_free (quoted_arg);
+						g_string_append_c (args_str, ' ');
+					}
+					gtk_entry_set_text (GTK_ENTRY (dlg->args), args_str->str);
+					g_string_free (args_str, TRUE);
+				}
+
+				if (cfg->build_uri == NULL)
+				{
+					/* No build directory defined, use source directory */
+					gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), dlg->project_uri);
+				}
+				else
+				{
+					gchar *scheme;
+					
+					scheme = g_uri_parse_scheme (cfg->build_uri);
+					if (scheme)
+					{
+						/* Absolute directory */
+						g_free (scheme);
+						build_gtk_file_chooser_create_and_set_current_folder_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), cfg->build_uri);
+					}
+					else
+					{
+						GFile *dir;
+						GFile *build_dir;
+						gchar *build_uri;
+						
+						/* Relative directory */
+						dir = g_file_new_for_uri (dlg->project_uri);
+						build_dir = g_file_resolve_relative_path (dir,cfg->build_uri);
+						g_object_unref (dir);
+						build_uri = g_file_get_uri (build_dir);
+						g_object_unref (build_dir);
+						build_gtk_file_chooser_create_and_set_current_folder_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), build_uri);
+						g_free (build_uri);										
+					}
+					
+				}
+			}
+		}
+	}
+	g_free (name);
+}
+
+static void 
+fill_dialog (BuildConfigureDialog *dlg)
+{
+	GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING);
+	GList *node;
+	const DefaultBuildConfiguration *cfg;
+
+	/* Add default entry if missing */
+	for (cfg = default_config; cfg->name != NULL; cfg++)
+	{
+		for (node = g_list_first (dlg->config_list); node != NULL; node = g_list_next (node))
+		{
+			if (strcmp (((BuildConfiguration *)node->data)->name, cfg->name) == 0) break;
+		}
+		if (node == NULL)
+		{
+			/* Add configuration */
+			BuildConfiguration *new_cfg;
+			
+			new_cfg = g_new (BuildConfiguration, 1);
+			new_cfg->name = g_strdup (cfg->name);
+			new_cfg->build_uri = g_strdup (cfg->build_uri);
+			new_cfg->args = NULL;
+			if (cfg->args)
+			{
+				g_shell_parse_argv (cfg->args, NULL, &new_cfg->args, NULL);
+			}
+				
+			dlg->config_list = g_list_append (dlg->config_list, new_cfg);
+		}
+	}
+	
+	gtk_combo_box_set_model (GTK_COMBO_BOX(dlg->combo), GTK_TREE_MODEL(store));
+	gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (dlg->combo), 0);
+	
+	for (node = g_list_first (dlg->config_list); node != NULL; node = g_list_next (node))
+	{
+		GtkTreeIter iter;
+		
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter, 0, ((BuildConfiguration *)node->data)->name, -1);
+	}
+}
+
+static void
+save_configuration (BuildConfigureDialog *dlg)
+{
+	gchar *configuration;
+	GList *node;
+	BuildConfiguration *cfg;
+	gchar *uri;
+	
+	configuration = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg->combo));
+	
+	for (node = dlg->config_list; node != NULL; node = g_list_next (node))
+	{
+		cfg = (BuildConfiguration *)node->data;
+		
+		if (strcmp (configuration, cfg->name) == 0)
+		{
+			/* Move this configuration at the beginning */
+			dlg->config_list = g_list_remove_link (dlg->config_list, node);
+			dlg->config_list = g_list_concat (node, dlg->config_list);
+			g_free (configuration);
+			break;
+		}
+	}
+	if (node == NULL)
+	{
+		/* Create a new configuration */
+		dlg->config_list = g_list_prepend (dlg->config_list, g_new0 (BuildConfiguration, 1));
+		node = dlg->config_list;
+		cfg = (BuildConfiguration *)node->data;
+		cfg->name = configuration;
+	}
+	
+	g_strfreev (cfg->args);
+	cfg->args = NULL;
+	g_free (cfg->build_uri);
+	
+	g_shell_parse_argv (gtk_entry_get_text (GTK_ENTRY (dlg->args)), NULL, &cfg->args, NULL);
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser));
+	cfg->build_uri = uri;
+}
+
+BuildConfiguration*
+build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, GList **config_list, gboolean *run_autogen)
+{
+	GladeXML* gxml;
+	BuildConfigureDialog dlg;
+	BuildConfiguration *cfg;
+
+	gint response;
+	
+	/* Get all dialog widgets */
+	gxml = glade_xml_new (GLADE_FILE, CONFIGURE_DIALOG, NULL);
+	dlg.win = glade_xml_get_widget (gxml, CONFIGURE_DIALOG);
+	dlg.combo = glade_xml_get_widget(gxml, CONFIGURATION_COMBO);
+	dlg.autogen = glade_xml_get_widget(gxml, RUN_AUTOGEN_CHECK);
+	dlg.build_dir_chooser = glade_xml_get_widget(gxml, BUILD_DIR_CHOOSER);
+	dlg.args = glade_xml_get_widget(gxml, CONFIGURE_ARGS_ENTRY);
+	dlg.ok = glade_xml_get_widget(gxml, OK_BUTTON);
+	g_object_unref (gxml);
+	
+	dlg.config_list = *config_list;
+	dlg.project_uri = project_root_uri;
+
+	/* Set run autogen option */	
+	if (*run_autogen) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg.autogen), TRUE);
+
+	g_signal_connect (dlg.combo, "changed", G_CALLBACK (on_select_configuration), &dlg);
+	
+	fill_dialog(&dlg);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (dlg.combo), 0);	
+	
+	response = gtk_dialog_run (GTK_DIALOG (dlg.win));
+	
+	if (response == GTK_RESPONSE_OK)
+	{
+		save_configuration (&dlg);	
+		*config_list = dlg.config_list;
+		*run_autogen = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg.autogen));
+
+		cfg = build_configuration_copy ((BuildConfiguration *)dlg.config_list->data);
+		build_gtk_file_chooser_keep_folder (GTK_FILE_CHOOSER (dlg.build_dir_chooser), cfg->build_uri);		
+	}
+	else
+	{
+		cfg = NULL;
+	}
+	gtk_widget_destroy (GTK_WIDGET(dlg.win));
+
+	return cfg;
+}
+
+#endif
+
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static void
+build_configuration_list_free_list (BuildConfigurationList *list)
+{
+	BuildConfiguration *cfg;
+	
+	for (cfg = list->cfg; cfg != NULL;)
+	{
+		BuildConfiguration *next = cfg->next;
+		
+		if (cfg->args) g_strfreev (cfg->args);
+		if (cfg->build_uri) g_free (cfg->build_uri);
+		if (cfg->name) g_free (cfg->name);
+		g_free (cfg);
+		cfg = next;
+	}
+	list->cfg = NULL;	
+}
+
+static BuildConfiguration *
+build_configuration_list_untranslated_get (BuildConfigurationList *list, const gchar *name)
+{
+	BuildConfiguration *cfg;
+		
+	for (cfg = build_configuration_list_get_first (list); cfg != NULL; cfg = build_configuration_next (cfg))
+	{
+		if (strcmp (cfg->name, name) == 0) return cfg;
+	}
+	
+	return NULL;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+BuildConfiguration *
+build_configuration_list_get_first (BuildConfigurationList *list)
+{
+	return list->cfg;
+}
+
+BuildConfiguration *
+build_configuration_next (BuildConfiguration *cfg)
+{
+	return cfg->next;
+}
+
+BuildConfiguration *
+build_configuration_list_get (BuildConfigurationList *list, const gchar *name)
+{
+	BuildConfiguration *cfg;
+		
+	for (cfg = build_configuration_list_get_first (list); cfg != NULL; cfg = build_configuration_next (cfg))
+	{
+		if (strcmp (cfg->name, name) == 0) return cfg;
+	}
+	
+	return NULL;
+}
+
+BuildConfiguration *
+build_configuration_list_get_selected (BuildConfigurationList *list)
+{
+	return list->selected == NULL ? list->cfg : list->selected;
+}
+
+gint
+build_configuration_list_get_position (BuildConfigurationList *list, BuildConfiguration *cfg)
+{
+	BuildConfiguration *node;
+	gint position = 0;
+	
+	for (node = build_configuration_list_get_first (list); node != NULL; node = node->next)
+	{
+		if (node == cfg) return position;
+		position++;
+	}
+	
+	return -1;
+}
+
+BuildConfiguration *
+build_configuration_list_select (BuildConfigurationList *list, const gchar *name)
+{
+	BuildConfiguration *cfg = NULL;
+
+	if (name != NULL) cfg = build_configuration_list_get (list, name);
+	list->selected = cfg;
+	
+	return list->selected;
+}
+
+void 
+build_configuration_list_from_string_list (BuildConfigurationList *list, GList *str_list)
+{
+	GList *node;
+	BuildConfiguration *prev = NULL;
+	const DefaultBuildConfiguration *dcfg;
+	
+	build_configuration_list_free_list (list);
+	
+	/* Read all configurations from list */
+	for (node = str_list; node != NULL; node = g_list_next(node))
+	{
+		BuildConfiguration *cfg = g_new0 (BuildConfiguration, 1);
+		gchar *str = (gchar *)node->data;
+		gchar *end;
+		
+		cfg->translate = *str == '1';
+		str += 2;
+		end = strchr (str, ':');
+		if (end != NULL)
+		{
+			gchar *name;
+			
+			*end = '\0';
+			name = build_unescape_string (str);
+			cfg->name = name;
+			str = end + 1;
+			
+			cfg->build_uri = *str == '\0' ? NULL : g_strdup (str);
+			
+			cfg->args = NULL;
+			
+			cfg->next = NULL;
+			cfg->prev = prev;
+			if (prev == NULL)
+			{
+				list->cfg = cfg;
+			}
+			else
+			{
+				prev->next = cfg;
+			}
+			prev = cfg;
+		}
+		else
+		{
+			g_free (cfg);
+		}
+	}
+	
+	/* Add default entry if missing */
+	for (dcfg = default_config; dcfg->name != NULL; dcfg++)
+	{
+		BuildConfiguration *cfg;
+		
+		cfg = build_configuration_list_untranslated_get (list, dcfg->name);
+		if (cfg == NULL)
+		{
+			/* Add configuration */
+			cfg = g_new (BuildConfiguration, 1);
+			cfg->translate = 1;
+			cfg->name = g_strdup (dcfg->name);
+			cfg->build_uri = g_strdup (dcfg->build_uri);
+			cfg->args = NULL;
+			cfg->next = NULL;
+			cfg->prev = prev;
+			if (prev == NULL)
+			{
+				list->cfg = cfg;
+			}
+			else
+			{
+				prev->next = cfg;
+			}
+			prev = cfg;
+		}
+		if ((cfg->args == NULL) && (dcfg->args))
+		{
+				g_shell_parse_argv (dcfg->args, NULL, &cfg->args, NULL);
+		}
+	}	
+}
+
+GList * 
+build_configuration_list_to_string_list (BuildConfigurationList *list)
+{
+	GList *str_list = NULL;
+	BuildConfiguration *cfg;
+	
+	for (cfg = build_configuration_list_get_first (list); cfg != NULL; cfg = build_configuration_next (cfg))
+	{
+		gchar *esc_name = build_escape_string (cfg->name);
+		str_list = g_list_prepend (str_list, g_strdup_printf("%c:%s:%s", cfg->translate ? '1' : '0', esc_name, cfg->build_uri == NULL ? "" : cfg->build_uri));
+		g_free (esc_name);							   
+	}
+	str_list = g_list_reverse (str_list);
+
+	return str_list;
+}
+
+/* Get and Set functions
+ *---------------------------------------------------------------------------*/
+
+void
+build_configuration_list_set_project_uri (BuildConfigurationList *list, const gchar *uri)
+{
+	g_free (list->project_root_uri);
+	list->project_root_uri = g_strdup (uri);
+}
+
+const gchar *
+build_configuration_get_translated_name (BuildConfiguration *cfg)
+{
+	return cfg->translate ? _(cfg->name) : cfg->name;
+}
+
+const gchar *
+build_configuration_get_name (BuildConfiguration *cfg)
+{
+	return cfg->name;
+}
+
+gboolean 
+build_configuration_list_set_build_uri (BuildConfigurationList *list, BuildConfiguration *cfg, const gchar *build_uri)
+{
+	GFile *root;
+	GFile *build;
+	gchar *rel_uri;
+	
+	root = g_file_new_for_uri (list->project_root_uri);
+	build = g_file_new_for_uri (build_uri);
+	
+	rel_uri = g_file_get_relative_path (root, build);
+	if (rel_uri)
+	{
+		g_free (cfg->build_uri);
+		cfg->build_uri = rel_uri;
+	}
+	g_object_unref (root);
+	g_object_unref (build);
+	
+	return rel_uri != NULL;
+}
+
+gchar *
+build_configuration_list_get_build_uri (BuildConfigurationList *list, BuildConfiguration *cfg)
+{
+	if (cfg->build_uri != NULL)
+	{
+		GFile *root;
+		GFile *build;
+		gchar *uri;
+	
+		root = g_file_new_for_uri (list->project_root_uri);
+		build = g_file_resolve_relative_path (root, cfg->build_uri);
+	
+		uri = g_file_get_uri (build);
+	
+		g_object_unref (root);
+		g_object_unref (build);
+		
+		return uri;
+	}
+	else
+	{
+		return g_strdup (list->project_root_uri);
+	}
+}
+
+const gchar *
+build_configuration_get_relative_build_uri (BuildConfiguration *cfg)
+{
+	return cfg->build_uri;
+}
+
+void
+build_configuration_set_args (BuildConfiguration *cfg, const gchar *args)
+{
+	if (cfg->args) g_strfreev (cfg->args);
+	if (args != NULL)
+	{
+		g_shell_parse_argv (args, NULL, &cfg->args, NULL);
+	}
+}
+
+gchar **
+build_configuration_get_args (BuildConfiguration *cfg)
+{
+	return cfg->args;
+}
+
+/* Constructor & Destructor
+ *---------------------------------------------------------------------------*/
+
+void
+build_configuration_list_free (BuildConfigurationList *list)
+{
+	g_free (list->project_root_uri);
+
+	build_configuration_list_free_list (list);
+	
+	g_free (list);
+}
+
+BuildConfigurationList*
+build_configuration_list_new (void)
+{
+	BuildConfigurationList *list;
+	
+	list = g_new0 (BuildConfigurationList, 1);
+	
+	return list;
+}

Added: trunk/plugins/build-basic-autotools/configuration-list.h
==============================================================================
--- (empty file)
+++ trunk/plugins/build-basic-autotools/configuration-list.h	Thu Jul 17 21:09:41 2008
@@ -0,0 +1,51 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    configuration-list.h
+    Copyright (C) 2008 SÃbastien Granjoux
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+ 
+#ifndef CONFIGURATION_LIST_H
+#define CONFIGURATION_LIST_H
+
+#include <glib.h>
+
+typedef struct _BuildConfiguration BuildConfiguration;
+typedef struct _BuildConfigurationList BuildConfigurationList;
+
+BuildConfigurationList* build_configuration_list_new (void);
+void build_configuration_list_free (BuildConfigurationList *list);
+
+void build_configuration_list_from_string_list (BuildConfigurationList *list, GList *str_list);
+GList *build_configuration_list_to_string_list (BuildConfigurationList *list);
+
+BuildConfiguration *build_configuration_list_get_first (BuildConfigurationList *list);
+BuildConfiguration *build_configuration_list_get_selected (BuildConfigurationList *list);
+gint build_configuration_list_get_position (BuildConfigurationList *list, BuildConfiguration *cfg);
+BuildConfiguration *build_configuration_next (BuildConfiguration *cfg);
+BuildConfiguration *build_configuration_list_get (BuildConfigurationList *list, const gchar *name);
+BuildConfiguration *build_configuration_list_select (BuildConfigurationList *list, const gchar *name);
+
+void build_configuration_list_set_project_uri (BuildConfigurationList *list, const gchar *uri);
+const gchar *build_configuration_get_translated_name (BuildConfiguration *cfg);
+const gchar *build_configuration_get_name (BuildConfiguration *cfg);
+gboolean build_configuration_list_set_build_uri (BuildConfigurationList *list, BuildConfiguration *cfg, const gchar *build_uri);
+gchar *build_configuration_list_get_build_uri (BuildConfigurationList *list, BuildConfiguration *cfg);
+const gchar *build_configuration_get_relative_build_uri (BuildConfiguration *cfg);
+void build_configuration_set_args (BuildConfiguration *cfg, const gchar *args);
+gchar **build_configuration_get_args (BuildConfiguration *cfg);
+
+#endif /* CONFIGURATION_LIST_H */

Modified: trunk/plugins/debug-manager/start.c
==============================================================================
--- trunk/plugins/debug-manager/start.c	(original)
+++ trunk/plugins/debug-manager/start.c	Thu Jul 17 21:09:41 2008
@@ -884,7 +884,7 @@
 }
 
 static void
-on_build_finished (GObject *builder, GError *err, gpointer user_data)
+on_build_finished (GObject *builder, IAnjutaBuilderHandle handle, GError *err, gpointer user_data)
 {
 	DmaStart *this = (DmaStart *)user_data;
 	
@@ -899,7 +899,7 @@
 }
 
 static void
-on_is_built_finished (GObject *builder, GError *err, gpointer user_data)
+on_is_built_finished (GObject *builder, IAnjutaBuilderHandle handle, GError *err, gpointer user_data)
 {
 	DmaStart *this = (DmaStart *)user_data;
 	

Modified: trunk/plugins/project-manager/plugin.c
==============================================================================
--- trunk/plugins/project-manager/plugin.c	(original)
+++ trunk/plugins/project-manager/plugin.c	Thu Jul 17 21:09:41 2008
@@ -27,6 +27,7 @@
 #include <libanjuta/interfaces/ianjuta-project-manager.h>
 #include <libanjuta/interfaces/ianjuta-document-manager.h>
 #include <libanjuta/interfaces/ianjuta-file-manager.h>
+#include <libanjuta/interfaces/ianjuta-builder.h>
 #include <libanjuta/anjuta-profile-manager.h>
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-status.h>
@@ -1307,7 +1308,7 @@
 	
 	update_title (plugin, plugin->project_root_uri);
 	anjuta_shell_add_value (ANJUTA_PLUGIN(plugin)->shell,
-							"project_root_uri",
+							IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
 							value, NULL);
 	
 	/* If profile scoped to "project", restore project session */
@@ -1353,7 +1354,7 @@
 	
 	update_title (ANJUTA_PLUGIN_PROJECT_MANAGER (plugin), NULL);
 	anjuta_shell_remove_value (ANJUTA_PLUGIN (plugin)->shell,
-							   "project_root_uri", NULL);
+						  IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, NULL);
 }
 
 static void
@@ -1615,7 +1616,7 @@
 }
 
 static gchar *
-get_element_uri_from_id (ProjectManagerPlugin *plugin, const gchar *id)
+get_element_uri_from_id (ProjectManagerPlugin *plugin, const gchar *id, const gchar *root)
 {
 	gchar *path, *ptr;
 	gchar *uri;
@@ -1638,7 +1639,7 @@
 	}
 	
 	anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
-					  "project_root_uri", G_TYPE_STRING,
+					  root, G_TYPE_STRING,
 					  &project_root, NULL);
 	uri = g_build_filename (project_root, path, NULL);
 	/* DEBUG_PRINT ("Converting id: %s to %s", id, uri); */
@@ -1647,12 +1648,12 @@
 }
 
 static const gchar *
-get_element_relative_path (ProjectManagerPlugin *plugin, const gchar *uri)
+get_element_relative_path (ProjectManagerPlugin *plugin, const gchar *uri, const gchar *root)
 {
 	const gchar *project_root = NULL;
 	
 	anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
-					  "project_root_uri", G_TYPE_STRING,
+					  root, G_TYPE_STRING,
 					  &project_root, NULL);
 	if (project_root)
 	{
@@ -1680,7 +1681,7 @@
 	const gchar *rel_path;
 	gchar *test_id;
 	
-	rel_path = get_element_relative_path (plugin, uri);
+	rel_path = get_element_relative_path (plugin, uri, IANJUTA_BUILDER_ROOT_URI);
 	
 	if (!rel_path)
 		return NULL;
@@ -1728,11 +1729,11 @@
 	}
 	else if (get_uri_vfs_type (uri) | GNOME_VFS_FILE_TYPE_DIRECTORY)
 	{
-		id = g_strconcat (get_element_relative_path (plugin, uri), "/", NULL);
+		id = g_strconcat (get_element_relative_path (plugin, uri, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI), "/", NULL);
 	}
 	else
 	{
-		id = strdup (get_element_relative_path (plugin, uri));
+		id = strdup (get_element_relative_path (plugin, uri, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
 	}
 	return id;
 }
@@ -1818,7 +1819,8 @@
 			{
 				elements = g_list_prepend (elements,
 										   get_element_uri_from_id (plugin,
-												(const gchar *)node->data));
+												(const gchar *)node->data,
+												IANJUTA_BUILDER_ROOT_URI));
 				g_free (node->data);
 				node = node->next;
 			}
@@ -1834,7 +1836,8 @@
 			{
 				elements = g_list_prepend (elements,
 										   get_element_uri_from_id (plugin,
-												(const gchar *)node->data));
+												(const gchar *)node->data,
+										        IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
 				g_free (node->data);
 				node = node->next;
 			}
@@ -1947,7 +1950,8 @@
 				if (strcmp (t_type, type_node->data) == 0)
 				{
 					gchar *target_uri = get_element_uri_from_id (plugin,
-																 target_id);
+																 target_id,
+																 IANJUTA_BUILDER_ROOT_URI);
 					elements = g_list_prepend (elements, target_uri);
 				}
 			}
@@ -2022,7 +2026,7 @@
 										   GBF_TREE_NODE_TARGET);
 	if (data && data->type == GBF_TREE_NODE_TARGET)
 	{
-		uri = get_element_uri_from_id (plugin, data->id);
+		uri = get_element_uri_from_id (plugin, data->id, IANJUTA_BUILDER_ROOT_URI);
 		gbf_tree_data_free (data);
 		return uri;
 	}
@@ -2103,7 +2107,7 @@
 	}
 	update_operation_end (plugin, TRUE);
 	
-	source_uri = get_element_uri_from_id(plugin, source_id);
+	source_uri = get_element_uri_from_id(plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
 	g_free(source_id);
 	
 	return source_uri;
@@ -2160,7 +2164,8 @@
 	{
 		source_uris = g_list_append (source_uris,
 									 get_element_uri_from_id (plugin,
-														  source_ids->data));
+														  source_ids->data,
+														  IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
 		g_free (source_ids->data);
 		source_ids = g_list_next(source_ids);
 	}
@@ -2191,7 +2196,7 @@
 											 default_group_id,
 											 target_name_to_add);
 	update_operation_end (plugin, TRUE);
-	target_uri = get_element_uri_from_id (plugin, target_id);
+	target_uri = get_element_uri_from_id (plugin, target_id, IANJUTA_BUILDER_ROOT_URI);
 	g_free (target_id);
 	g_free (default_group_id);
 	return target_uri;
@@ -2220,7 +2225,7 @@
 										   default_group_id,
 										   group_name_to_add);
 	update_operation_end (plugin, TRUE);
-	group_uri = get_element_uri_from_id (plugin, group_id);
+	group_uri = get_element_uri_from_id (plugin, group_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
 	g_free (group_id);
 	g_free (default_group_id);
 	return group_uri;

Modified: trunk/plugins/project-wizard/autogen.c
==============================================================================
--- trunk/plugins/project-wizard/autogen.c	(original)
+++ trunk/plugins/project-wizard/autogen.c	Thu Jul 17 21:09:41 2008
@@ -352,7 +352,7 @@
 	}
 	
 	this->busy = TRUE;
-	if (!anjuta_launcher_execute_v (this->launcher, args, on_autogen_output, this))
+	if (!anjuta_launcher_execute_v (this->launcher, args, NULL, on_autogen_output, this))
 	{
 		return FALSE;
 	}

Modified: trunk/plugins/run-program/execute.c
==============================================================================
--- trunk/plugins/run-program/execute.c	(original)
+++ trunk/plugins/run-program/execute.c	Thu Jul 17 21:09:41 2008
@@ -401,7 +401,7 @@
 }
 
 static void
-on_build_finished (GObject *builder, GError *err, gpointer user_data)
+on_build_finished (GObject *builder, IAnjutaBuilderHandle handle, GError *err, gpointer user_data)
 {
 	RunProgramPlugin *plugin = (RunProgramPlugin *)user_data;
 	
@@ -418,7 +418,7 @@
 }
 
 static void
-on_is_built_finished (GObject *builder, GError *err, gpointer user_data)
+on_is_built_finished (GObject *builder, IAnjutaBuilderHandle handle, GError *err, gpointer user_data)
 {
 	RunProgramPlugin *plugin = (RunProgramPlugin *)user_data;
 	



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