1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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>
25 #include <glade/glade-xml.h>
26 #include <libanjuta/anjuta-debug.h>
27 #include <libanjuta/anjuta-shell.h>
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 ())
46 *---------------------------------------------------------------------------*/
48 typedef struct _BuildConfigureDialog BuildConfigureDialog
;
50 struct _BuildConfigureDialog
56 GtkWidget
*build_dir_chooser
;
60 BuildConfigurationList
*config_list
;
62 const gchar
*project_uri
;
65 typedef struct _BuildMissingDirectory BuildMissingDirectory
;
67 struct _BuildMissingDirectory
74 /* Create directory at run time for GtkFileChooserButton
75 *---------------------------------------------------------------------------*/
77 /* Create a directories, including parents if necessary, return
81 build_make_directories (GFile
*file
,
82 GCancellable
*cancellable
,
85 GError
*path_error
= NULL
;
86 GList
*children
= NULL
;
89 parent
= g_file_get_parent(file
);
93 if (g_file_make_directory (file
, NULL
, &path_error
))
95 /* Making child directory succeed */
98 /* All directories have been created */
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
);
114 parent
= g_file_get_parent(file
);
118 g_object_unref (parent
);
119 g_propagate_error (error
, path_error
);
127 build_gtk_file_chooser_create_directory_get_quark (void)
129 static GQuark quark
= 0;
132 quark
= g_quark_from_static_string ("gtk-file-chooser-create-directory");
137 /* Remove created directory */
139 on_build_missing_directory_destroyed (BuildMissingDirectory
* dir
)
141 /* Remove previously created directories */
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
);)
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
);
163 /* If the folder is missing created it before setting it */
166 build_gtk_file_chooser_create_and_set_current_folder_uri (GtkFileChooser
*chooser
, const gchar
*uri
)
169 GError
*error
= NULL
;
172 dir
= g_file_new_for_uri (uri
);
173 parent
= build_make_directories (dir
, NULL
, &error
);
176 BuildMissingDirectory
* dir
;
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
,
190 (GDestroyNotify
)on_build_missing_directory_destroyed
);
194 g_object_set_qdata (G_OBJECT (chooser
),
195 GTK_FILE_CHOOSER_CREATE_DIRECTORY_QUARK
,
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 */
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
);
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
);
227 g_object_unref (created_dir
);
228 g_object_unref (needed_dir
);
234 *---------------------------------------------------------------------------*/
237 on_select_configuration (GtkComboBox
*widget
, gpointer user_data
)
239 BuildConfigureDialog
*dlg
= (BuildConfigureDialog
*)user_data
;
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);
249 name
= gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg
->combo
));
254 /* Configuration name is mandatory disable Ok button */
255 gtk_widget_set_sensitive (dlg
->ok
, FALSE
);
259 BuildConfiguration
*cfg
;
264 gtk_widget_set_sensitive (dlg
->ok
, TRUE
);
266 cfg
= build_configuration_list_select (dlg
->config_list
, name
);
270 args_str
= g_string_new (NULL
);
271 arg
= build_configuration_get_args (cfg
);
274 for (; *arg
!= NULL
; arg
++)
276 gchar
*quoted_arg
= g_shell_quote (*arg
);
278 g_string_append (args_str
, 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
);
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
))
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
)));
316 *---------------------------------------------------------------------------*/
319 build_dialog_configure (GtkWindow
* parent
, const gchar
*project_root_uri
, BuildConfigurationList
*config_list
, gboolean
*run_autogen
)
322 BuildConfigureDialog dlg
;
323 BuildConfiguration
*cfg
= NULL
;
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
);
346 response
= gtk_dialog_run (GTK_DIALOG (dlg
.win
));
348 if (response
== GTK_RESPONSE_OK
)
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);
363 name
= gtk_combo_box_get_active_text (GTK_COMBO_BOX (dlg
.combo
));
365 cfg
= build_configuration_list_create (config_list
, 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
);
376 gtk_widget_destroy (GTK_WIDGET(dlg
.win
));