message-view: bgo #727634 - Cannot copy build output
[anjuta.git] / plugins / language-support-cpp-java / plugin.c
blobc31b4a61049edbc441ae4ad3891dd5a9c1e42693
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
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
21 #include <config.h>
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <libanjuta/anjuta-shell.h>
25 #include <libanjuta/anjuta-debug.h>
26 #include <libanjuta/anjuta-pkg-config-chooser.h>
27 #include <libanjuta/anjuta-pkg-config.h>
28 #include <libanjuta/interfaces/ianjuta-iterable.h>
29 #include <libanjuta/interfaces/ianjuta-document.h>
30 #include <libanjuta/interfaces/ianjuta-document-manager.h>
31 #include <libanjuta/interfaces/ianjuta-editor.h>
32 #include <libanjuta/interfaces/ianjuta-file.h>
33 #include <libanjuta/interfaces/ianjuta-editor-cell.h>
34 #include <libanjuta/interfaces/ianjuta-editor-language.h>
35 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
36 #include <libanjuta/interfaces/ianjuta-editor-glade-signal.h>
37 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
38 #include <libanjuta/interfaces/ianjuta-editor-search.h>
39 #include <libanjuta/interfaces/ianjuta-preferences.h>
40 #include <libanjuta/interfaces/ianjuta-symbol.h>
41 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
42 #include <libanjuta/interfaces/ianjuta-language.h>
43 #include <libanjuta/interfaces/ianjuta-glade.h>
45 #include "plugin.h"
46 #include "cpp-packages.h"
49 /* Pixmaps */
50 #define ANJUTA_PIXMAP_SWAP "anjuta-swap"
51 #define ANJUTA_PIXMAP_AUTOINDENT "anjuta-indent-auto"
52 #define ANJUTA_STOCK_SWAP "anjuta-swap"
53 #define ANJUTA_STOCK_AUTOINDENT "anjuta-indent"
54 #define ANJUTA_STOCK_COMMENT "anjuta-comment"
56 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-language-support-cpp-java.xml"
57 #define PREFS_BUILDER PACKAGE_DATA_DIR"/glade/anjuta-language-cpp-java.ui"
58 #define ICON_FILE "anjuta-language-cpp-java-plugin.png"
60 /* Preferences keys */
61 #define ANJUTA_PREF_SCHEMA_PREFIX "org.gnome.anjuta."
62 #define PREF_SCHEMA "org.gnome.anjuta.plugins.cpp"
63 #define PREF_USER_PACKAGES "user-packages"
64 #define PREF_PROJECT_PACKAGES "load-project-packages"
66 /* Callback generator defines */
67 #define C_SEPARATOR "\n"
68 #define C_BODY "\n{\n\n}\n"
69 #define C_OFFSET 4
71 #define CHDR_SEPARATOR " "
72 #define CHDR_BODY ";\n"
73 #define CHDR_OFFSET 1
75 /* Widgets marker */
76 #define WIDGETS_DECLARATION_MARKER_PREFIX "/* ANJUTA: Widgets declaration for "
77 #define WIDGETS_DECLARATION_MARKER_SUFFIX " - DO NOT REMOVE */"
79 static gpointer parent_class;
81 /* Glade support */
83 static CppFileType
84 get_filetype (GFile *file)
86 if (file)
88 gchar* mime_type = anjuta_util_get_file_mime_type (file);
89 if (mime_type)
91 if (g_str_equal (mime_type, "text/x-csrc"))
92 return LS_FILE_C;
93 else if (g_str_equal (mime_type, "text/x-chdr"))
94 return LS_FILE_CHDR;
95 else if (g_str_equal (mime_type, "text/x-c++src"))
96 return LS_FILE_CPP;
97 else if (g_str_equal (mime_type, "text/x-c++hdr"))
98 return LS_FILE_CPPHDR;
99 else
100 return LS_FILE_OTHER;
103 return LS_FILE_OTHER;
106 static void
107 init_file_type (CppJavaPlugin* lang_plugin)
109 GFile* file = ianjuta_file_get_file (IANJUTA_FILE (lang_plugin->current_editor),
110 NULL);
112 lang_plugin->filetype = get_filetype (file);
115 static gboolean
116 on_glade_drop_possible (IAnjutaEditor* editor,
117 IAnjutaIterable* iterator,
118 CppJavaPlugin* lang_plugin)
120 switch (lang_plugin->filetype)
122 case LS_FILE_C:
123 case LS_FILE_CHDR:
124 return TRUE;
125 default:
126 return FALSE;
130 static gchar*
131 language_support_check_param_name (const gchar* name,
132 GList** names)
134 gint index = 0;
135 GString* real_name = g_string_new (name);
136 while (g_list_find_custom (*names, real_name->str, (GCompareFunc) strcmp))
138 g_string_free (real_name, TRUE);
139 real_name = g_string_new (name);
140 g_string_append_printf (real_name, "%d", ++index);
142 *names = g_list_append (*names, real_name->str);
143 return g_string_free (real_name, FALSE);
146 static const gchar*
147 language_support_get_signal_parameter (const gchar* type_name, GList** names)
149 const gchar* c;
150 const gchar* param_name = NULL;
151 GString* param_string;
152 gchar* real_name;
153 /* Search for the second upper character */
154 for (c = type_name + 1; *c != '\0'; c++)
156 if (g_ascii_isupper (*c))
158 param_name = c;
159 break;
162 if (param_name && strlen (param_name))
164 param_string = g_string_new (param_name);
165 g_string_ascii_down (param_string);
167 else
169 param_string = g_string_new ("arg");
171 real_name = language_support_check_param_name (g_string_free (param_string, FALSE), names);
173 return real_name;
176 static GString*
177 language_support_generate_c_signature (const gchar* separator,
178 const gchar* widget,
179 GSignalQuery query,
180 gboolean swapped,
181 const gchar* handler)
183 GList* names = NULL;
184 GString* str = g_string_new ("\n");
185 const gchar* widget_param = language_support_get_signal_parameter (widget,
186 &names);
187 int i;
188 g_string_append (str, g_type_name (query.return_type));
189 if (!swapped)
190 g_string_append_printf (str, "%s%s (%s *%s",
191 separator, handler, widget, widget_param);
192 else
193 g_string_append_printf (str, "%s%s (gpointer user_data, %s *%s",
194 separator, handler, widget, widget_param);
196 for (i = 0; i < query.n_params; i++)
198 const gchar* type_name = g_type_name (query.param_types[i]);
199 if (!type_name) continue;
201 const gchar* param_name = language_support_get_signal_parameter (type_name,
202 &names);
204 if (query.param_types[i] <= G_TYPE_DOUBLE)
206 g_string_append_printf (str, ", %s %s", type_name, param_name);
208 else
210 g_string_append_printf (str, ", %s *%s", type_name, param_name);
213 if (!swapped)
214 g_string_append (str, ", gpointer user_data)");
215 else
216 g_string_append (str, ")");
218 anjuta_util_glist_strings_free (names);
220 return str;
223 const gchar* SOURCE_EXT[] =
225 ".c",
226 ".cc",
227 ".C",
228 ".cpp",
229 ".cxx",
230 ".ccg",
231 NULL
234 const gchar* HEADER_EXT[] =
236 ".h",
237 ".hh",
238 ".H",
239 ".hpp",
240 ".hxx",
241 ".hg",
242 NULL
245 static GFile*
246 language_support_get_header_file (IAnjutaEditor* editor)
248 GFile *file, *parent;
249 gchar *parent_uri, *basename, *ext;
250 GFile *ret = NULL;
252 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
253 if (!file)
254 return NULL;
256 parent = g_file_get_parent (file);
257 parent_uri = g_file_get_uri (parent);
258 basename = g_file_get_basename (file);
259 g_object_unref (file);
260 g_object_unref (parent);
261 ext = strstr (basename, ".");
263 if (ext)
265 int i;
266 for (i = 0; SOURCE_EXT[i] != NULL; i++)
268 if (g_str_equal (ext, SOURCE_EXT[i]))
270 int j;
271 for (j = 0; HEADER_EXT[j] != NULL; j++)
273 gchar* filename;
274 gchar* uri;
275 GFile* new_file;
276 *ext = '\0';
277 filename = g_strdup_printf ("%s%s", basename, HEADER_EXT[j]);
278 uri = g_build_filename (parent_uri, filename, NULL);
279 new_file = g_file_new_for_uri (uri);
280 g_free (uri);
281 g_free(filename);
282 if (g_file_query_exists (new_file, NULL))
284 ret = new_file;
285 goto end;
287 g_object_unref (new_file);
289 break;
291 if (g_str_equal (ext, HEADER_EXT[i]))
293 int j;
294 for (j = 0; SOURCE_EXT[j] != NULL; j++)
296 gchar* filename;
297 gchar* uri;
298 GFile* new_file;
299 *ext = '\0';
300 filename = g_strdup_printf ("%s%s", basename, SOURCE_EXT[j]);
301 uri = g_build_filename (parent_uri, filename, NULL);
302 new_file = g_file_new_for_uri (uri);
303 g_free (uri);
304 g_free(filename);
305 if (g_file_query_exists (new_file, NULL))
307 ret = new_file;
308 goto end;
310 g_object_unref (new_file);
312 break;
317 end:
318 g_free(basename);
319 g_free (parent_uri);
321 return ret;
324 static IAnjutaEditor*
325 language_support_get_editor_from_file (CppJavaPlugin* lang_plugin,
326 GFile *file)
328 IAnjutaDocumentManager *document_manager = anjuta_shell_get_interface (
329 ANJUTA_PLUGIN (lang_plugin)->shell,
330 IAnjutaDocumentManager,
331 NULL);
333 IAnjutaDocument *document = ianjuta_document_manager_find_document_with_file
334 (document_manager,
335 file,
336 NULL);
338 return IANJUTA_EDITOR (document);
341 static IAnjutaIterable*
342 language_support_get_mark_position (IAnjutaEditor* editor, gchar* mark)
344 IAnjutaEditorCell *search_start = IANJUTA_EDITOR_CELL (
345 ianjuta_editor_get_start_position (editor, NULL));
346 IAnjutaEditorCell *search_end = IANJUTA_EDITOR_CELL (
347 ianjuta_editor_get_end_position (editor, NULL));
348 IAnjutaEditorCell *result_start = NULL;
349 IAnjutaEditorCell *result_end = NULL;
351 ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor),
352 mark, FALSE,
353 search_start, search_end,
354 &result_start,
355 &result_end, NULL);
357 if (result_start)
358 g_object_unref (result_start);
360 return result_end ? IANJUTA_ITERABLE (result_end) : NULL;
363 static IAnjutaIterable*
364 language_support_find_symbol (CppJavaPlugin* lang_plugin,
365 IAnjutaEditor* editor,
366 const gchar* handler)
368 IAnjutaSymbolManager *isymbol_manager = anjuta_shell_get_interface (
369 ANJUTA_PLUGIN (lang_plugin)->shell,
370 IAnjutaSymbolManager,
371 NULL);
373 IAnjutaSymbolQuery *symbol_query = ianjuta_symbol_manager_create_query (
374 isymbol_manager,
375 IANJUTA_SYMBOL_QUERY_SEARCH_FILE,
376 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
377 NULL);
378 IAnjutaSymbolField field = IANJUTA_SYMBOL_FIELD_FILE_POS;
379 ianjuta_symbol_query_set_fields (symbol_query, 1, &field, NULL);
381 GFile* file = ianjuta_file_get_file (IANJUTA_FILE (editor),
382 NULL);
384 IAnjutaIterable *iter = ianjuta_symbol_query_search_file (symbol_query,
385 handler, file, NULL);
387 g_object_unref (file);
388 g_object_unref (symbol_query);
390 return iter;
393 static gchar*
394 get_text_between (IAnjutaEditor *editor, gchar *prefix, gchar *suffix)
396 IAnjutaEditorCell *search_start = IANJUTA_EDITOR_CELL (
397 ianjuta_editor_get_start_position (editor, NULL));
398 IAnjutaEditorCell *search_end = IANJUTA_EDITOR_CELL (
399 ianjuta_editor_get_end_position (editor, NULL));
401 IAnjutaEditorCell *result_start;
402 IAnjutaEditorCell *result_end = NULL;
404 IAnjutaEditorCell *prefix_end;
405 IAnjutaEditorCell *suffix_start;
407 ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor),
408 prefix, FALSE,
409 search_start, search_end,
410 &result_start,
411 &result_end, NULL);
413 if (!result_end)
414 return NULL;
416 g_object_unref (result_start);
418 prefix_end = result_end;
420 ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor),
421 suffix, FALSE,
422 result_end, search_end,
423 &result_start,
424 &result_end, NULL);
426 suffix_start = result_start;
428 if (!result_end)
429 return NULL;
431 g_object_unref (result_end);
433 return ianjuta_editor_get_text (editor, prefix_end, suffix_start, NULL);
436 static gchar*
437 prepare_callback_body (gchar* user_data, IAnjutaEditor* editor, gint *offset)
439 if (g_strcmp0 (user_data, "(null)")) {
440 *offset = C_OFFSET + 1;
441 return g_strdup_printf("\n{\n\tGObject *%s = G_OBJECT (user_data);\n\n}\n", user_data);
444 gchar *macro_string = get_text_between (editor, "/* ANJUTA: Macro ", " gets ");
446 if (!macro_string) {
447 *offset = C_OFFSET;
448 return g_strdup_printf ("%s", C_BODY);
451 gchar *prefix = g_strdup_printf ("/* ANJUTA: Macro %s gets ", macro_string);
452 gchar *struct_string = get_text_between(editor, prefix, " - DO NOT REMOVE */");
453 g_free (prefix);
455 if (!struct_string) {
456 g_free (macro_string);
457 *offset = C_OFFSET;
458 return g_strdup_printf ("%s", C_BODY);
461 gchar *new_body;
462 new_body = g_strdup_printf("\n{\n\t%s *self = %s(user_data);\n\t%sPrivate *priv = self->priv;\n\n}\n",
463 struct_string, macro_string, struct_string);
464 *offset = C_OFFSET + 2;
466 g_free (macro_string);
467 g_free (struct_string);
469 return new_body;
472 static gboolean
473 language_support_get_callback_strings (gchar** separator,
474 gchar** body,
475 gint* offset,
476 gchar* user_data,
477 IAnjutaEditor* editor,
478 CppFileType filetype)
480 switch (filetype)
482 case LS_FILE_C:
484 *separator = C_SEPARATOR;
485 *body = prepare_callback_body (user_data, editor, offset);
486 break;
488 case LS_FILE_CHDR:
490 *separator = CHDR_SEPARATOR;
491 *body = g_strdup_printf ("%s", CHDR_BODY);
492 *offset = CHDR_OFFSET;
493 break;
495 default:
496 return FALSE;
499 return TRUE;
502 static IAnjutaIterable*
503 language_support_get_header_editor_and_mark (CppJavaPlugin* lang_plugin,
504 IAnjutaEditor* editor,
505 gchar* mark,
506 IAnjutaEditor** header_editor)
508 IAnjutaIterable* mark_position = NULL;
509 GFile *header_file = language_support_get_header_file (editor);
511 /* Yes, we have a header */
512 if (header_file)
514 *header_editor = language_support_get_editor_from_file (lang_plugin,
515 header_file);
516 /* We'll now search for the mark */
518 mark_position = language_support_get_mark_position (*header_editor, mark);
520 g_object_unref (header_file);
523 return mark_position;
526 static void
527 language_support_add_c_callback (CppJavaPlugin* lang_plugin,
528 IAnjutaEditor* editor,
529 IAnjutaIterable* position,
530 GStrv split_signal_data,
531 CppFileType filetype)
533 GSignalQuery query;
535 gchar* separator;
536 gchar* body;
537 gint offset;
539 const gchar* widget = split_signal_data[0];
540 const gchar* signal = split_signal_data[1];
541 const gchar* handler = split_signal_data[2];
542 const gchar* user_data = split_signal_data[3];
544 gboolean swapped = g_str_equal (split_signal_data[4], "1");
546 GType type = g_type_from_name (widget);
547 guint id = g_signal_lookup (signal, type);
549 g_signal_query (id, &query);
552 if (!language_support_get_callback_strings (&separator, &body, &offset, user_data, editor, filetype))
553 return;
555 GString* str = language_support_generate_c_signature (separator, widget,
556 query, swapped, handler);
558 g_string_append (str, body);
560 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
561 ianjuta_editor_insert (editor, position,
562 str->str, -1, NULL);
563 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
565 /* Code was inserted, we'll now check if we should add a prototype to the header */
566 if (filetype == LS_FILE_C)
568 IAnjutaEditor* header_editor;
569 IAnjutaIterable* mark_position;
570 mark_position = language_support_get_header_editor_and_mark (lang_plugin,
571 editor,
572 "/* Callbacks */",
573 &header_editor);
574 if (mark_position)
576 /* Check if there's a the prototype to the header */
577 IAnjutaIterable* symbol;
578 symbol = language_support_find_symbol (lang_plugin, header_editor, handler);
580 if (symbol)
582 g_object_unref (symbol);
583 } else {
584 /* Add prototype to the header */
585 language_support_add_c_callback (lang_plugin, header_editor, mark_position,
586 split_signal_data, LS_FILE_CHDR);
587 g_signal_emit_by_name (G_OBJECT (header_editor), "code-changed", NULL, NULL);
590 g_object_unref (mark_position);
594 gchar *string = g_string_free (str, FALSE);
596 /* Emit code-added signal, so symbols will be updated */
597 g_signal_emit_by_name (G_OBJECT (editor), "code-changed", position, string);
599 if (string) g_free (string);
601 /* Body is a bit different form other strings and must be freed */
602 if (body) g_free (body);
604 /* Will now set the caret position offset */
605 ianjuta_editor_goto_line (editor,
606 ianjuta_editor_get_line_from_position (
607 editor, position, NULL) + offset, NULL);
610 static void
611 on_glade_drop (IAnjutaEditor* editor,
612 IAnjutaIterable* iterator,
613 const gchar* signal_data,
614 CppJavaPlugin* lang_plugin)
616 GStrv split_signal_data = g_strsplit(signal_data, ":", 5);
617 char *handler = split_signal_data[2];
619 * Split signal data format:
620 * widget = split_signaldata[0];
621 * signal = split_signaldata[1];
622 * handler = split_signaldata[2];
623 * user_data = split_signaldata[3];
624 * swapped = g_str_equal (split_signaldata[4], "1");
627 IAnjutaIterable *iter;
628 iter = language_support_find_symbol (lang_plugin,
629 IANJUTA_EDITOR (editor),
630 handler);
631 if (iter == NULL)
633 GFile *file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
634 CppFileType filetype = get_filetype (file);
635 language_support_add_c_callback (lang_plugin, editor, iterator, split_signal_data, filetype);
636 } else {
637 /* Symbol found, going there */
638 ianjuta_editor_goto_line (editor, ianjuta_symbol_get_int (
639 IANJUTA_SYMBOL (iter),
640 IANJUTA_SYMBOL_FIELD_FILE_POS,
641 NULL), NULL);
642 g_object_unref (iter);
644 g_strfreev (split_signal_data);
647 static gchar* generate_widget_member_decl_str (gchar* widget_name)
649 return g_strdup_printf ("\n\tGtkWidget* %s;", widget_name);
652 static gchar* generate_widget_member_init_str (gchar* widget_name)
654 return g_strdup_printf ("\n\tpriv->%s = GTK_WIDGET ("
655 "gtk_builder_get_object(builder, \"%s\"));", widget_name, widget_name);
658 static gboolean insert_after_mark (IAnjutaEditor* editor, gchar* mark,
659 gchar* code_to_add, CppJavaPlugin* lang_plugin)
661 IAnjutaIterable* mark_position;
662 mark_position = language_support_get_mark_position (editor, mark);
663 if (!mark_position)
664 return FALSE;
666 ianjuta_editor_insert (editor, mark_position, code_to_add, -1, NULL);
668 /* Emit code-added signal, so symbols will be updated *
669 g_signal_emit_by_name (G_OBJECT (editor), "code-changed", mark_position, code_to_add);*/
671 g_object_unref (mark_position);
673 return TRUE;
676 static gchar*
677 generate_widget_member_decl_marker (gchar* ui_filename)
679 return g_strdup_printf (WIDGETS_DECLARATION_MARKER_PREFIX "%s" WIDGETS_DECLARATION_MARKER_SUFFIX,
680 ui_filename);
683 static gchar*
684 generate_widget_member_init_marker (gchar* ui_filename)
686 return g_strdup_printf ("/* ANJUTA: Widgets initialization for %s - DO NOT REMOVE */", ui_filename);
689 static gboolean
690 glade_widget_member_of_scope (gchar *widget_name, IAnjutaIterable *members)
692 do {
693 IAnjutaSymbol *symbol = IANJUTA_SYMBOL (members);
694 gchar *member_name = ianjuta_symbol_get_string (symbol, IANJUTA_SYMBOL_FIELD_NAME, NULL);
695 /* Checks if member already exists... */
696 if (g_strcmp0 (member_name, widget_name) == 0) {
697 return TRUE;
699 } while (ianjuta_iterable_next (members, NULL));
701 return FALSE;
704 static gboolean
705 glade_widget_already_in_scope (IAnjutaEditor* editor, gchar* widget_name,
706 gchar* mark, CppJavaPlugin* lang_plugin)
708 gboolean ret = FALSE;
709 IAnjutaIterable *mark_position;
710 IAnjutaSymbolQuery *query_scope;
711 IAnjutaIterable *scope;
712 IAnjutaSymbolQuery *query_members;
713 mark_position = language_support_get_mark_position (editor, mark);
715 if (!mark_position)
716 return FALSE;
718 int line = ianjuta_editor_get_line_from_position (editor, mark_position, NULL);
719 g_object_unref(mark_position);
722 IAnjutaSymbolManager *symbol_manager =
723 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin)->shell, IAnjutaSymbolManager, NULL);
725 query_scope = ianjuta_symbol_manager_create_query (symbol_manager,
726 IANJUTA_SYMBOL_QUERY_SEARCH_SCOPE,
727 IANJUTA_SYMBOL_QUERY_DB_PROJECT, NULL);
728 if (!query_scope)
729 return FALSE;
731 GFile *file = ianjuta_file_get_file (IANJUTA_FILE(editor), NULL);
732 gchar* path = g_file_get_path (file);
734 scope = ianjuta_symbol_query_search_scope (query_scope, path, line, NULL);
735 g_object_unref(query_scope);
737 if (!scope)
738 return FALSE;
740 query_members = ianjuta_symbol_manager_create_query (symbol_manager,
741 IANJUTA_SYMBOL_QUERY_SEARCH_MEMBERS,
742 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
743 NULL);
745 if (query_members)
747 IAnjutaIterable *members = ianjuta_symbol_query_search_members (
748 query_members,
749 IANJUTA_SYMBOL(scope), NULL);
750 g_object_unref(query_members);
752 if (members)
754 ret = glade_widget_member_of_scope (widget_name, members);
755 g_object_unref(members);
759 g_object_unref(scope);
761 return ret;
764 static void insert_member_decl_and_init (IAnjutaEditor* editor, gchar* widget_name,
765 gchar* ui_filename, CppJavaPlugin* lang_plugin)
767 AnjutaStatus* status;
768 gchar* member_decl = generate_widget_member_decl_str(widget_name);
769 gchar* member_init = generate_widget_member_init_str(widget_name);
771 gchar* member_decl_marker = generate_widget_member_decl_marker (ui_filename);
772 gchar* member_init_marker = generate_widget_member_init_marker (ui_filename);
774 status = anjuta_shell_get_status (ANJUTA_PLUGIN (lang_plugin)->shell, NULL);
776 if (!glade_widget_already_in_scope (editor, widget_name, member_decl_marker, lang_plugin))
779 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
780 if (insert_after_mark (editor, member_decl_marker, member_decl, lang_plugin))
782 insert_after_mark (editor, member_init_marker, member_init, lang_plugin);
783 g_signal_emit_by_name (G_OBJECT (editor), "code-changed", NULL, NULL);
784 anjuta_status_set (status, _("Code added for widget."));
786 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
789 g_free (member_decl);
790 g_free (member_init);
792 g_free (member_decl_marker);
793 g_free (member_init_marker);
796 static void
797 on_glade_member_add (IAnjutaEditor* editor, gchar* widget_typename,
798 gchar* widget_name, gchar* path, CppJavaPlugin* lang_plugin)
800 GFile* ui_file = g_file_new_for_path (path);
801 gchar* ui_filename = g_file_get_basename (ui_file);
803 insert_member_decl_and_init (editor, widget_name, ui_filename, lang_plugin);
806 static void
807 on_glade_callback_add (IAnjutaEditor* editor,
808 gchar *widget_typename,
809 gchar *signal_name,
810 gchar *handler_name,
811 gchar *object,
812 gboolean swap,
813 gboolean after,
814 gchar* path,
815 CppJavaPlugin* lang_plugin)
817 GFile* ui_file = g_file_new_for_path (path);
818 gchar* ui_filename = g_file_get_basename (ui_file);
820 /* Using marker to search for compatibility */
821 gchar *mark = generate_widget_member_init_marker (ui_filename);
822 IAnjutaIterable* mark_position;
823 mark_position = language_support_get_mark_position (editor, mark);
824 if (mark_position)
826 IAnjutaIterable* end = ianjuta_editor_get_end_position (editor, NULL);
828 /* String format: widgettypename:signalname:handler_name:object:swap:after */
829 gchar *signal_data = g_strdup_printf("%s:%s:%s:%s:%s:%s",
830 widget_typename,
831 signal_name,
832 handler_name,
833 object,
834 swap?"1":"0",
835 after?"1":"0");
837 on_glade_drop (editor, end, signal_data, lang_plugin);
839 g_free(signal_data);
841 g_free(mark);
844 /* Enable/Disable language-support */
845 static void
846 install_support (CppJavaPlugin *lang_plugin)
848 /* Searching for association */
849 gchar *ui_filename = get_text_between (lang_plugin->current_editor,
850 WIDGETS_DECLARATION_MARKER_PREFIX,
851 WIDGETS_DECLARATION_MARKER_SUFFIX);
853 if (ui_filename)
855 GFile *file = ianjuta_file_get_file (IANJUTA_FILE (lang_plugin->current_editor), NULL);
856 gchar *filename = g_file_get_basename (file);
858 IAnjutaGlade *glade = anjuta_shell_get_interface (
859 ANJUTA_PLUGIN (lang_plugin)->shell,
860 IAnjutaGlade,
861 NULL);
863 ianjuta_glade_add_association (glade, ui_filename, filename, NULL);
866 IAnjutaLanguage* lang_manager =
867 anjuta_shell_get_interface (ANJUTA_PLUGIN (lang_plugin)->shell,
868 IAnjutaLanguage, NULL);
870 if (!lang_manager)
871 return;
873 if (lang_plugin->support_installed)
874 return;
876 lang_plugin->current_language =
877 ianjuta_language_get_name_from_editor (lang_manager,
878 IANJUTA_EDITOR_LANGUAGE (lang_plugin->current_editor), NULL);
880 DEBUG_PRINT("Language support installed for: %s",
881 lang_plugin->current_language);
883 if (!(lang_plugin->current_language &&
884 (g_str_equal (lang_plugin->current_language, "C")
885 || g_str_equal (lang_plugin->current_language, "C++")
886 || g_str_equal (lang_plugin->current_language, "Vala")
887 || g_str_equal (lang_plugin->current_language, "Java"))))
889 return;
892 init_file_type (lang_plugin);
894 if (g_str_equal (lang_plugin->current_language, "C" ) ||
895 g_str_equal (lang_plugin->current_language, "C++"))
897 if (IANJUTA_IS_EDITOR_GLADE_SIGNAL (lang_plugin->current_editor))
899 g_signal_connect (lang_plugin->current_editor,
900 "drop-possible", G_CALLBACK (on_glade_drop_possible),
901 lang_plugin);
902 g_signal_connect (lang_plugin->current_editor,
903 "drop", G_CALLBACK (on_glade_drop),
904 lang_plugin);
907 g_signal_connect (lang_plugin->current_editor,
908 "glade-callback-add",
909 G_CALLBACK (on_glade_callback_add),
910 lang_plugin);
912 g_signal_connect (lang_plugin->current_editor,
913 "glade-member-add",
914 G_CALLBACK (on_glade_member_add),
915 lang_plugin);
917 lang_plugin->packages = cpp_packages_new (ANJUTA_PLUGIN (lang_plugin));
918 cpp_packages_load(lang_plugin->packages, FALSE);
921 lang_plugin->support_installed = TRUE;
924 static void
925 uninstall_support (CppJavaPlugin *lang_plugin)
927 if (!lang_plugin->support_installed)
928 return;
930 g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
931 on_glade_drop_possible, lang_plugin);
932 g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
933 on_glade_drop, lang_plugin);
934 g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
935 G_CALLBACK (on_glade_member_add),
936 lang_plugin);
937 g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
938 G_CALLBACK (on_glade_callback_add),
939 lang_plugin);
941 if (lang_plugin->packages)
943 g_object_unref (lang_plugin->packages);
944 lang_plugin->packages = NULL;
946 lang_plugin->support_installed = FALSE;
949 static void
950 on_editor_language_changed (IAnjutaEditor *editor,
951 const gchar *new_language,
952 CppJavaPlugin *plugin)
954 uninstall_support (plugin);
955 install_support (plugin);
958 static void
959 on_value_added_current_editor (AnjutaPlugin *plugin, const gchar *name,
960 const GValue *value, gpointer data)
962 CppJavaPlugin *lang_plugin;
963 IAnjutaDocument* doc = IANJUTA_DOCUMENT(g_value_get_object (value));
964 lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (plugin);
965 if (IANJUTA_IS_EDITOR(doc))
966 lang_plugin->current_editor = G_OBJECT(doc);
967 else
969 lang_plugin->current_editor = NULL;
970 return;
972 if (IANJUTA_IS_EDITOR(lang_plugin->current_editor))
973 install_support (lang_plugin);
974 g_signal_connect (lang_plugin->current_editor, "language-changed",
975 G_CALLBACK (on_editor_language_changed),
976 plugin);
979 static void
980 on_value_removed_current_editor (AnjutaPlugin *plugin, const gchar *name,
981 gpointer data)
983 CppJavaPlugin *lang_plugin;
984 lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (plugin);
985 if (lang_plugin->current_editor)
986 g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
987 G_CALLBACK (on_editor_language_changed),
988 plugin);
989 if (IANJUTA_IS_EDITOR(lang_plugin->current_editor))
990 uninstall_support (lang_plugin);
991 lang_plugin->current_editor = NULL;
994 static void
995 on_swap_activate (GtkAction* action, gpointer data)
997 GFile* file;
998 CppJavaPlugin *lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
999 IAnjutaDocumentManager* docman =
1000 anjuta_shell_get_interface (ANJUTA_PLUGIN(lang_plugin)->shell,
1001 IAnjutaDocumentManager,
1002 NULL);
1003 if (!lang_plugin->current_editor || !docman)
1004 return;
1006 file = language_support_get_header_file (
1007 IANJUTA_EDITOR (lang_plugin->current_editor));
1009 if (file)
1011 ianjuta_document_manager_goto_file_line (docman,
1012 file,
1014 NULL);
1015 g_object_unref (file);
1019 /* Automatic comments */
1021 static gboolean
1022 is_commented_multiline (IAnjutaEditor *editor,
1023 IAnjutaIterable *start,
1024 IAnjutaIterable *end)
1026 gchar *text;
1027 gboolean is_commented = TRUE;
1029 text = ianjuta_editor_get_text (editor, start, end, NULL);
1030 while (is_commented && !g_str_has_prefix (text, "/*"))
1032 if (!ianjuta_iterable_previous (start, NULL))
1033 is_commented = FALSE;
1034 g_free (text);
1035 text = ianjuta_editor_get_text (editor, start, end, NULL);
1036 if (g_str_has_prefix (text, "*/"))
1037 is_commented = FALSE;
1039 while (is_commented && !g_str_has_suffix (text, "*/"))
1041 if (!ianjuta_iterable_next (end, NULL))
1042 is_commented = FALSE;
1043 g_free (text);
1044 text = ianjuta_editor_get_text (editor, start, end, NULL);
1045 if (g_str_has_suffix (text, "/*"))
1046 is_commented = FALSE;
1049 g_free (text);
1050 return is_commented;
1053 static void
1054 toggle_comment_multiline (IAnjutaEditor *editor,
1055 IAnjutaIterable *start,
1056 IAnjutaIterable *end)
1058 IAnjutaIterable *start_copy, *end_copy;
1059 gchar *text;
1060 gboolean is_commented;
1062 start_copy = ianjuta_iterable_clone (start, NULL);
1063 end_copy = ianjuta_iterable_clone (end, NULL);
1064 is_commented = is_commented_multiline (editor, start_copy, end_copy);
1065 text = ianjuta_editor_get_text (editor, start_copy, end_copy, NULL);
1067 if (is_commented)
1069 ianjuta_editor_erase (editor, start_copy, end_copy, NULL);
1070 ianjuta_editor_insert (editor, start_copy, text + 2,
1071 (strlen (text) - 4), NULL);
1073 else
1075 ianjuta_editor_insert (editor, end, "*/", -1, NULL);
1076 ianjuta_editor_insert (editor, start, "/*", -1, NULL);
1079 g_object_unref (start_copy);
1080 g_object_unref (end_copy);
1081 g_free (text);
1084 static void
1085 toggle_comment_singleline (CppJavaPlugin *plugin, IAnjutaEditor *editor,
1086 gint line)
1088 IAnjutaIterable *begin, *end, *begin_copy, *end_copy;
1089 gchar *text, *text_stripped, **text_diff = NULL;
1091 begin = ianjuta_editor_get_line_begin_position (editor, line, NULL);
1092 end = ianjuta_editor_get_line_end_position (editor, line, NULL);
1093 begin_copy = ianjuta_iterable_clone (begin, NULL);
1094 end_copy = ianjuta_iterable_clone (end, NULL);
1096 if (is_commented_multiline (editor, begin_copy, end_copy))
1098 toggle_comment_multiline (editor, begin_copy, end_copy);
1099 g_object_unref (begin);
1100 g_object_unref (end);
1101 g_object_unref (begin_copy);
1102 g_object_unref (end_copy);
1103 return;
1105 g_object_unref (begin_copy);
1106 g_object_unref (end_copy);
1108 text = ianjuta_editor_get_text (editor, begin, end, NULL);
1109 text_stripped = g_strstrip (g_strdup (text));
1110 text_diff = g_strsplit (text, text_stripped, 2);
1112 if (plugin->current_language &&
1113 (g_str_equal (plugin->current_language, "C")))
1115 if (g_str_has_prefix (text_stripped, "/*") &&
1116 g_str_has_suffix (text_stripped, "*/"))
1118 ianjuta_editor_erase (editor, begin, end, NULL);
1119 ianjuta_editor_insert (editor, begin, text_stripped + 2,
1120 (strlen (text_stripped) - 4), NULL);
1121 if (text_diff != NULL)
1122 ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
1124 else
1126 ianjuta_editor_insert (editor, end, "*/", -1, NULL);
1127 ianjuta_editor_insert (editor, begin, "/*", -1, NULL);
1130 else
1132 if (g_str_has_prefix (text_stripped, "//"))
1134 ianjuta_editor_erase (editor, begin, end, NULL);
1135 ianjuta_editor_insert (editor, begin, text_stripped + 2, -1, NULL);
1136 if (text_diff != NULL)
1137 ianjuta_editor_insert (editor, begin, *text_diff, -1, NULL);
1139 else
1141 ianjuta_editor_insert (editor, begin, "//", -1, NULL);
1145 g_object_unref (begin);
1146 g_object_unref (end);
1147 g_free (text);
1148 g_free (text_stripped);
1149 g_strfreev (text_diff);
1153 static void
1154 on_toggle_comment (GtkAction *action, gpointer data)
1156 gint line;
1157 gboolean has_selection;
1159 CppJavaPlugin *lang_plugin;
1160 IAnjutaEditor *editor;
1161 lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
1162 editor = IANJUTA_EDITOR (lang_plugin->current_editor);
1164 ianjuta_document_begin_undo_action (IANJUTA_DOCUMENT(editor), NULL);
1166 has_selection = ianjuta_editor_selection_has_selection
1167 (IANJUTA_EDITOR_SELECTION (editor), NULL);
1168 if (has_selection)
1170 IAnjutaIterable *sel_start, *sel_end;
1171 sel_start = ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor),
1172 NULL);
1173 sel_end = ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor),
1174 NULL);
1175 toggle_comment_multiline (editor, sel_start, sel_end);
1176 g_object_unref (sel_start);
1177 g_object_unref (sel_end);
1179 else
1181 line = ianjuta_editor_get_lineno (IANJUTA_EDITOR(editor), NULL);
1182 toggle_comment_singleline (lang_plugin, editor, line);
1184 ianjuta_document_end_undo_action (IANJUTA_DOCUMENT(editor), NULL);
1187 /* Plugin */
1189 static GtkActionEntry actions[] = {
1191 "ActionMenuEdit",
1192 NULL, N_("_Edit"),
1193 NULL, NULL, NULL
1196 "ActionEditToggleComment",
1197 ANJUTA_STOCK_COMMENT,
1198 N_("Comment/Uncomment"), "<control>m",
1199 N_("Comment or uncomment current selection"),
1200 G_CALLBACK (on_toggle_comment)
1202 { "ActionFileSwap",
1203 ANJUTA_STOCK_SWAP,
1204 N_("Swap .h/.c"), NULL,
1205 N_("Swap C header and source files"),
1206 G_CALLBACK (on_swap_activate)
1210 static void
1211 register_stock_icons (AnjutaPlugin *plugin)
1213 static gboolean registered = FALSE;
1215 if (registered)
1216 return;
1217 registered = TRUE;
1219 /* Register stock icons */
1220 BEGIN_REGISTER_ICON (plugin);
1221 REGISTER_ICON_FULL (ANJUTA_PIXMAP_SWAP, ANJUTA_STOCK_SWAP);
1222 REGISTER_ICON_FULL (ANJUTA_PIXMAP_AUTOINDENT, ANJUTA_STOCK_AUTOINDENT);
1223 END_REGISTER_ICON;
1226 static gboolean
1227 cpp_java_plugin_activate_plugin (AnjutaPlugin *plugin)
1229 AnjutaUI *ui;
1230 CppJavaPlugin *lang_plugin;
1231 static gboolean initialized = FALSE;
1233 lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (plugin);
1235 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Activating plugin ...");
1237 if (!initialized)
1239 register_stock_icons (plugin);
1242 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1243 lang_plugin->action_group =
1244 anjuta_ui_add_action_group_entries (ui, "ActionGroupCppJavaAssist",
1245 _("C++/Java Assistance"),
1246 actions,
1247 G_N_ELEMENTS (actions),
1248 GETTEXT_PACKAGE, TRUE,
1249 plugin);
1250 lang_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
1252 lang_plugin->editor_watch_id =
1253 anjuta_plugin_add_watch (plugin,
1254 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1255 on_value_added_current_editor,
1256 on_value_removed_current_editor,
1257 plugin);
1259 initialized = FALSE;
1260 return TRUE;
1263 static gboolean
1264 cpp_java_plugin_deactivate_plugin (AnjutaPlugin *plugin)
1266 AnjutaUI *ui;
1267 CppJavaPlugin *lang_plugin;
1268 lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (plugin);
1270 anjuta_plugin_remove_watch (plugin,
1271 lang_plugin->editor_watch_id,
1272 TRUE);
1274 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1275 anjuta_ui_unmerge (ui, lang_plugin->uiid);
1276 anjuta_ui_remove_action_group (ui, lang_plugin->action_group);
1278 lang_plugin->action_group = NULL;
1279 lang_plugin->uiid = 0;
1280 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Deactivated plugin.");
1281 return TRUE;
1284 static void
1285 cpp_java_plugin_finalize (GObject *obj)
1287 /* CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (obj); */
1289 /* Finalization codes here */
1290 G_OBJECT_CLASS (parent_class)->finalize (obj);
1293 static void
1294 cpp_java_plugin_dispose (GObject *obj)
1296 CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (obj);
1297 /* Disposition codes */
1299 g_object_unref (plugin->settings);
1301 G_OBJECT_CLASS (parent_class)->dispose (obj);
1304 static void
1305 cpp_java_plugin_instance_init (GObject *obj)
1307 CppJavaPlugin *plugin = ANJUTA_PLUGIN_CPP_JAVA (obj);
1308 plugin->action_group = NULL;
1309 plugin->current_editor = NULL;
1310 plugin->current_language = NULL;
1311 plugin->editor_watch_id = 0;
1312 plugin->uiid = 0;
1313 plugin->settings = g_settings_new (PREF_SCHEMA);
1314 plugin->packages = NULL;
1317 static void
1318 cpp_java_plugin_class_init (GObjectClass *klass)
1320 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1322 parent_class = g_type_class_peek_parent (klass);
1324 plugin_class->activate = cpp_java_plugin_activate_plugin;
1325 plugin_class->deactivate = cpp_java_plugin_deactivate_plugin;
1326 klass->finalize = cpp_java_plugin_finalize;
1327 klass->dispose = cpp_java_plugin_dispose;
1330 #define PREF_WIDGET_PACKAGES "preferences:load-project-packages"
1331 #define PREF_WIDGET_PKG_CONFIG "pkg_config_chooser1"
1333 static void
1334 cpp_java_plugin_select_user_packages (CppJavaPlugin* plugin,
1335 AnjutaPkgConfigChooser* chooser)
1337 gchar* user_packages = g_settings_get_string (plugin->settings,
1338 PREF_USER_PACKAGES);
1339 GStrv pkgs = g_strsplit (user_packages, ";", -1);
1340 gchar** pkg;
1341 GList* packages = NULL;
1342 for (pkg = pkgs; *pkg != NULL; pkg++)
1344 packages = g_list_append (packages, *pkg);
1346 anjuta_pkg_config_chooser_set_active_packages (chooser,
1347 packages);
1348 g_strfreev (pkgs);
1349 g_free (user_packages);
1350 g_list_free (packages);
1353 static void
1354 on_project_packages_toggled (GtkToggleButton* button,
1355 CppJavaPlugin* plugin)
1357 GtkWidget* pkg_config;
1358 gboolean active = gtk_toggle_button_get_active (button);
1359 pkg_config = GTK_WIDGET (gtk_builder_get_object (plugin->bxml, PREF_WIDGET_PKG_CONFIG));
1361 gtk_widget_set_sensitive (pkg_config, !active);
1363 anjuta_pkg_config_chooser_set_active_packages (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config),
1364 NULL);
1365 if (!active)
1367 anjuta_pkg_config_chooser_show_active_only (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config),
1368 FALSE);
1369 cpp_java_plugin_select_user_packages (plugin, ANJUTA_PKG_CONFIG_CHOOSER (pkg_config));
1370 cpp_packages_load (plugin->packages, TRUE);
1372 else
1374 anjuta_pkg_config_chooser_set_active_packages (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config),
1375 NULL);
1376 anjuta_pkg_config_chooser_show_active_only (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config),
1377 TRUE);
1381 static void
1382 cpp_java_plugin_update_user_packages (CppJavaPlugin* plugin,
1383 AnjutaPkgConfigChooser* chooser)
1385 GList* pkg;
1386 GList* packages = anjuta_pkg_config_chooser_get_active_packages (chooser);
1387 GString* pkg_string = g_string_new (NULL);
1389 for (pkg = packages; pkg != NULL; pkg = g_list_next (pkg))
1391 if (strlen (pkg_string->str))
1393 pkg_string = g_string_append_c (pkg_string, ';');
1395 pkg_string = g_string_append (pkg_string, pkg->data);
1397 g_settings_set_string (plugin->settings, PREF_USER_PACKAGES,
1398 pkg_string->str);
1399 g_string_free (pkg_string, TRUE);
1402 static void
1403 on_package_activated (AnjutaPkgConfigChooser *self, const gchar* package,
1404 gpointer data)
1406 CppJavaPlugin* plugin;
1408 plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
1410 g_message ("Activate package");
1412 cpp_java_plugin_update_user_packages (plugin, self);
1413 cpp_packages_load (plugin->packages, TRUE);
1416 static void
1417 on_package_deactivated (AnjutaPkgConfigChooser *self, const gchar* package,
1418 gpointer data)
1420 CppJavaPlugin* plugin;
1421 IAnjutaSymbolManager *isymbol_manager;
1422 gchar* version;
1424 plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
1426 DEBUG_PRINT ("deactivated %s", package);
1428 isymbol_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
1429 IAnjutaSymbolManager,
1430 NULL);
1431 version = anjuta_pkg_config_get_version (package);
1432 if (version)
1434 ianjuta_symbol_manager_deactivate_package (isymbol_manager,
1435 package,
1436 version,
1437 NULL);
1439 g_free (version);
1441 cpp_java_plugin_update_user_packages (plugin, self);
1444 static void
1445 ipreferences_merge (IAnjutaPreferences* ipref, AnjutaPreferences* prefs,
1446 GError** e)
1448 GError* error = NULL;
1449 CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (ipref);
1450 plugin->bxml = gtk_builder_new ();
1451 GtkWidget* toggle;
1452 GtkWidget* pkg_config;
1454 /* Add preferences */
1455 if (!gtk_builder_add_from_file (plugin->bxml, PREFS_BUILDER, &error))
1457 g_warning ("Couldn't load builder file: %s", error->message);
1458 g_error_free (error);
1460 anjuta_preferences_add_from_builder (prefs,
1461 plugin->bxml, plugin->settings,
1462 "preferences", _("API Tags (C/C++)"),
1463 ICON_FILE);
1464 toggle = GTK_WIDGET (gtk_builder_get_object (plugin->bxml, PREF_WIDGET_PACKAGES));
1465 g_signal_connect (toggle, "toggled", G_CALLBACK (on_project_packages_toggled),
1466 plugin);
1467 on_project_packages_toggled (GTK_TOGGLE_BUTTON (toggle), plugin);
1469 pkg_config = GTK_WIDGET (gtk_builder_get_object (plugin->bxml, PREF_WIDGET_PKG_CONFIG));
1470 anjuta_pkg_config_chooser_show_active_column (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config),
1471 TRUE);
1473 g_signal_connect (G_OBJECT (pkg_config), "package-activated",
1474 G_CALLBACK (on_package_activated), plugin);
1476 g_signal_connect (G_OBJECT (pkg_config), "package-deactivated",
1477 G_CALLBACK (on_package_deactivated), plugin);
1479 if (!g_settings_get_boolean (plugin->settings,
1480 PREF_PROJECT_PACKAGES))
1481 cpp_java_plugin_select_user_packages (plugin, ANJUTA_PKG_CONFIG_CHOOSER (pkg_config));
1483 gtk_widget_show (pkg_config);
1486 static void
1487 ipreferences_unmerge (IAnjutaPreferences* ipref, AnjutaPreferences* prefs,
1488 GError** e)
1490 CppJavaPlugin* plugin = ANJUTA_PLUGIN_CPP_JAVA (ipref);
1491 anjuta_preferences_remove_page(prefs, _("API Tags (C/C++)"));
1492 g_object_unref (plugin->bxml);
1495 static void
1496 ipreferences_iface_init (IAnjutaPreferencesIface* iface)
1498 iface->merge = ipreferences_merge;
1499 iface->unmerge = ipreferences_unmerge;
1502 ANJUTA_PLUGIN_BEGIN (CppJavaPlugin, cpp_java_plugin);
1503 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences, IANJUTA_TYPE_PREFERENCES);
1504 ANJUTA_PLUGIN_END;
1506 ANJUTA_SIMPLE_PLUGIN (CppJavaPlugin, cpp_java_plugin);