* plugins/build-basic-autotools/configuration-list.c,
[anjuta-git-plugin.git] / plugins / build-basic-autotools / build-options.c
blob6291e9be4903ff0ba83aa3360ef20956c21100ba
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 build-options.c
4 Copyright (C) 2008 Sébastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "build-options.h"
23 #include <glib/gi18n.h>
24 #include <gio/gio.h>
25 #include <glade/glade-xml.h>
26 #include <libanjuta/anjuta-debug.h>
27 #include <libanjuta/anjuta-shell.h>
28 #include <string.h>
30 /* Constants
31 *---------------------------------------------------------------------------*/
33 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-build-basic-autotools-plugin.glade"
35 #define CONFIGURE_DIALOG "configure_dialog"
36 #define RUN_AUTOGEN_CHECK "force_autogen_check"
37 #define CONFIGURATION_COMBO "configuration_combo_entry"
38 #define BUILD_DIR_CHOOSER "build_dir_chooser"
39 #define CONFIGURE_ARGS_ENTRY "configure_args_entry"
40 #define OK_BUTTON "ok_button"
42 #define GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK (build_gtk_file_chooser_create_directory_get_quark ())
45 /* Type defintions
46 *---------------------------------------------------------------------------*/
48 typedef struct _BuildConfigureDialog BuildConfigureDialog;
50 struct _BuildConfigureDialog
52 GtkWidget *win;
54 GtkWidget *combo;
55 GtkWidget *autogen;
56 GtkWidget *build_dir_chooser;
57 GtkWidget *args;
58 GtkWidget *ok;
60 BuildConfigurationList *config_list;
62 const gchar *project_uri;
65 typedef struct _BuildMissingDirectory BuildMissingDirectory;
67 struct _BuildMissingDirectory
69 gsize exist;
70 gchar uri[0];
74 /* Create directory at run time for GtkFileChooserButton
75 *---------------------------------------------------------------------------*/
77 /* Create a directories, including parents if necessary, return
78 * */
80 static GFile*
81 build_make_directories (GFile *file,
82 GCancellable *cancellable,
83 GError **error)
85 GError *path_error = NULL;
86 GList *children = NULL;
87 GFile *parent;
89 parent = g_file_get_parent(file);
91 for (;;)
93 if (g_file_make_directory (file, NULL, &path_error))
95 /* Making child directory succeed */
96 if (children == NULL)
98 /* All directories have been created */
99 return parent;
101 else
103 /* Get next child directory */
104 g_object_unref (file);
105 file = (GFile *)children->data;
106 children = g_list_delete_link (children, children);
109 else if (path_error->code == G_IO_ERROR_NOT_FOUND)
111 g_clear_error (&path_error);
112 children = g_list_prepend (children, file);
113 file = parent;
114 parent = g_file_get_parent(file);
116 else
118 g_object_unref (parent);
119 g_propagate_error (error, path_error);
121 return NULL;
126 static GQuark
127 build_gtk_file_chooser_create_directory_get_quark (void)
129 static GQuark quark = 0;
131 if (quark == 0)
132 quark = g_quark_from_static_string ("gtk-file-chooser-create-directory");
134 return quark;
137 /* Remove created directory */
138 static void
139 on_build_missing_directory_destroyed (BuildMissingDirectory* dir)
141 /* Remove previously created directories */
142 GFile* created_dir;
143 GFile* existing_dir;
145 created_dir = g_file_new_for_uri (dir->uri);
146 dir->uri[dir->exist] = '\0';
147 existing_dir = g_file_new_for_uri (dir->uri);
149 for (;!g_file_equal (created_dir, existing_dir);)
151 GFile *parent_dir;
153 if (!g_file_delete (created_dir, NULL, NULL)) break;
154 parent_dir = g_file_get_parent (created_dir);
155 g_object_unref (created_dir);
156 created_dir = parent_dir;
158 g_object_unref (created_dir);
159 g_object_unref (existing_dir);
160 g_free (dir);
163 /* If the folder is missing created it before setting it */
165 static gboolean
166 build_gtk_file_chooser_create_and_set_current_folder_uri (GtkFileChooser *chooser, const gchar *uri)
168 GFile *dir;
169 GError *error = NULL;
170 GFile *parent;
172 dir = g_file_new_for_uri (uri);
173 parent = build_make_directories (dir, NULL, &error);
174 if (parent != NULL)
176 BuildMissingDirectory* dir;
177 gchar *last;
178 gsize len;
180 len = strlen (uri);
181 dir = (BuildMissingDirectory *)g_new (char, sizeof (BuildMissingDirectory) + len + 1);
183 memcpy (dir->uri, uri, len + 1);
184 last = g_file_get_uri (parent);
185 dir->exist = strlen (last);
187 g_object_set_qdata_full (G_OBJECT (chooser),
188 GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK,
189 dir,
190 (GDestroyNotify)on_build_missing_directory_destroyed);
192 else
194 g_object_set_qdata (G_OBJECT (chooser),
195 GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK,
196 NULL);
197 g_error_free (error);
199 g_object_unref (dir);
201 return gtk_file_chooser_set_current_folder_uri (chooser, uri);
204 /* Do not delete the automatically created folder */
205 static void
206 build_gtk_file_chooser_keep_folder (GtkFileChooser *chooser, const char *uri)
208 BuildMissingDirectory* dir;
210 dir = g_object_steal_qdata (G_OBJECT (chooser), GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK);
211 if (dir != NULL)
213 GFile *created_dir;
214 GFile *needed_dir;
216 needed_dir = g_file_new_for_uri (uri);
217 created_dir = g_file_new_for_uri (dir->uri);
218 if (!g_file_equal (created_dir, needed_dir))
220 /* Need to delete created directory */
221 on_build_missing_directory_destroyed (dir);
223 else
225 g_free (dir);
227 g_object_unref (created_dir);
228 g_object_unref (needed_dir);
233 /* Helper functions
234 *---------------------------------------------------------------------------*/
236 static void
237 on_select_configuration (GtkComboBox *widget, gpointer user_data)
239 BuildConfigureDialog *dlg = (BuildConfigureDialog *)user_data;
240 gchar *name;
241 GtkTreeIter iter;
243 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dlg->combo), &iter))
245 gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dlg->combo)), &iter, 1, &name, -1);
247 else
249 name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg->combo));
252 if (*name == '\0')
254 /* Configuration name is mandatory disable Ok button */
255 gtk_widget_set_sensitive (dlg->ok, FALSE);
257 else
259 BuildConfiguration *cfg;
260 GString* args_str;
261 gchar **arg;
262 gchar *uri;
264 gtk_widget_set_sensitive (dlg->ok, TRUE);
266 cfg = build_configuration_list_select (dlg->config_list, name);
268 if (cfg != NULL)
270 args_str = g_string_new (NULL);
271 arg = build_configuration_get_args (cfg);
272 if (arg)
274 for (; *arg != NULL; arg++)
276 gchar *quoted_arg = g_shell_quote (*arg);
278 g_string_append (args_str, quoted_arg);
279 g_free (quoted_arg);
280 g_string_append_c (args_str, ' ');
283 gtk_entry_set_text (GTK_ENTRY (dlg->args), args_str->str);
284 g_string_free (args_str, TRUE);
286 uri = build_configuration_list_get_build_uri (dlg->config_list, cfg);
287 build_gtk_file_chooser_create_and_set_current_folder_uri (GTK_FILE_CHOOSER (dlg->build_dir_chooser), uri);
288 g_free (uri);
291 g_free (name);
294 static void
295 fill_dialog (BuildConfigureDialog *dlg)
297 GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
298 BuildConfiguration *cfg;
300 gtk_combo_box_set_model (GTK_COMBO_BOX(dlg->combo), GTK_TREE_MODEL(store));
301 gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (dlg->combo), 0);
303 for (cfg = build_configuration_list_get_first (dlg->config_list); cfg != NULL; cfg = build_configuration_next (cfg))
305 GtkTreeIter iter;
307 gtk_list_store_append (store, &iter);
308 gtk_list_store_set (store, &iter, 0, build_configuration_get_translated_name (cfg), 1, build_configuration_get_name (cfg), -1);
310 gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->combo),
311 build_configuration_list_get_position (dlg->config_list,
312 build_configuration_list_get_selected (dlg->config_list)));
315 /* Public functions
316 *---------------------------------------------------------------------------*/
318 gboolean
319 build_dialog_configure (GtkWindow* parent, const gchar *project_root_uri, BuildConfigurationList *config_list, gboolean *run_autogen)
321 GladeXML* gxml;
322 BuildConfigureDialog dlg;
323 BuildConfiguration *cfg = NULL;
324 gint response;
326 /* Get all dialog widgets */
327 gxml = glade_xml_new (GLADE_FILE, CONFIGURE_DIALOG, NULL);
328 dlg.win = glade_xml_get_widget (gxml, CONFIGURE_DIALOG);
329 dlg.combo = glade_xml_get_widget(gxml, CONFIGURATION_COMBO);
330 dlg.autogen = glade_xml_get_widget(gxml, RUN_AUTOGEN_CHECK);
331 dlg.build_dir_chooser = glade_xml_get_widget(gxml, BUILD_DIR_CHOOSER);
332 dlg.args = glade_xml_get_widget(gxml, CONFIGURE_ARGS_ENTRY);
333 dlg.ok = glade_xml_get_widget(gxml, OK_BUTTON);
334 g_object_unref (gxml);
336 dlg.config_list = config_list;
337 dlg.project_uri = project_root_uri;
339 /* Set run autogen option */
340 if (*run_autogen) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg.autogen), TRUE);
342 g_signal_connect (dlg.combo, "changed", G_CALLBACK (on_select_configuration), &dlg);
344 fill_dialog(&dlg);
346 response = gtk_dialog_run (GTK_DIALOG (dlg.win));
348 if (response == GTK_RESPONSE_OK)
350 gchar *name;
351 gchar *uri;
352 const gchar *args;
353 GtkTreeIter iter;
355 *run_autogen = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg.autogen));
357 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (dlg.combo), &iter))
359 gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (dlg.combo)), &iter, 1, &name, -1);
361 else
363 name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg.combo));
365 cfg = build_configuration_list_create (config_list, name);
366 g_free (name);
368 args = gtk_entry_get_text (GTK_ENTRY (dlg.args));
369 build_configuration_set_args (cfg, args);
371 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg.build_dir_chooser));
372 build_configuration_list_set_build_uri (dlg.config_list, cfg, uri);
373 build_gtk_file_chooser_keep_folder (GTK_FILE_CHOOSER (dlg.build_dir_chooser), uri);
374 g_free (uri);
376 gtk_widget_destroy (GTK_WIDGET(dlg.win));
378 return cfg != NULL;