1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2000 Naba Kumar
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
25 #include <glib/gstdio.h>
27 #include <libanjuta/anjuta-shell.h>
28 #include <libanjuta/anjuta-launcher.h>
29 #include <libanjuta/anjuta-utils.h>
30 #include <libanjuta/anjuta-debug.h>
31 #include <libanjuta/anjuta-plugin-manager.h>
32 #include <libanjuta/interfaces/ianjuta-file.h>
33 #include <libanjuta/interfaces/ianjuta-file-manager.h>
34 #include <libanjuta/interfaces/ianjuta-project-manager.h>
35 #include <libanjuta/interfaces/ianjuta-file-loader.h>
36 #include <libanjuta/interfaces/ianjuta-buildable.h>
37 #include <libanjuta/interfaces/ianjuta-builder.h>
38 #include <libanjuta/interfaces/ianjuta-environment.h>
39 #include <libanjuta/interfaces/ianjuta-message-manager.h>
40 #include <libanjuta/interfaces/ianjuta-document-manager.h>
41 #include <libanjuta/interfaces/ianjuta-language.h>
42 #include <libanjuta/interfaces/ianjuta-file-savable.h>
43 #include <libanjuta/interfaces/ianjuta-indicable.h>
44 #include <libanjuta/interfaces/ianjuta-markable.h>
45 #include <libanjuta/interfaces/ianjuta-preferences.h>
48 #include "build-options.h"
54 #if defined(__FreeBSD__)
55 #include <sys/signal.h>
58 #define ICON_FILE "anjuta-build-basic-autotools-plugin-48.png"
59 #define ANJUTA_PIXMAP_BUILD "anjuta-build"
60 #define ANJUTA_STOCK_BUILD "anjuta-build"
62 #define UI_FILE PACKAGE_DATA_DIR "/ui/anjuta-build-basic-autotools-plugin.xml"
63 #define MAX_BUILD_PANES 3
64 #define PREF_SCHEMA "org.gnome.anjuta.plugins.build"
65 #define PREF_INDICATORS_AUTOMATIC "indicators-automatic"
66 #define PREF_PARALLEL_MAKE "parallel-make"
67 #define PREF_PARALLEL_MAKE_JOB "parallel-make-job"
68 #define PREF_TRANSLATE_MESSAGE "translate-message"
69 #define PREF_CONTINUE_ON_ERROR "continue-error"
71 #define BUILD_PREFS_DIALOG "preferences-dialog-build"
72 #define BUILD_PREFS_ROOT "preferences-build-container"
73 #define INSTALL_ROOT_CHECK "preferences:install-root"
74 #define INSTALL_ROOT_ENTRY "preferences:install-root-command"
75 #define PARALLEL_MAKE_CHECK "preferences:parallel-make"
76 #define PARALLEL_MAKE_SPIN "preferences:parallel-make-job"
78 static gpointer parent_class
;
100 IAnjutaIndicableIndicator indicator
;
101 } BuildIndicatorLocation
;
103 /* Command processing */
106 AnjutaPlugin
*plugin
;
108 AnjutaLauncher
*launcher
;
111 BuildProgram
*program
;
113 IAnjutaMessageView
*message_view
;
114 GHashTable
*build_dir_stack
;
116 /* Indicator locations */
119 /* Editors in which indicators have been updated */
120 GHashTable
*indicators_updated_editors
;
123 IAnjutaEnvironment
*environment
;
130 static void update_project_ui (BasicAutotoolsPlugin
*bb_plugin
);
132 static GList
*patterns_list
= NULL
;
134 /* The translations should match that of 'make' program. Both strings uses
135 * pearl regular expression
136 * 2 similar strings are used in order to parse the output of 2 different
137 * version of make if necessary. If you update one string, move the first
138 * string into the second slot and then replace the first string only. */
139 static MessagePattern patterns_make_entering
[] = {{N_("make(\\[\\d+\\])?:\\s+Entering\\s+directory\\s+`(.+)'"), NULL
, NULL
},
140 {N_("make(\\[\\d+\\])?:\\s+Entering\\s+directory\\s+'(.+)'"), NULL
, NULL
},
143 /* The translations should match that of 'make' program. Both strings uses
144 * pearl regular expression
145 * 2 similar strings are used in order to parse the output of 2 different
146 * version of make if necessary. If you update one string, move the first
147 * string into the second slot and then replace the first string only. */
148 static MessagePattern patterns_make_leaving
[] = {{N_("make(\\[\\d+\\])?:\\s+Leaving\\s+directory\\s+`(.+)'"), NULL
, NULL
},
149 {N_("make(\\[\\d+\\])?:\\s+Leaving\\s+directory\\s+'(.+)'"), NULL
, NULL
},
153 *---------------------------------------------------------------------------*/
155 /* Allow installation as root (#321455) */
156 static void on_root_check_toggled(GtkWidget
* toggle_button
, GtkWidget
* entry
)
158 gtk_widget_set_sensitive(entry
,
159 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button
)));
163 escape_label (const gchar
*str
)
168 ret
= g_string_new ("");
170 while (*iter
!= '\0')
174 ret
= g_string_append (ret
, "__");
183 iter
= g_utf8_next_char (iter
);
186 ret
= g_string_append_len (ret
, start
, end
- start
);
189 return g_string_free (ret
, FALSE
);
192 /* Indicator locations reported by the build */
194 static BuildIndicatorLocation
*
195 build_indicator_location_new (const gchar
*filename
, gint line
,
196 IAnjutaIndicableIndicator indicator
,
197 const gchar
* tooltip
)
199 BuildIndicatorLocation
*loc
= g_new0 (BuildIndicatorLocation
, 1);
200 loc
->file
= g_file_new_for_path (filename
);
202 loc
->indicator
= indicator
;
203 loc
->tooltip
= g_strdup (tooltip
);
208 build_indicator_location_set (BuildIndicatorLocation
*loc
,
209 IAnjutaEditor
*editor
,
212 IAnjutaIterable
*line_start
, *line_end
;
214 if (editor
&& editor_file
&&
215 IANJUTA_IS_INDICABLE (editor
) &&
216 IANJUTA_IS_EDITOR (editor
) &&
217 g_file_equal (editor_file
, loc
->file
))
219 DEBUG_PRINT ("loc line: %d", loc
->line
);
221 line_start
= ianjuta_editor_get_line_begin_position (editor
,
224 line_end
= ianjuta_editor_get_line_end_position (editor
,
226 ianjuta_indicable_set (IANJUTA_INDICABLE (editor
),
227 line_start
, line_end
, loc
->indicator
,
230 g_object_unref (line_start
);
231 g_object_unref (line_end
);
233 if (editor
&& editor_file
&&
234 IANJUTA_IS_MARKABLE (editor
) &&
235 g_file_equal (editor_file
, loc
->file
))
237 ianjuta_markable_mark (IANJUTA_MARKABLE (editor
),
238 loc
->line
, IANJUTA_MARKABLE_MESSAGE
,
244 build_indicator_location_free (BuildIndicatorLocation
*loc
)
246 g_object_unref (loc
->file
);
247 g_free (loc
->tooltip
);
254 build_context_stack_destroy (gpointer value
)
256 GSList
*slist
= (GSList
*)value
;
259 g_slist_foreach (slist
, (GFunc
)g_free
, NULL
);
260 g_slist_free (slist
);
265 build_context_push_dir (BuildContext
*context
, const gchar
*key
,
270 if (context
->build_dir_stack
== NULL
)
272 context
->build_dir_stack
=
273 g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
,
274 build_context_stack_destroy
);
276 dir_stack
= g_hash_table_lookup (context
->build_dir_stack
, key
);
278 g_hash_table_steal (context
->build_dir_stack
, key
);
280 dir_stack
= g_slist_prepend (dir_stack
, g_strdup (dir
));
281 g_hash_table_insert (context
->build_dir_stack
, (gpointer
)key
, dir_stack
);
285 build_context_pop_dir (BuildContext
*context
, const gchar
*key
,
291 if (context
->build_dir_stack
== NULL
)
293 dir_stack
= g_hash_table_lookup (context
->build_dir_stack
, key
);
294 if (dir_stack
== NULL
)
297 g_hash_table_steal (context
->build_dir_stack
, key
);
298 top_dir
= dir_stack
->data
;
299 dir_stack
= g_slist_remove (dir_stack
, top_dir
);
301 if (strcmp (top_dir
, dir
) != 0)
303 DEBUG_PRINT("%s", "Directory stack misaligned!!");
307 g_hash_table_insert (context
->build_dir_stack
, (gpointer
)key
, dir_stack
);
311 build_context_get_dir (BuildContext
*context
, const gchar
*key
)
315 if (context
->build_dir_stack
== NULL
)
317 dir_stack
= g_hash_table_lookup (context
->build_dir_stack
, key
);
318 if (dir_stack
== NULL
)
321 return dir_stack
->data
;
325 build_context_get_work_dir (BuildContext
* context
)
327 return context
->program
->work_dir
;
331 build_context_get_plugin (BuildContext
* context
)
333 return context
->plugin
;
337 build_context_cancel (BuildContext
*context
)
339 if (context
->launcher
!= NULL
)
341 anjuta_launcher_signal (context
->launcher
, SIGTERM
);
346 build_context_destroy_command (BuildContext
*context
)
348 if (context
->used
) return FALSE
;
349 if (context
->program
)
351 build_program_free (context
->program
);
352 context
->program
= NULL
;
355 if (context
->launcher
)
357 g_object_unref (context
->launcher
);
358 context
->launcher
= NULL
;
361 if (context
->environment
)
363 g_object_unref (context
->environment
);
364 context
->environment
= NULL
;
367 /* Empty context, remove from pool */
368 if (context
->message_view
== NULL
)
370 ANJUTA_PLUGIN_BASIC_AUTOTOOLS (context
->plugin
)->contexts_pool
=
371 g_list_remove (ANJUTA_PLUGIN_BASIC_AUTOTOOLS (context
->plugin
)->contexts_pool
,
384 build_context_destroy_view (BuildContext
*context
)
386 BasicAutotoolsPlugin
* plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (context
->plugin
);
387 if (context
->message_view
)
389 gtk_widget_destroy (GTK_WIDGET (context
->message_view
));
390 context
->message_view
= NULL
;
393 if (context
->build_dir_stack
)
395 g_hash_table_destroy (context
->build_dir_stack
);
396 context
->build_dir_stack
= NULL
;
398 if (context
->indicators_updated_editors
)
400 g_hash_table_destroy (context
->indicators_updated_editors
);
401 context
->indicators_updated_editors
= NULL
;
404 g_slist_foreach (context
->locations
, (GFunc
) build_indicator_location_free
,
406 g_slist_free (context
->locations
);
407 context
->locations
= NULL
;
409 /* Empty context, remove from pool */
410 if (context
->launcher
== NULL
)
412 plugin
->contexts_pool
=
413 g_list_remove (plugin
->contexts_pool
,
420 anjuta_launcher_signal (context
->launcher
, SIGKILL
);
427 build_context_destroy (BuildContext
*context
)
429 if (build_context_destroy_command (context
))
431 build_context_destroy_view (context
);
436 build_context_reset (BuildContext
*context
)
440 ianjuta_message_view_clear (context
->message_view
, NULL
);
442 if (context
->build_dir_stack
)
443 g_hash_table_destroy (context
->build_dir_stack
);
444 context
->build_dir_stack
= NULL
;
446 g_slist_foreach (context
->locations
,
447 (GFunc
) build_indicator_location_free
, NULL
);
448 g_slist_free (context
->locations
);
449 context
->locations
= NULL
;
460 fp
= fopen (PACKAGE_DATA_DIR
"/build/automake-c.filters", "r");
463 DEBUG_PRINT ("Failed to load filters: %s",
464 PACKAGE_DATA_DIR
"/build/automake-c.filters");
467 while (!feof (fp
) && !ferror (fp
))
471 BuildPattern
*pattern
;
473 if (!fgets (buffer
, 1024, fp
))
475 tokens
= g_strsplit (buffer
, "|||", 3);
477 if (!tokens
[0] || !tokens
[1])
479 DEBUG_PRINT ("Cannot parse regex: %s", buffer
);
483 pattern
= g_new0 (BuildPattern
, 1);
484 pattern
->pattern
= g_strdup (tokens
[0]);
485 pattern
->replace
= g_strdup (tokens
[1]);
487 pattern
->options
= atoi (tokens
[2]);
490 patterns_list
= g_list_prepend (patterns_list
, pattern
);
493 patterns_list
= g_list_reverse (patterns_list
);
497 build_regex_init_message (MessagePattern
*patterns
)
499 g_return_if_fail (patterns
!= NULL
);
501 if (patterns
->regex
!= NULL
)
502 return; /* Already done */
504 for (;patterns
->pattern
!= NULL
; patterns
++)
506 /* Untranslated string */
507 patterns
->regex
= g_regex_new(
513 /* Translated string */
514 patterns
->local_regex
= g_regex_new(
515 _(patterns
->pattern
),
526 GError
*error
= NULL
;
528 build_regex_init_message (patterns_make_entering
);
530 build_regex_init_message (patterns_make_leaving
);
536 if (((BuildPattern
*)(patterns_list
->data
))->regex
)
539 node
= patterns_list
;
542 BuildPattern
*pattern
;
544 pattern
= node
->data
;
550 &error
); /* for error message */
552 DEBUG_PRINT ("GRegex compilation failed: pattern \"%s\": error %s",
553 pattern
->pattern
, error
->message
);
554 g_error_free (error
);
556 node
= g_list_next (node
);
560 /* Regex processing */
562 build_get_summary (const gchar
*details
, BuildPattern
* bp
)
565 GMatchInfo
*match_info
;
570 if (!bp
|| !bp
->regex
)
573 matched
= g_regex_match(
574 bp
->regex
, /* result of g_regex_new() */
575 details
, /* the subject string */
581 ret
= g_string_new ("");
583 while (*iter
!= '\0')
585 if (*iter
== '\\' && isdigit(*(iter
+ 1)))
587 char temp
[2] = {0, 0};
588 gint start_pos
, end_pos
;
590 temp
[0] = *(iter
+ 1);
591 int idx
= atoi (temp
);
593 g_match_info_fetch_pos (match_info
, idx
, &start_pos
, &end_pos
);
595 ret
= g_string_append_len (ret
, details
+ start_pos
,
596 end_pos
- start_pos
);
605 iter
= g_utf8_next_char (iter
);
608 ret
= g_string_append_len (ret
, start
, end
- start
);
612 final
= g_string_free (ret
, FALSE
);
613 if (strlen (final
) <= 0) {
618 g_match_info_free (match_info
);
624 on_build_mesg_arrived (AnjutaLauncher
*launcher
,
625 AnjutaLauncherOutputType output_type
,
626 const gchar
* mesg
, gpointer user_data
)
628 BuildContext
*context
= (BuildContext
*)user_data
;
629 /* Message view could have been destroyed */
630 if (context
->message_view
)
631 ianjuta_message_view_buffer_append (context
->message_view
, mesg
, NULL
);
635 parse_error_line (const gchar
* line
, gchar
** filename
, int *lineno
)
642 while (line
[i
++] != ':')
644 if (i
>= strlen (line
) || i
>= 512 || line
[i
- 1] == ' ')
649 if (isdigit (line
[i
]))
652 while (isdigit (line
[i
++])) ;
653 dummy
= g_strndup (&line
[j
], i
- j
- 1);
654 *lineno
= atoi (dummy
);
657 dummy
= g_strndup (line
, j
- 1);
658 *filename
= g_strdup (g_strstrip (dummy
));
675 } while (isspace (line
[i
]) == FALSE
);
677 while (line
[i
++] != ':')
679 if (i
>= strlen (line
) || i
>= 512 || line
[i
- 1] == ' ')
686 if (isdigit (line
[i
]))
689 while (isdigit (line
[i
++])) ;
690 dummy
= g_strndup (&line
[j
], i
- j
- 1);
691 *lineno
= atoi (dummy
);
694 dummy
= g_strndup (&line
[k
], j
- k
- 1);
695 *filename
= g_strdup (g_strstrip (dummy
));
706 on_build_mesg_format (IAnjutaMessageView
*view
, const gchar
*one_line
,
707 BuildContext
*context
)
709 gchar
*dummy_fn
, *line
;
711 IAnjutaMessageViewType type
;
713 gchar
*summary
= NULL
;
714 gchar
*freeptr
= NULL
;
715 BasicAutotoolsPlugin
*p
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (context
->plugin
);
717 GMatchInfo
*match_info
;
720 g_return_if_fail (one_line
!= NULL
);
722 /* Check if make enter a new directory */
724 for (pat
= patterns_make_entering
; pat
->pattern
!= NULL
; pat
++)
726 matched
= g_regex_match(
732 g_match_info_free (match_info
);
733 matched
= g_regex_match(
739 g_match_info_free (match_info
);
746 dir
= g_match_info_fetch (match_info
, 2);
747 dir
= context
->environment
? ianjuta_environment_get_real_directory(context
->environment
, dir
, NULL
)
749 build_context_push_dir (context
, "default", dir
);
750 summary
= g_strdup_printf(_("Entering: %s"), dir
);
751 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
,
752 summary
, one_line
, NULL
);
755 g_match_info_free (match_info
);
758 /* Check if make leave a directory */
760 for (pat
= patterns_make_leaving
; pat
->pattern
!= NULL
; pat
++)
762 matched
= g_regex_match(
768 g_match_info_free (match_info
);
769 matched
= g_regex_match(
775 g_match_info_free (match_info
);
782 dir
= g_match_info_fetch (match_info
, 2);
783 dir
= context
->environment
? ianjuta_environment_get_real_directory(context
->environment
, dir
, NULL
)
785 build_context_pop_dir (context
, "default", dir
);
786 summary
= g_strdup_printf(_("Leaving: %s"), dir
);
787 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
,
788 summary
, one_line
, NULL
);
791 g_match_info_free (match_info
);
794 /* Save freeptr so that we can free the copied string */
795 line
= freeptr
= g_strdup (one_line
);
797 g_strchug(line
); /* Remove leading whitespace */
798 if (g_str_has_prefix(line
, "if ") == TRUE
)
803 /* Find the first occurence of ';' (ignoring nesting in quotations) */
804 end
= strchr(line
, ';');
811 type
= IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
;
812 if (parse_error_line(line
, &dummy_fn
, &dummy_int
))
814 gchar
*start_str
, *end_str
, *mid_str
;
815 BuildIndicatorLocation
*loc
;
816 IAnjutaIndicableIndicator indicator
;
818 if ((strstr (line
, "warning:") != NULL
) ||
819 /* The translations should match that of 'gcc' program.
820 * The second string with -old should be used for an older
821 * version of 'gcc' if necessary. If you update one string,
822 * move the first one to translate the -old string and then
823 * replace the first string only. */
824 (strstr (line
, _("warning:")) != NULL
) ||
825 (strstr (line
, _("warning:-old")) != NULL
))
827 type
= IANJUTA_MESSAGE_VIEW_TYPE_WARNING
;
828 indicator
= IANJUTA_INDICABLE_WARNING
;
830 else if ((strstr (line
, "error:") != NULL
) ||
831 /* The translations should match that of 'gcc' program.
832 * The second string with -old should be used for an older
833 * version of 'gcc' if necessary. If you update one string,
834 * move the first one to translate the -old string and then
835 * replace the first string only. */
836 (strstr (line
, _("error:")) != NULL
) ||
837 (strstr (line
, _("error:-old")) != NULL
))
839 type
= IANJUTA_MESSAGE_VIEW_TYPE_ERROR
;
840 indicator
= IANJUTA_INDICABLE_CRITICAL
;
844 type
= IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
;
845 indicator
= IANJUTA_INDICABLE_IMPORTANT
;
848 mid_str
= strstr (line
, dummy_fn
);
849 DEBUG_PRINT ("mid_str = %s, line = %s", mid_str
, line
);
850 start_str
= g_strndup (line
, mid_str
- line
);
851 end_str
= line
+ strlen (start_str
) + strlen (dummy_fn
);
852 DEBUG_PRINT("dummy_fn: %s", dummy_fn
);
853 if (g_path_is_absolute(dummy_fn
))
855 mid_str
= g_strdup(dummy_fn
);
859 mid_str
= g_build_filename (build_context_get_dir (context
, "default"),
862 DEBUG_PRINT ("mid_str: %s", mid_str
);
866 line
= g_strconcat (start_str
, mid_str
, end_str
, NULL
);
868 /* We sucessfully build an absolute path of the file (mid_str),
869 * so we create an indicator location for it and save it.
870 * Additionally, check of current editor holds this file and if
871 * so, set the indicator.
873 DEBUG_PRINT ("dummy int: %d", dummy_int
);
875 loc
= build_indicator_location_new (mid_str
, dummy_int
,
877 context
->locations
= g_slist_prepend (context
->locations
, loc
);
879 /* If current editor file is same as indicator file, set indicator */
880 if (g_settings_get_boolean (p
->settings
, PREF_INDICATORS_AUTOMATIC
))
882 build_indicator_location_set (loc
, p
->current_editor
,
883 p
->current_editor_file
);
888 line
= g_strconcat (start_str
, dummy_fn
, end_str
, NULL
);
895 node
= patterns_list
;
898 BuildPattern
*pattern
= node
->data
;
899 summary
= build_get_summary (line
, pattern
);
902 node
= g_list_next (node
);
907 ianjuta_message_view_append (view
, type
, summary
, line
, NULL
);
911 ianjuta_message_view_append (view
, type
, line
, "", NULL
);
916 on_build_mesg_parse (IAnjutaMessageView
*view
, const gchar
*line
,
917 BuildContext
*context
)
921 if (parse_error_line (line
, &filename
, &lineno
))
923 IAnjutaDocumentManager
*docman
;
926 /* Go to file and line number */
927 docman
= anjuta_shell_get_interface (context
->plugin
->shell
,
928 IAnjutaDocumentManager
,
931 /* Full path is detected from parse_error_line() */
932 file
= g_file_new_for_path(filename
);
933 ianjuta_document_manager_goto_file_line_mark(docman
, file
, lineno
, TRUE
, NULL
);
934 g_object_unref (file
);
939 on_build_terminated (AnjutaLauncher
*launcher
,
940 gint child_pid
, gint status
, gulong time_taken
,
941 BuildContext
*context
)
943 context
->used
= FALSE
;
944 if (context
->program
->callback
!= NULL
)
948 if (WIFEXITED (status
))
950 if (WEXITSTATUS (status
) != 0)
952 err
= g_error_new (ianjuta_builder_error_quark (),
953 WEXITSTATUS (status
),
954 _("Command exited with status %d"), WEXITSTATUS (status
));
957 else if (WIFSIGNALED (status
))
959 switch (WTERMSIG (status
))
962 err
= g_error_new (ianjuta_builder_error_quark (),
963 IANJUTA_BUILDER_CANCELED
,
964 _("Command canceled by user"));
967 err
= g_error_new (ianjuta_builder_error_quark (),
968 IANJUTA_BUILDER_ABORTED
,
969 _("Command aborted by user"));
972 err
= g_error_new (ianjuta_builder_error_quark (),
973 IANJUTA_BUILDER_INTERRUPTED
,
974 _("Command terminated with signal %d"), WTERMSIG(status
));
980 err
= g_error_new_literal (ianjuta_builder_error_quark (),
981 IANJUTA_BUILDER_TERMINATED
,
982 _("Command terminated for an unknown reason"));
984 build_program_callback (context
->program
, G_OBJECT (context
->plugin
), context
, err
);
985 if (err
!= NULL
) g_error_free (err
);
988 return; /* Another command is run */
990 g_signal_handlers_disconnect_by_func (context
->launcher
,
991 G_CALLBACK (on_build_terminated
),
994 /* Message view could have been destroyed before */
995 if (context
->message_view
)
997 IAnjutaMessageManager
*mesg_manager
;
1000 buff1
= g_strdup_printf (_("Total time taken: %lu secs\n"),
1002 mesg_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (context
->plugin
)->shell
,
1003 IAnjutaMessageManager
, NULL
);
1006 ianjuta_message_view_buffer_append (context
->message_view
,
1007 _("Completed unsuccessfully\n"), NULL
);
1008 ianjuta_message_manager_set_view_icon_from_stock (mesg_manager
,
1009 context
->message_view
,
1010 GTK_STOCK_STOP
, NULL
);
1014 ianjuta_message_view_buffer_append (context
->message_view
,
1015 _("Completed successfully\n"), NULL
);
1016 ianjuta_message_manager_set_view_icon_from_stock (mesg_manager
,
1017 context
->message_view
,
1018 GTK_STOCK_APPLY
, NULL
);
1020 ianjuta_message_view_buffer_append (context
->message_view
, buff1
, NULL
);
1023 /* Goto the first error if it exists */
1024 /* if (anjuta_preferences_get_int (ANJUTA_PREFERENCES (app->preferences),
1025 "build.option.gotofirst"))
1026 an_message_manager_next(app->messages);
1029 update_project_ui (ANJUTA_PLUGIN_BASIC_AUTOTOOLS (context
->plugin
));
1031 build_context_destroy_command (context
);
1035 on_message_view_destroyed (BuildContext
*context
, GtkWidget
*view
)
1037 DEBUG_PRINT ("%s", "Destroying build context");
1038 context
->message_view
= NULL
;
1040 build_context_destroy_view (context
);
1044 build_set_animation (IAnjutaMessageManager
* mesg_manager
, BuildContext
* context
)
1046 GtkIconTheme
*icon_theme
= gtk_icon_theme_get_default ();
1047 GtkIconInfo
*icon_info
;
1049 icon_info
= gtk_icon_theme_lookup_icon (icon_theme
, "process-working", 16, 0);
1050 name
= gtk_icon_info_get_filename (icon_info
);
1053 int size
= gtk_icon_info_get_base_size (icon_info
);
1054 GdkPixbufSimpleAnim
* anim
= gdk_pixbuf_simple_anim_new (size
, size
, 5);
1055 GdkPixbuf
*image
= gdk_pixbuf_new_from_file (name
, NULL
);
1058 int grid_width
= gdk_pixbuf_get_width (image
);
1059 int grid_height
= gdk_pixbuf_get_height (image
);
1061 for (y
= 0; y
< grid_height
; y
+= size
)
1063 for (x
= 0; x
< grid_width
; x
+= size
)
1065 GdkPixbuf
*pixbuf
= gdk_pixbuf_new_subpixbuf (image
, x
, y
, size
,size
);
1068 gdk_pixbuf_simple_anim_add_frame (anim
, pixbuf
);
1072 ianjuta_message_manager_set_view_icon (mesg_manager
,
1073 context
->message_view
,
1074 GDK_PIXBUF_ANIMATION (anim
), NULL
);
1075 g_object_unref (image
);
1078 gtk_icon_info_free (icon_info
);
1082 static BuildContext
*
1083 build_get_context_with_message(BasicAutotoolsPlugin
*plugin
, const gchar
*dir
)
1085 IAnjutaMessageManager
*mesg_manager
;
1088 BuildContext
*context
= NULL
;
1089 static gint message_pane_count
= 0;
1091 /* Initialise regex rules */
1094 subdir
= g_path_get_basename (dir
);
1095 /* Translators: the first number is the number of the build attemp,
1096 the string is the directory where the build takes place */
1097 snprintf (mname
, 128, _("Build %d: %s"), ++message_pane_count
, subdir
);
1100 /* If we already have MAX_BUILD_PANES build panes, find a free context */
1101 if (g_list_length (plugin
->contexts_pool
) >= MAX_BUILD_PANES
)
1104 node
= plugin
->contexts_pool
;
1109 if (c
->launcher
== NULL
)
1114 node
= g_list_next (node
);
1118 mesg_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
1119 IAnjutaMessageManager
, NULL
);
1122 build_context_reset (context
);
1124 /* It will be re-inserted in right order */
1125 plugin
->contexts_pool
= g_list_remove (plugin
->contexts_pool
, context
);
1126 ianjuta_message_manager_set_view_title (mesg_manager
,
1127 context
->message_view
,
1133 /* If no free context found, create one */
1134 context
= g_new0 (BuildContext
, 1);
1135 context
->plugin
= ANJUTA_PLUGIN(plugin
);
1136 context
->indicators_updated_editors
=
1137 g_hash_table_new (g_direct_hash
, g_direct_equal
);
1139 context
->message_view
=
1140 ianjuta_message_manager_add_view (mesg_manager
, mname
,
1143 g_signal_connect (G_OBJECT (context
->message_view
), "buffer_flushed",
1144 G_CALLBACK (on_build_mesg_format
), context
);
1145 g_signal_connect (G_OBJECT (context
->message_view
), "message_clicked",
1146 G_CALLBACK (on_build_mesg_parse
), context
);
1147 g_object_weak_ref (G_OBJECT (context
->message_view
),
1148 (GWeakNotify
)on_message_view_destroyed
, context
);
1150 build_set_animation (mesg_manager
, context
);
1152 ianjuta_message_manager_set_current_view (mesg_manager
,
1153 context
->message_view
, NULL
);
1155 /* Reset indicators in editors */
1156 if (IANJUTA_IS_INDICABLE (plugin
->current_editor
))
1157 ianjuta_indicable_clear (IANJUTA_INDICABLE (plugin
->current_editor
),
1159 if (IANJUTA_IS_MARKABLE (plugin
->current_editor
))
1160 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (plugin
->current_editor
),
1161 IANJUTA_MARKABLE_MESSAGE
, NULL
);
1162 g_hash_table_remove_all (context
->indicators_updated_editors
);
1169 build_get_context (BasicAutotoolsPlugin
*plugin
, const gchar
*dir
,
1172 BuildContext
*context
= NULL
;
1173 AnjutaPluginManager
*plugin_manager
;
1178 context
= build_get_context_with_message (plugin
, dir
);
1182 /* Context without a message view */
1183 context
= g_new0 (BuildContext
, 1);
1184 DEBUG_PRINT ("new context %p", context
);
1185 context
->plugin
= ANJUTA_PLUGIN(plugin
);
1188 plugin_manager
= anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin
)->shell
, NULL
);
1190 if (context
->environment
!= NULL
)
1192 g_object_unref (context
->environment
);
1194 if (anjuta_plugin_manager_is_active_plugin (plugin_manager
, "IAnjutaEnvironment"))
1196 IAnjutaEnvironment
*env
= IANJUTA_ENVIRONMENT (anjuta_shell_get_object (ANJUTA_PLUGIN (plugin
)->shell
,
1197 "IAnjutaEnvironment", NULL
));
1200 context
->environment
= env
;
1204 context
->environment
= NULL
;
1207 context
->launcher
= anjuta_launcher_new ();
1208 g_signal_connect (G_OBJECT (context
->launcher
), "child-exited",
1209 G_CALLBACK (on_build_terminated
), context
);
1210 build_context_push_dir (context
, "default", dir
);
1211 buf
= g_strconcat (dir
, "/", NULL
);
1215 plugin
->contexts_pool
= g_list_append (plugin
->contexts_pool
, context
);
1221 build_set_command_in_context (BuildContext
* context
, BuildProgram
*prog
)
1223 context
->program
= prog
;
1224 context
->used
= TRUE
;
1228 build_execute_command_in_context (BuildContext
* context
, GError
**err
)
1230 GSettings
* settings
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS(context
->plugin
)->settings
;
1232 /* Send options to make */
1233 if (strcmp (build_program_get_basename (context
->program
), "make") == 0)
1235 if (g_settings_get_boolean (settings
, PREF_PARALLEL_MAKE
))
1237 gchar
*arg
= g_strdup_printf ("-j%d", g_settings_get_int (settings
, PREF_PARALLEL_MAKE_JOB
));
1238 build_program_insert_arg (context
->program
, 1, arg
);
1241 if (g_settings_get_boolean (settings
, PREF_CONTINUE_ON_ERROR
))
1243 build_program_insert_arg (context
->program
, 1, "-k");
1247 /* Set a current working directory which can contains symbolic links */
1248 build_program_add_env (context
->program
, "PWD", context
->program
->work_dir
);
1250 if (!g_settings_get_boolean (settings
, PREF_TRANSLATE_MESSAGE
))
1252 build_program_add_env (context
->program
, "LANGUAGE", "C");
1255 if (!build_program_override (context
->program
, context
->environment
))
1257 build_context_destroy_command (context
);
1261 if (context
->message_view
)
1265 command
= g_strjoinv (" ", context
->program
->argv
);
1266 ianjuta_message_view_buffer_append (context
->message_view
,
1267 "Building in directory: ", NULL
);
1268 ianjuta_message_view_buffer_append (context
->message_view
, context
->program
->work_dir
, NULL
);
1269 ianjuta_message_view_buffer_append (context
->message_view
, "\n", NULL
);
1270 ianjuta_message_view_buffer_append (context
->message_view
, command
, NULL
);
1271 ianjuta_message_view_buffer_append (context
->message_view
, "\n", NULL
);
1274 anjuta_launcher_execute_v (context
->launcher
,
1275 context
->program
->work_dir
,
1276 context
->program
->argv
,
1277 context
->program
->envp
,
1278 on_build_mesg_arrived
, context
);
1282 anjuta_launcher_execute_v (context
->launcher
,
1283 context
->program
->work_dir
,
1284 context
->program
->argv
,
1285 context
->program
->envp
,
1293 build_delayed_execute_command (IAnjutaFileSavable
*savable
, GFile
*file
, gpointer user_data
)
1295 BuildContext
*context
= (BuildContext
*)user_data
;
1297 if (savable
!= NULL
)
1299 g_signal_handlers_disconnect_by_func (savable
, G_CALLBACK (build_delayed_execute_command
), user_data
);
1300 context
->file_saved
--;
1303 if (context
->file_saved
== 0)
1305 build_execute_command_in_context (context
, NULL
);
1310 build_save_and_execute_command_in_context (BuildContext
* context
, GError
**err
)
1312 IAnjutaDocumentManager
*docman
;
1314 context
->file_saved
= 0;
1316 docman
= anjuta_shell_get_interface (context
->plugin
->shell
, IAnjutaDocumentManager
, NULL
);
1317 /* No document manager, so no file to save */
1320 GList
*doc_list
= ianjuta_document_manager_get_doc_widgets (docman
, NULL
);
1323 for (node
= g_list_first (doc_list
); node
!= NULL
; node
= g_list_next (node
))
1325 if (IANJUTA_IS_FILE_SAVABLE (node
->data
))
1327 IAnjutaFileSavable
* save
= IANJUTA_FILE_SAVABLE (node
->data
);
1328 if (ianjuta_file_savable_is_dirty (save
, NULL
))
1330 context
->file_saved
++;
1331 g_signal_connect (G_OBJECT (save
), "saved", G_CALLBACK (build_delayed_execute_command
), context
);
1332 ianjuta_file_savable_save (save
, NULL
);
1336 g_list_free (doc_list
);
1339 build_delayed_execute_command (NULL
, NULL
, context
);
1345 build_cancel_command (BasicAutotoolsPlugin
* bplugin
, BuildContext
*context
,
1350 if (context
== NULL
) return;
1352 for (node
= g_list_first (bplugin
->contexts_pool
); node
!= NULL
; node
= g_list_next (node
))
1354 if (node
->data
== context
)
1356 build_context_cancel (context
);
1361 /* Invalid handle passed */
1362 g_return_if_reached ();
1367 *---------------------------------------------------------------------------*/
1370 build_module_from_file (BasicAutotoolsPlugin
*plugin
, GFile
*file
, gchar
**target
)
1372 if (plugin
->project_root_dir
== NULL
)
1374 /* No project, use file without extension */
1376 GFile
*module
= NULL
;
1380 basename
= g_file_get_basename (file
);
1381 ptr
= strrchr (basename
, '.');
1382 if ((ptr
!= NULL
) && (ptr
!= basename
))
1387 parent
= g_file_get_parent (file
);
1390 module
= g_file_get_child (parent
, basename
);
1391 g_object_unref (parent
);
1395 if (ptr
!= NULL
) *ptr
= '.';
1407 /* Get corresponding build directory */
1408 return build_file_from_file (plugin
, file
, target
);
1414 on_build_project (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1416 if (plugin
->project_root_dir
)
1418 build_configure_and_build (plugin
, build_build_file_or_dir
, plugin
->project_root_dir
, NULL
, NULL
, NULL
);
1423 on_install_project (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1425 if (plugin
->project_root_dir
)
1427 build_configure_and_build (plugin
, build_install_dir
, plugin
->project_root_dir
, NULL
, NULL
, NULL
);
1432 on_clean_project (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1434 if (plugin
->project_root_dir
)
1436 build_clean_dir (plugin
, plugin
->project_root_dir
, NULL
);
1441 on_configure_project (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1443 build_configure_dialog (plugin
, NULL
, NULL
, NULL
, NULL
, NULL
);
1447 on_build_tarball (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1449 build_configure_and_build (plugin
, (BuildFunc
) build_tarball
, NULL
, NULL
, NULL
, NULL
);
1453 on_build_module (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1457 g_return_if_fail (plugin
->current_editor_file
!= NULL
);
1459 module
= build_module_from_file (plugin
, plugin
->current_editor_file
, NULL
);
1462 build_configure_and_build (plugin
, build_build_file_or_dir
, module
, NULL
, NULL
, NULL
);
1463 g_object_unref (module
);
1468 on_install_module (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1470 g_return_if_fail (plugin
->current_editor_file
!= NULL
);
1472 build_configure_and_build (plugin
, build_install_dir
, plugin
->current_editor_file
, NULL
, NULL
, NULL
);
1476 on_clean_module (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1478 g_return_if_fail (plugin
->current_editor_file
!= NULL
);
1480 build_clean_dir (plugin
, plugin
->current_editor_file
, NULL
);
1484 on_compile_file (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1486 g_return_if_fail (plugin
->current_editor_file
!= NULL
);
1488 build_configure_and_build (plugin
, (BuildFunc
) build_compile_file
, plugin
->current_editor_file
, NULL
, NULL
, NULL
);
1492 on_distclean_project (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1494 build_distclean (plugin
);
1498 on_select_configuration (GtkRadioMenuItem
*item
, gpointer user_data
)
1500 if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item
)))
1502 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (user_data
);
1507 name
= g_object_get_data (G_OBJECT (item
), "untranslated_name");
1509 build_configuration_list_select (plugin
->configurations
, name
);
1511 value
= g_new0 (GValue
, 1);
1512 g_value_init (value
, G_TYPE_STRING
);
1514 uri
= build_configuration_list_get_build_uri (plugin
->configurations
, build_configuration_list_get_selected (plugin
->configurations
));
1515 g_value_set_string (value
, uri
);
1518 anjuta_shell_add_value (ANJUTA_PLUGIN (plugin
)->shell
, IANJUTA_BUILDER_ROOT_URI
, value
, NULL
);
1522 /* File manager context menu */
1524 fm_compile (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1526 g_return_if_fail (plugin
->fm_current_file
!= NULL
);
1528 build_configure_and_build (plugin
, (BuildFunc
) build_compile_file
, plugin
->fm_current_file
, NULL
, NULL
, NULL
);
1532 fm_build (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1535 g_return_if_fail (plugin
->fm_current_file
!= NULL
);
1537 module
= build_module_from_file (plugin
, plugin
->fm_current_file
, NULL
);
1540 build_configure_and_build (plugin
, build_build_file_or_dir
, module
, NULL
, NULL
, NULL
);
1541 g_object_unref (module
);
1546 fm_install (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1548 g_return_if_fail (plugin
->fm_current_file
!= NULL
);
1550 build_configure_and_build (plugin
, build_install_dir
, plugin
->fm_current_file
, NULL
, NULL
, NULL
);
1554 fm_clean (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1556 g_return_if_fail (plugin
->fm_current_file
!= NULL
);
1558 build_clean_dir (plugin
, plugin
->fm_current_file
, NULL
);
1561 /* Project manager context menu */
1563 pm_compile (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1565 g_return_if_fail (plugin
->pm_current_file
!= NULL
);
1567 build_configure_and_build (plugin
, (BuildFunc
) build_compile_file
, plugin
->pm_current_file
, NULL
, NULL
, NULL
);
1571 pm_build (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1575 g_return_if_fail (plugin
->pm_current_file
!= NULL
);
1577 module
= build_module_from_file (plugin
, plugin
->pm_current_file
, NULL
);
1580 build_configure_and_build (plugin
, build_build_file_or_dir
, module
, NULL
, NULL
, NULL
);
1581 g_object_unref (module
);
1586 pm_install (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1588 g_return_if_fail (plugin
->pm_current_file
!= NULL
);
1590 build_configure_and_build (plugin
, build_install_dir
, plugin
->pm_current_file
, NULL
, NULL
, NULL
);
1594 pm_clean (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1596 g_return_if_fail (plugin
->pm_current_file
!= NULL
);
1598 build_clean_dir (plugin
, plugin
->pm_current_file
, NULL
);
1601 /* Message view context menu */
1603 mv_cancel (GtkAction
*action
, BasicAutotoolsPlugin
*plugin
)
1605 IAnjutaMessageManager
*msgman
;
1607 msgman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
1608 IAnjutaMessageManager
,
1613 IAnjutaMessageView
*view
;
1615 view
= ianjuta_message_manager_get_current_view (msgman
, NULL
);
1620 for (node
= g_list_first (plugin
->contexts_pool
); node
!= NULL
; node
= g_list_next (node
))
1622 BuildContext
*context
;
1624 context
= (BuildContext
*)node
->data
;
1625 if (context
->message_view
== view
)
1627 build_context_cancel (context
);
1635 static GtkActionEntry build_actions
[] =
1638 "ActionMenuBuild", NULL
,
1639 N_("_Build"), NULL
, NULL
, NULL
1642 "ActionBuildBuildProject", GTK_STOCK_CONVERT
,
1643 N_("_Build Project"), "<shift>F7",
1644 N_("Build whole project"),
1645 G_CALLBACK (on_build_project
)
1648 "ActionBuildInstallProject", NULL
,
1649 N_("_Install Project"), NULL
,
1650 N_("Install whole project"),
1651 G_CALLBACK (on_install_project
)
1654 "ActionBuildCleanProject", NULL
,
1655 N_("_Clean Project"), NULL
,
1656 N_("Clean whole project"),
1657 G_CALLBACK (on_clean_project
)
1660 "ActionBuildConfigure", NULL
,
1661 N_("C_onfigure Project…"), NULL
,
1662 N_("Configure project"),
1663 G_CALLBACK (on_configure_project
)
1666 "ActionBuildDistribution", NULL
,
1667 N_("Build _Tarball"), NULL
,
1668 N_("Build project tarball distribution"),
1669 G_CALLBACK (on_build_tarball
)
1672 "ActionBuildBuildModule", ANJUTA_STOCK_BUILD
,
1673 N_("_Build Module"), "F7",
1674 N_("Build module associated with current file"),
1675 G_CALLBACK (on_build_module
)
1678 "ActionBuildInstallModule", NULL
,
1679 N_("_Install Module"), NULL
,
1680 N_("Install module associated with current file"),
1681 G_CALLBACK (on_install_module
)
1684 "ActionBuildCleanModule", NULL
,
1685 N_("_Clean Module"), NULL
,
1686 N_("Clean module associated with current file"),
1687 G_CALLBACK (on_clean_module
)
1690 "ActionBuildCompileFile", NULL
,
1691 N_("Co_mpile File"), "F9",
1692 N_("Compile current editor file"),
1693 G_CALLBACK (on_compile_file
)
1696 "ActionBuildSelectConfiguration", NULL
,
1697 N_("Select Configuration"), NULL
,
1698 N_("Select current configuration"),
1702 "ActionBuildRemoveConfiguration", NULL
,
1703 N_("Remove Configuration"), NULL
,
1704 N_("Clean project (distclean) and remove configuration directory if possible"),
1705 G_CALLBACK (on_distclean_project
)
1709 static GtkActionEntry build_popup_actions
[] =
1712 "ActionPopupBuild", NULL
,
1713 N_("_Build"), NULL
, NULL
, NULL
1716 "ActionPopupBuildCompile", GTK_STOCK_CONVERT
,
1717 N_("_Compile"), NULL
,
1719 G_CALLBACK (fm_compile
)
1722 "ActionPopupBuildBuild", GTK_STOCK_EXECUTE
,
1725 G_CALLBACK (fm_build
)
1728 "ActionPopupBuildInstall", NULL
,
1729 N_("_Install"), NULL
,
1730 N_("Install module"),
1731 G_CALLBACK (fm_install
)
1734 "ActionPopupBuildClean", NULL
,
1737 G_CALLBACK (fm_clean
)
1740 "ActionPopupPMBuild", NULL
,
1741 N_("_Build"), NULL
, NULL
, NULL
1744 "ActionPopupPMBuildCompile", GTK_STOCK_CONVERT
,
1745 N_("_Compile"), NULL
,
1747 G_CALLBACK (pm_compile
)
1750 "ActionPopupPMBuildBuild", GTK_STOCK_EXECUTE
,
1753 G_CALLBACK (pm_build
)
1756 "ActionPopupPMBuildInstall", NULL
,
1757 N_("_Install"), NULL
,
1758 N_("Install module"),
1759 G_CALLBACK (pm_install
)
1762 "ActionPopupPMBuildClean", NULL
,
1765 G_CALLBACK (pm_clean
)
1768 "ActionPopupMVBuildCancel", NULL
,
1769 N_("_Cancel command"), NULL
,
1770 N_("Cancel build command"),
1771 G_CALLBACK (mv_cancel
)
1776 update_module_ui (BasicAutotoolsPlugin
*bb_plugin
)
1780 gchar
*filename
= NULL
;
1781 gchar
*module
= NULL
;
1783 gboolean has_file
= FALSE
;
1784 gboolean has_makefile
= FALSE
;
1785 gboolean has_project
= TRUE
;
1786 gboolean has_object
= FALSE
;
1788 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin
)->shell
, NULL
);
1790 DEBUG_PRINT ("%s", "Updating module UI");
1792 has_file
= bb_plugin
->current_editor_file
!= NULL
;
1793 has_project
= bb_plugin
->project_root_dir
!= NULL
;
1801 mod
= build_module_from_file (bb_plugin
, bb_plugin
->current_editor_file
, &target
);
1803 if (has_project
&& !g_file_equal (mod
, bb_plugin
->project_root_dir
) && !g_file_equal (mod
, bb_plugin
->project_build_dir
))
1805 module_name
= g_file_get_basename (mod
);
1806 module
= escape_label (module_name
);
1807 g_free (module_name
);
1811 filename
= escape_label (target
);
1814 has_makefile
= directory_has_makefile (mod
) || directory_has_makefile_am (bb_plugin
, mod
);
1815 g_object_unref (mod
);
1817 mod
= build_object_from_file (bb_plugin
, bb_plugin
->current_editor_file
);
1821 g_object_unref (mod
);
1825 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1826 "ActionBuildBuildModule");
1827 label
= g_strdup_printf (module
? _("_Build (%s)") : _("_Build"), module
);
1828 g_object_set (G_OBJECT (action
), "sensitive", has_file
&& (has_makefile
|| !has_project
),
1829 "label", label
, NULL
);
1832 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1833 "ActionBuildInstallModule");
1834 label
= g_strdup_printf (module
? _("_Install (%s)") : _("_Install"), module
);
1835 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
,
1836 "visible", has_project
, "label", label
, NULL
);
1839 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1840 "ActionBuildCleanModule");
1841 label
= g_strdup_printf (module
? _("_Clean (%s)") : _("_Clean"), module
);
1842 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
,
1843 "visible", has_project
, "label", label
, NULL
);
1847 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1848 "ActionBuildCompileFile");
1849 label
= g_strdup_printf (filename
? _("Co_mpile (%s)") : _("Co_mpile"), filename
);
1850 g_object_set (G_OBJECT (action
), "sensitive", has_object
,
1851 "label", label
, NULL
);
1859 update_fm_module_ui (BasicAutotoolsPlugin
*bb_plugin
)
1863 gboolean has_file
= FALSE
;
1864 gboolean has_makefile
= FALSE
;
1865 gboolean has_project
= TRUE
;
1866 gboolean has_object
= FALSE
;
1867 gboolean is_directory
= FALSE
;
1869 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin
)->shell
, NULL
);
1871 has_file
= bb_plugin
->fm_current_file
!= NULL
;
1876 mod
= build_module_from_file (bb_plugin
, bb_plugin
->fm_current_file
, NULL
);
1879 has_makefile
= directory_has_makefile (mod
) || directory_has_makefile_am (bb_plugin
, mod
);
1880 g_object_unref (mod
);
1883 is_directory
= g_file_query_file_type (bb_plugin
->fm_current_file
, 0, NULL
) == G_FILE_TYPE_DIRECTORY
;
1886 mod
= build_object_from_file (bb_plugin
, bb_plugin
->fm_current_file
);
1890 g_object_unref (mod
);
1894 has_project
= bb_plugin
->project_root_dir
!= NULL
;
1896 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1897 "ActionPopupBuild");
1898 g_object_set (G_OBJECT (action
), "visible", has_file
&& (has_makefile
|| (!is_directory
&& !has_project
)), NULL
);
1900 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1901 "ActionPopupBuildCompile");
1902 g_object_set (G_OBJECT (action
), "sensitive", has_object
, "visible", !is_directory
, NULL
);
1904 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1905 "ActionPopupBuildBuild");
1906 g_object_set (G_OBJECT (action
), "sensitive", has_file
&& (has_makefile
|| (!is_directory
&& !has_project
)), NULL
);
1908 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1909 "ActionPopupBuildInstall");
1910 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
1912 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1913 "ActionPopupBuildClean");
1914 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
1918 update_pm_module_ui (BasicAutotoolsPlugin
*bb_plugin
)
1922 gboolean has_file
= FALSE
;
1923 gboolean has_makefile
= FALSE
;
1924 gboolean has_project
= TRUE
;
1925 gboolean has_object
= FALSE
;
1926 gboolean is_directory
= FALSE
;
1928 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin
)->shell
, NULL
);
1930 has_file
= bb_plugin
->pm_current_file
!= NULL
;
1935 mod
= build_module_from_file (bb_plugin
, bb_plugin
->pm_current_file
, NULL
);
1938 has_makefile
= directory_has_makefile (mod
) || directory_has_makefile_am (bb_plugin
, mod
);
1939 g_object_unref (mod
);
1942 is_directory
= g_file_query_file_type (bb_plugin
->pm_current_file
, 0, NULL
) == G_FILE_TYPE_DIRECTORY
;
1945 mod
= build_object_from_file (bb_plugin
, bb_plugin
->pm_current_file
);
1949 g_object_unref (mod
);
1953 has_project
= bb_plugin
->project_root_dir
!= NULL
;
1955 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1956 "ActionPopupPMBuild");
1957 g_object_set (G_OBJECT (action
), "visible", has_file
&& (has_makefile
|| !has_project
), NULL
);
1959 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1960 "ActionPopupPMBuildCompile");
1961 g_object_set (G_OBJECT (action
), "sensitive", has_object
, "visible", !is_directory
, NULL
);
1963 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1964 "ActionPopupPMBuildBuild");
1965 g_object_set (G_OBJECT (action
), "sensitive", has_file
&& (has_makefile
|| !has_project
), NULL
);
1967 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1968 "ActionPopupPMBuildInstall");
1969 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
1971 action
= anjuta_ui_get_action (ui
, "ActionGroupPopupBuild",
1972 "ActionPopupPMBuildClean");
1973 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
1978 update_project_ui (BasicAutotoolsPlugin
*bb_plugin
)
1982 gboolean has_makefile
;
1983 gboolean has_project
;
1985 DEBUG_PRINT ("%s", "Updating project UI");
1987 has_project
= bb_plugin
->project_root_dir
!= NULL
;
1988 has_makefile
= has_project
&& (directory_has_makefile (bb_plugin
->project_build_dir
) || directory_has_makefile_am (bb_plugin
, bb_plugin
->project_build_dir
));
1990 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (bb_plugin
)->shell
, NULL
);
1991 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1992 "ActionBuildBuildProject");
1993 g_object_set (G_OBJECT (action
), "sensitive", has_project
, "visible", has_project
, NULL
);
1994 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1995 "ActionBuildInstallProject");
1996 g_object_set (G_OBJECT (action
), "sensitive", has_project
, "visible", has_project
, NULL
);
1997 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
1998 "ActionBuildCleanProject");
1999 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
2000 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
2001 "ActionBuildDistribution");
2002 g_object_set (G_OBJECT (action
), "sensitive", has_project
, "visible", has_project
, NULL
);
2003 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
2004 "ActionBuildConfigure");
2005 g_object_set (G_OBJECT (action
), "sensitive", has_project
, "visible", has_project
, NULL
);
2006 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
2007 "ActionBuildSelectConfiguration");
2008 g_object_set (G_OBJECT (action
), "sensitive", has_project
, "visible", has_project
, NULL
);
2009 action
= anjuta_ui_get_action (ui
, "ActionGroupBuild",
2010 "ActionBuildRemoveConfiguration");
2011 g_object_set (G_OBJECT (action
), "sensitive", has_makefile
, "visible", has_project
, NULL
);
2013 update_module_ui (bb_plugin
);
2017 build_update_configuration_menu (BasicAutotoolsPlugin
*plugin
)
2019 GtkWidget
*submenu
= NULL
;
2020 BuildConfiguration
*cfg
;
2021 BuildConfiguration
*selected
;
2022 GSList
*group
= NULL
;
2024 submenu
= gtk_menu_new ();
2025 selected
= build_configuration_list_get_selected (plugin
->configurations
);
2026 for (cfg
= build_configuration_list_get_first (plugin
->configurations
); cfg
!= NULL
; cfg
= build_configuration_next (cfg
))
2030 item
= gtk_radio_menu_item_new_with_mnemonic (group
, build_configuration_get_translated_name (cfg
));
2031 group
= gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item
));
2032 if (cfg
== selected
)
2034 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item
), TRUE
);
2036 g_object_set_data_full (G_OBJECT (item
), "untranslated_name", g_strdup (build_configuration_get_name (cfg
)), g_free
);
2037 g_signal_connect (G_OBJECT (item
), "toggled", G_CALLBACK (on_select_configuration
), plugin
);
2038 gtk_menu_shell_append (GTK_MENU_SHELL (submenu
), item
);
2040 gtk_menu_item_set_submenu (GTK_MENU_ITEM (plugin
->configuration_menu
), submenu
);
2041 gtk_widget_show_all (submenu
);
2045 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
2046 AnjutaSession
*session
, BasicAutotoolsPlugin
*plugin
)
2048 GList
*configurations
;
2049 BuildConfiguration
*cfg
;
2052 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
2055 configurations
= build_configuration_list_to_string_list (plugin
->configurations
);
2056 anjuta_session_set_string_list (session
, "Build",
2057 "Configuration list",
2059 g_list_foreach (configurations
, (GFunc
)g_free
, NULL
);
2060 g_list_free (configurations
);
2062 cfg
= build_configuration_list_get_selected (plugin
->configurations
);
2065 name
= build_configuration_get_name (cfg
);
2066 anjuta_session_set_string (session
, "Build", "Selected Configuration", name
);
2068 for (cfg
= build_configuration_list_get_first (plugin
->configurations
); cfg
!= NULL
; cfg
= build_configuration_next (cfg
))
2073 key
= g_strconcat("BuildArgs/", build_configuration_get_name (cfg
), NULL
);
2074 anjuta_session_set_string (session
, "Build",
2076 build_configuration_get_args(cfg
));
2079 list
= build_configuration_get_variables (cfg
);
2082 key
= g_strconcat("BuildEnv/", build_configuration_get_name (cfg
), NULL
);
2083 anjuta_session_set_string_list (session
, "Build",
2092 on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
2093 AnjutaSession
*session
, BasicAutotoolsPlugin
*plugin
)
2095 GList
*configurations
;
2097 BuildConfiguration
*cfg
;
2099 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
2102 configurations
= anjuta_session_get_string_list (session
, "Build",
2103 "Configuration list");
2105 build_configuration_list_from_string_list (plugin
->configurations
, configurations
);
2106 g_list_foreach (configurations
, (GFunc
)g_free
, NULL
);
2107 g_list_free (configurations
);
2109 selected
= anjuta_session_get_string (session
, "Build", "Selected Configuration");
2110 build_configuration_list_select (plugin
->configurations
, selected
);
2113 for (cfg
= build_configuration_list_get_first (plugin
->configurations
); cfg
!= NULL
; cfg
= build_configuration_next (cfg
))
2119 key
= g_strconcat("BuildArgs/", build_configuration_get_name (cfg
), NULL
);
2120 args
= anjuta_session_get_string (session
, "Build", key
);
2124 build_configuration_set_args (cfg
, args
);
2128 key
= g_strconcat("BuildEnv/", build_configuration_get_name (cfg
), NULL
);
2129 env
= anjuta_session_get_string_list (session
, "Build", key
);
2135 /* New variables are added at the beginning of the list */
2136 for (item
= env
; item
!= NULL
; item
= g_list_next (item
))
2138 build_configuration_set_variable (cfg
, (gchar
*)item
->data
);
2139 g_free (item
->data
);
2146 build_project_configured (G_OBJECT (plugin
), NULL
, NULL
, NULL
);
2150 value_added_fm_current_file (AnjutaPlugin
*plugin
, const char *name
,
2151 const GValue
*value
, gpointer data
)
2153 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2155 if (ba_plugin
->fm_current_file
)
2156 g_object_unref (ba_plugin
->fm_current_file
);
2157 ba_plugin
->fm_current_file
= g_value_dup_object (value
);
2159 update_fm_module_ui (ba_plugin
);
2163 value_removed_fm_current_file (AnjutaPlugin
*plugin
,
2164 const char *name
, gpointer data
)
2166 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2168 if (ba_plugin
->fm_current_file
)
2169 g_object_unref (ba_plugin
->fm_current_file
);
2170 ba_plugin
->fm_current_file
= NULL
;
2172 update_fm_module_ui (ba_plugin
);
2176 value_added_pm_current_uri (AnjutaPlugin
*plugin
, const char *name
,
2177 const GValue
*value
, gpointer data
)
2179 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2182 uri
= g_value_get_string (value
);
2183 if (ba_plugin
->pm_current_file
)
2184 g_object_unref (ba_plugin
->pm_current_file
);
2185 ba_plugin
->pm_current_file
= g_file_new_for_uri (uri
);
2187 update_pm_module_ui (ba_plugin
);
2191 value_removed_pm_current_uri (AnjutaPlugin
*plugin
,
2192 const char *name
, gpointer data
)
2194 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2196 if (ba_plugin
->pm_current_file
)
2197 g_object_unref (ba_plugin
->pm_current_file
);
2198 ba_plugin
->pm_current_file
= NULL
;
2200 update_pm_module_ui (ba_plugin
);
2204 value_added_project_root_uri (AnjutaPlugin
*plugin
, const gchar
*name
,
2205 const GValue
*value
, gpointer user_data
)
2207 BasicAutotoolsPlugin
*bb_plugin
;
2208 const gchar
*root_uri
;
2210 bb_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2212 g_free (bb_plugin
->project_root_dir
);
2213 bb_plugin
->project_root_dir
= NULL
;
2215 root_uri
= g_value_get_string (value
);
2218 bb_plugin
->project_root_dir
= g_file_new_for_uri (root_uri
);
2221 build_configuration_list_set_project_uri (bb_plugin
->configurations
, root_uri
);
2223 /* Export project build uri */
2224 anjuta_shell_add_value (ANJUTA_PLUGIN(plugin
)->shell
,
2225 IANJUTA_BUILDER_ROOT_URI
,
2228 update_project_ui (bb_plugin
);
2232 value_removed_project_root_uri (AnjutaPlugin
*plugin
, const gchar
*name
,
2235 BasicAutotoolsPlugin
*bb_plugin
;
2237 bb_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2239 if (bb_plugin
->project_root_dir
!= NULL
) g_object_unref (bb_plugin
->project_root_dir
);
2240 if (bb_plugin
->project_build_dir
!= NULL
) g_object_unref (bb_plugin
->project_build_dir
);
2241 g_free (bb_plugin
->program_args
);
2243 bb_plugin
->run_in_terminal
= TRUE
;
2244 bb_plugin
->program_args
= NULL
;
2245 bb_plugin
->project_build_dir
= NULL
;
2246 bb_plugin
->project_root_dir
= NULL
;
2248 build_configuration_list_set_project_uri (bb_plugin
->configurations
, NULL
);
2250 /* Export project build uri */
2251 anjuta_shell_remove_value (ANJUTA_PLUGIN (plugin
)->shell
,
2252 IANJUTA_BUILDER_ROOT_URI
, NULL
);
2254 update_project_ui (bb_plugin
);
2258 value_added_project_build_uri (AnjutaPlugin
*plugin
, const gchar
*name
,
2259 const GValue
*value
, gpointer user_data
)
2261 BasicAutotoolsPlugin
*bb_plugin
;
2262 const gchar
*build_uri
;
2264 bb_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2266 if (bb_plugin
->project_build_dir
!= NULL
) g_object_unref (bb_plugin
->project_build_dir
);
2267 bb_plugin
->project_build_dir
= NULL
;
2269 build_uri
= g_value_get_string (value
);
2272 bb_plugin
->project_build_dir
= g_file_new_for_uri (build_uri
);
2274 update_project_ui (bb_plugin
);
2278 on_update_indicators_idle (gpointer data
)
2280 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (data
);
2281 IAnjutaEditor
*editor
= ba_plugin
->current_editor
;
2283 /* If indicators are not yet updated in the editor, do it */
2284 if (ba_plugin
->current_editor_file
&&
2285 IANJUTA_IS_INDICABLE (editor
) &&
2286 g_settings_get_boolean (ba_plugin
->settings
,
2287 PREF_INDICATORS_AUTOMATIC
))
2290 node
= ba_plugin
->contexts_pool
;
2293 BuildContext
*context
= node
->data
;
2294 if (g_hash_table_lookup (context
->indicators_updated_editors
,
2298 ianjuta_indicable_clear (IANJUTA_INDICABLE (editor
), NULL
);
2301 loc_node
= context
->locations
;
2304 build_indicator_location_set ((BuildIndicatorLocation
*) loc_node
->data
,
2305 IANJUTA_EDITOR (editor
), ba_plugin
->current_editor_file
);
2306 loc_node
= g_slist_next (loc_node
);
2308 g_hash_table_insert (context
->indicators_updated_editors
,
2311 node
= g_list_next (node
);
2318 on_editor_destroy (IAnjutaEditor
*editor
, BasicAutotoolsPlugin
*ba_plugin
)
2320 g_hash_table_remove (ba_plugin
->editors_created
, editor
);
2324 on_editor_changed (IAnjutaEditor
*editor
, IAnjutaIterable
*position
,
2325 gboolean added
, gint length
, gint lines
, const gchar
*text
,
2326 BasicAutotoolsPlugin
*ba_plugin
)
2329 IAnjutaIterable
*begin_pos
, *end_pos
;
2330 if (g_hash_table_lookup (ba_plugin
->editors_created
,
2333 line
= ianjuta_editor_get_line_from_position (editor
, position
, NULL
);
2334 begin_pos
= ianjuta_editor_get_line_begin_position (editor
, line
, NULL
);
2335 end_pos
= ianjuta_editor_get_line_end_position (editor
, line
, NULL
);
2336 if (IANJUTA_IS_INDICABLE (editor
))
2338 DEBUG_PRINT ("Clearing indicator on line %d", line
);
2339 ianjuta_indicable_set (IANJUTA_INDICABLE (editor
), begin_pos
,
2340 end_pos
, IANJUTA_INDICABLE_NONE
, NULL
);
2342 DEBUG_PRINT ("Editor changed: line number = %d, added = %d,"
2343 " text length = %d, number of lines = %d",
2344 line
, added
, length
, lines
);
2345 g_object_unref (begin_pos
);
2346 g_object_unref (end_pos
);
2350 value_added_current_editor (AnjutaPlugin
*plugin
, const char *name
,
2351 const GValue
*value
, gpointer data
)
2356 editor
= g_value_get_object (value
);
2358 if (!IANJUTA_IS_EDITOR(editor
))
2361 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2362 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
2364 ba_plugin
->current_editor
= IANJUTA_EDITOR (editor
);
2366 if (g_hash_table_lookup (ba_plugin
->editors_created
,
2367 ba_plugin
->current_editor
) == NULL
)
2369 g_hash_table_insert (ba_plugin
->editors_created
,
2370 ba_plugin
->current_editor
,
2371 ba_plugin
->current_editor
);
2372 g_signal_connect (ba_plugin
->current_editor
, "destroy",
2373 G_CALLBACK (on_editor_destroy
), plugin
);
2374 g_signal_connect (ba_plugin
->current_editor
, "changed",
2375 G_CALLBACK (on_editor_changed
), plugin
);
2378 if (ba_plugin
->current_editor_file
!= NULL
) g_object_unref (ba_plugin
->current_editor_file
);
2379 ba_plugin
->current_editor_file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), NULL
);
2380 update_module_ui (ba_plugin
);
2382 g_idle_add (on_update_indicators_idle
, plugin
);
2386 value_removed_current_editor (AnjutaPlugin
*plugin
,
2387 const char *name
, gpointer data
)
2389 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2391 if (ba_plugin
->indicators_updated_editors
&&
2392 g_hash_table_lookup (ba_plugin
->indicators_updated_editors
,
2393 ba_plugin
->current_editor
))
2395 g_hash_table_remove (ba_plugin
->indicators_updated_editors
,
2396 ba_plugin
->current_editor
);
2399 if (ba_plugin
->current_editor_file
)
2400 g_object_unref (ba_plugin
->current_editor_file
);
2401 ba_plugin
->current_editor_file
= NULL
;
2402 ba_plugin
->current_editor
= NULL
;
2404 update_module_ui (ba_plugin
);
2408 register_stock_icons (AnjutaPlugin
*plugin
)
2410 static gboolean registered
= FALSE
;
2416 BEGIN_REGISTER_ICON (plugin
);
2417 REGISTER_ICON_FULL (ANJUTA_PIXMAP_BUILD
, ANJUTA_STOCK_BUILD
);
2422 activate_plugin (AnjutaPlugin
*plugin
)
2425 static gboolean initialized
= FALSE
;
2426 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2430 register_stock_icons (plugin
);
2432 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
2434 g_signal_connect (plugin
->shell
, "save-session",
2435 G_CALLBACK (on_session_save
),
2437 g_signal_connect (plugin
->shell
, "load-session",
2438 G_CALLBACK (on_session_load
),
2441 /* Add action group */
2442 ba_plugin
->build_action_group
=
2443 anjuta_ui_add_action_group_entries (ui
,
2445 _("Build commands"),
2447 sizeof(build_actions
)/sizeof(GtkActionEntry
),
2448 GETTEXT_PACKAGE
, TRUE
, plugin
);
2449 ba_plugin
->build_popup_action_group
=
2450 anjuta_ui_add_action_group_entries (ui
,
2451 "ActionGroupPopupBuild",
2452 /* Translators: This is a group of build
2453 * commands which appears in pop up menus */
2454 _("Build popup commands"),
2455 build_popup_actions
,
2456 sizeof(build_popup_actions
)/sizeof(GtkActionEntry
),
2457 GETTEXT_PACKAGE
, FALSE
, plugin
);
2459 ba_plugin
->build_merge_id
= anjuta_ui_merge (ui
, UI_FILE
);
2461 ba_plugin
->configuration_menu
= gtk_ui_manager_get_widget (GTK_UI_MANAGER(ui
),
2462 "/MenuMain/PlaceHolderBuildMenus/MenuBuild/SelectConfiguration");
2463 update_project_ui (ba_plugin
);
2466 ba_plugin
->fm_watch_id
=
2467 anjuta_plugin_add_watch (plugin
, IANJUTA_FILE_MANAGER_SELECTED_FILE
,
2468 value_added_fm_current_file
,
2469 value_removed_fm_current_file
, NULL
);
2470 ba_plugin
->pm_watch_id
=
2471 anjuta_plugin_add_watch (plugin
, IANJUTA_PROJECT_MANAGER_CURRENT_URI
,
2472 value_added_pm_current_uri
,
2473 value_removed_pm_current_uri
, NULL
);
2474 ba_plugin
->project_root_watch_id
=
2475 anjuta_plugin_add_watch (plugin
, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
2476 value_added_project_root_uri
,
2477 value_removed_project_root_uri
, NULL
);
2478 ba_plugin
->project_build_watch_id
=
2479 anjuta_plugin_add_watch (plugin
, IANJUTA_BUILDER_ROOT_URI
,
2480 value_added_project_build_uri
,
2482 ba_plugin
->editor_watch_id
=
2483 anjuta_plugin_add_watch (plugin
, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
2484 value_added_current_editor
,
2485 value_removed_current_editor
, NULL
);
2492 deactivate_plugin (AnjutaPlugin
*plugin
)
2495 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (plugin
);
2497 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
2499 g_signal_handlers_disconnect_by_func (plugin
->shell
,
2500 G_CALLBACK (on_session_save
),
2502 g_signal_handlers_disconnect_by_func (plugin
->shell
,
2503 G_CALLBACK (on_session_load
),
2506 /* Remove watches */
2507 anjuta_plugin_remove_watch (plugin
, ba_plugin
->fm_watch_id
, TRUE
);
2508 anjuta_plugin_remove_watch (plugin
, ba_plugin
->pm_watch_id
, TRUE
);
2509 anjuta_plugin_remove_watch (plugin
, ba_plugin
->project_root_watch_id
, TRUE
);
2510 anjuta_plugin_remove_watch (plugin
, ba_plugin
->project_build_watch_id
, TRUE
);
2511 anjuta_plugin_remove_watch (plugin
, ba_plugin
->editor_watch_id
, TRUE
);
2514 anjuta_ui_unmerge (ui
, ba_plugin
->build_merge_id
);
2516 /* Remove action group */
2517 anjuta_ui_remove_action_group (ui
, ba_plugin
->build_action_group
);
2518 anjuta_ui_remove_action_group (ui
, ba_plugin
->build_popup_action_group
);
2523 dispose (GObject
*obj
)
2525 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (obj
);
2527 g_object_unref (ba_plugin
->settings
);
2529 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
2533 finalize (GObject
*obj
)
2536 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (obj
);
2538 for (i
= 0; i
< IANJUTA_BUILDABLE_N_COMMANDS
; i
++)
2540 g_free (ba_plugin
->commands
[i
]);
2541 ba_plugin
->commands
[i
] = NULL
;
2544 if (ba_plugin
->fm_current_file
!= NULL
) g_object_unref (ba_plugin
->fm_current_file
);
2545 if (ba_plugin
->pm_current_file
!= NULL
) g_object_unref (ba_plugin
->pm_current_file
);
2546 if (ba_plugin
->current_editor_file
!= NULL
) g_object_unref (ba_plugin
->current_editor_file
);
2547 if (ba_plugin
->project_root_dir
!= NULL
) g_object_unref (ba_plugin
->project_root_dir
);
2548 if (ba_plugin
->project_build_dir
!= NULL
) g_object_unref (ba_plugin
->project_build_dir
);
2549 g_free (ba_plugin
->program_args
);
2550 build_configuration_list_free (ba_plugin
->configurations
);
2552 ba_plugin
->fm_current_file
= NULL
;
2553 ba_plugin
->pm_current_file
= NULL
;
2554 ba_plugin
->current_editor_file
= NULL
;
2555 ba_plugin
->project_root_dir
= NULL
;
2556 ba_plugin
->project_build_dir
= NULL
;
2557 ba_plugin
->program_args
= NULL
;
2558 ba_plugin
->configurations
= NULL
;
2560 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
2564 basic_autotools_plugin_instance_init (GObject
*obj
)
2567 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (obj
);
2569 for (i
= 0; i
< IANJUTA_BUILDABLE_N_COMMANDS
; i
++)
2570 ba_plugin
->commands
[i
] = NULL
;
2572 ba_plugin
->fm_current_file
= NULL
;
2573 ba_plugin
->pm_current_file
= NULL
;
2574 ba_plugin
->current_editor_file
= NULL
;
2575 ba_plugin
->project_root_dir
= NULL
;
2576 ba_plugin
->project_build_dir
= NULL
;
2577 ba_plugin
->current_editor
= NULL
;
2578 ba_plugin
->contexts_pool
= NULL
;
2579 ba_plugin
->configurations
= build_configuration_list_new ();
2580 ba_plugin
->program_args
= NULL
;
2581 ba_plugin
->run_in_terminal
= TRUE
;
2582 ba_plugin
->last_exec_uri
= NULL
;
2583 ba_plugin
->editors_created
= g_hash_table_new (g_direct_hash
,
2585 ba_plugin
->settings
= g_settings_new (PREF_SCHEMA
);
2589 basic_autotools_plugin_class_init (GObjectClass
*klass
)
2591 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
2593 parent_class
= g_type_class_peek_parent (klass
);
2595 plugin_class
->activate
= activate_plugin
;
2596 plugin_class
->deactivate
= deactivate_plugin
;
2597 klass
->dispose
= dispose
;
2598 klass
->finalize
= finalize
;
2602 /* IAnjutaBuildable implementation
2603 *---------------------------------------------------------------------------*/
2606 ibuildable_set_command (IAnjutaBuildable
*manager
,
2607 IAnjutaBuildableCommand command_id
,
2608 const gchar
*command_override
, GError
**err
)
2610 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2611 if (plugin
->commands
[command_id
])
2612 g_free (plugin
->commands
[command_id
]);
2613 plugin
->commands
[command_id
] = g_strdup (command_override
);
2617 ibuildable_reset_commands (IAnjutaBuildable
*manager
, GError
**err
)
2620 BasicAutotoolsPlugin
*ba_plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2622 for (i
= 0; i
< IANJUTA_BUILDABLE_N_COMMANDS
; i
++)
2624 g_free (ba_plugin
->commands
[i
]);
2625 ba_plugin
->commands
[i
] = NULL
;
2629 static const gchar
*
2630 ibuildable_get_command (IAnjutaBuildable
*manager
,
2631 IAnjutaBuildableCommand command_id
,
2634 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2635 return plugin
->commands
[command_id
];
2639 ibuildable_build (IAnjutaBuildable
*manager
, const gchar
*directory
,
2642 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2645 file
= g_file_new_for_path (directory
);
2646 if (file
== NULL
) return;
2648 build_build_file_or_dir (plugin
, file
, NULL
, NULL
, err
);
2650 g_object_unref (file
);
2654 ibuildable_clean (IAnjutaBuildable
*manager
, const gchar
*directory
,
2657 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2660 file
= g_file_new_for_path (directory
);
2661 if (file
== NULL
) return;
2663 build_clean_dir (plugin
, file
, err
);
2665 g_object_unref (file
);
2669 ibuildable_install (IAnjutaBuildable
*manager
, const gchar
*directory
,
2672 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2675 file
= g_file_new_for_path (directory
);
2676 if (file
== NULL
) return;
2678 build_install_dir (plugin
, file
, NULL
, NULL
, err
);
2680 g_object_unref (file
);
2684 ibuildable_configure (IAnjutaBuildable
*manager
, const gchar
*directory
,
2687 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2690 file
= g_file_new_for_path (directory
);
2691 if (file
== NULL
) return;
2693 build_configure_dir (plugin
, file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
2695 g_object_unref (file
);
2699 ibuildable_generate (IAnjutaBuildable
*manager
, const gchar
*directory
,
2702 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2705 file
= g_file_new_for_path (directory
);
2706 if (file
== NULL
) return;
2708 build_generate_dir (plugin
, file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
2710 g_object_unref (file
);
2714 ibuildable_execute (IAnjutaBuildable
*manager
, const gchar
*uri
,
2717 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (manager
);
2718 if (uri
&& strlen (uri
) > 0)
2719 execute_program (plugin
, uri
);
2721 execute_program (plugin
, NULL
);
2725 ibuildable_iface_init (IAnjutaBuildableIface
*iface
)
2727 /* iface->compile = ibuildable_compile; */
2728 iface
->set_command
= ibuildable_set_command
;
2729 iface
->get_command
= ibuildable_get_command
;
2730 iface
->reset_commands
= ibuildable_reset_commands
;
2731 iface
->build
= ibuildable_build
;
2732 iface
->clean
= ibuildable_clean
;
2733 iface
->install
= ibuildable_install
;
2734 iface
->configure
= ibuildable_configure
;
2735 iface
->generate
= ibuildable_generate
;
2736 iface
->execute
= ibuildable_execute
;
2740 /* IAnjutaFile implementation
2741 *---------------------------------------------------------------------------*/
2744 ifile_open (IAnjutaFile
*manager
, GFile
* file
,
2747 gchar
* uri
= g_file_get_uri (file
);
2748 ianjuta_buildable_execute (IANJUTA_BUILDABLE (manager
), uri
, NULL
);
2753 ifile_get_file (IAnjutaFile
*manager
, GError
**err
)
2755 DEBUG_PRINT ("%s", "Unsupported operation");
2760 ifile_iface_init (IAnjutaFileIface
*iface
)
2762 iface
->open
= ifile_open
;
2763 iface
->get_file
= ifile_get_file
;
2767 /* IAnjutaBuilder implementation
2768 *---------------------------------------------------------------------------*/
2770 static IAnjutaBuilderHandle
2771 ibuilder_is_built (IAnjutaBuilder
*builder
, const gchar
*uri
,
2772 IAnjutaBuilderCallback callback
, gpointer user_data
,
2775 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder
);
2776 BuildContext
*context
;
2779 file
= g_file_new_for_uri (uri
);
2780 if (file
== NULL
) return NULL
;
2782 context
= build_is_file_built (plugin
, file
, callback
, user_data
, err
);
2784 g_object_unref (file
);
2786 return (IAnjutaBuilderHandle
)context
;
2789 static IAnjutaBuilderHandle
2790 ibuilder_build (IAnjutaBuilder
*builder
, const gchar
*uri
,
2791 IAnjutaBuilderCallback callback
, gpointer user_data
,
2794 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder
);
2795 BuildContext
*context
;
2798 file
= g_file_new_for_uri (uri
);
2799 if (file
== NULL
) return NULL
;
2801 context
= build_configure_and_build (plugin
, build_build_file_or_dir
, plugin
->project_root_dir
, callback
, user_data
, NULL
);
2803 g_object_unref (file
);
2805 return (IAnjutaBuilderHandle
)context
;
2809 ibuilder_cancel (IAnjutaBuilder
*builder
, IAnjutaBuilderHandle handle
, GError
**err
)
2811 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder
);
2813 build_cancel_command (plugin
, (BuildContext
*)handle
, err
);
2817 ibuilder_list_configuration (IAnjutaBuilder
*builder
, GError
**err
)
2819 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder
);
2821 return build_list_configuration (plugin
);
2825 ibuilder_get_uri_configuration (IAnjutaBuilder
*builder
, const gchar
*uri
, GError
**err
)
2827 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (builder
);
2829 return build_get_uri_configuration (plugin
, uri
);
2833 ibuilder_iface_init (IAnjutaBuilderIface
*iface
)
2835 iface
->is_built
= ibuilder_is_built
;
2836 iface
->build
= ibuilder_build
;
2837 iface
->cancel
= ibuilder_cancel
;
2838 iface
->list_configuration
= ibuilder_list_configuration
;
2839 iface
->get_uri_configuration
= ibuilder_get_uri_configuration
;
2842 /* IAnjutaPreferences implementation
2843 *---------------------------------------------------------------------------*/
2846 ipreferences_merge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
2848 GtkWidget
*root_check
;
2849 GtkWidget
*make_check
;
2850 GtkWidget
*root_entry
;
2851 GtkWidget
*make_entry
;
2853 BasicAutotoolsPlugin
*plugin
= ANJUTA_PLUGIN_BASIC_AUTOTOOLS (ipref
);
2855 /* Create the preferences page */
2856 bxml
= anjuta_util_builder_new (BUILDER_FILE
, NULL
);
2859 anjuta_util_builder_get_objects (bxml
,
2860 INSTALL_ROOT_CHECK
, &root_check
,
2861 INSTALL_ROOT_ENTRY
, &root_entry
,
2862 PARALLEL_MAKE_CHECK
, &make_check
,
2863 PARALLEL_MAKE_SPIN
, &make_entry
,
2866 g_signal_connect(G_OBJECT(root_check
), "toggled", G_CALLBACK(on_root_check_toggled
), root_entry
);
2867 on_root_check_toggled (root_check
, root_entry
);
2869 g_signal_connect(G_OBJECT(make_check
), "toggled", G_CALLBACK(on_root_check_toggled
), make_entry
);
2870 on_root_check_toggled (make_check
, make_entry
);
2872 anjuta_preferences_add_from_builder (prefs
, bxml
, plugin
->settings
,
2873 BUILD_PREFS_ROOT
, _("Build Autotools"), ICON_FILE
);
2875 g_object_unref (bxml
);
2879 ipreferences_unmerge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
2881 anjuta_preferences_remove_page(prefs
, _("Build Autotools"));
2885 ipreferences_iface_init(IAnjutaPreferencesIface
* iface
)
2887 iface
->merge
= ipreferences_merge
;
2888 iface
->unmerge
= ipreferences_unmerge
;
2891 ANJUTA_PLUGIN_BEGIN (BasicAutotoolsPlugin
, basic_autotools_plugin
);
2892 ANJUTA_PLUGIN_ADD_INTERFACE (ibuilder
, IANJUTA_TYPE_BUILDER
);
2893 ANJUTA_PLUGIN_ADD_INTERFACE (ibuildable
, IANJUTA_TYPE_BUILDABLE
);
2894 ANJUTA_PLUGIN_ADD_INTERFACE (ifile
, IANJUTA_TYPE_FILE
);
2895 ANJUTA_PLUGIN_ADD_INTERFACE (ipreferences
, IANJUTA_TYPE_PREFERENCES
);
2898 ANJUTA_SIMPLE_PLUGIN (BasicAutotoolsPlugin
, basic_autotools_plugin
);