1 /* -*- Mode: C; indent-tabs-mode: nil; 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
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>
46 #include "cpp-packages.h"
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"
71 #define CHDR_SEPARATOR " "
72 #define CHDR_BODY ";\n"
76 #define WIDGETS_DECLARATION_MARKER_PREFIX "/* ANJUTA: Widgets declaration for "
77 #define WIDGETS_DECLARATION_MARKER_SUFFIX " - DO NOT REMOVE */"
79 static gpointer parent_class
;
84 get_filetype (GFile
*file
)
88 gchar
* mime_type
= anjuta_util_get_file_mime_type (file
);
91 if (g_str_equal (mime_type
, "text/x-csrc"))
93 else if (g_str_equal (mime_type
, "text/x-chdr"))
95 else if (g_str_equal (mime_type
, "text/x-c++src"))
97 else if (g_str_equal (mime_type
, "text/x-c++hdr"))
98 return LS_FILE_CPPHDR
;
100 return LS_FILE_OTHER
;
103 return LS_FILE_OTHER
;
107 init_file_type (CppJavaPlugin
* lang_plugin
)
109 GFile
* file
= ianjuta_file_get_file (IANJUTA_FILE (lang_plugin
->current_editor
),
112 lang_plugin
->filetype
= get_filetype (file
);
116 on_glade_drop_possible (IAnjutaEditor
* editor
,
117 IAnjutaIterable
* iterator
,
118 CppJavaPlugin
* lang_plugin
)
120 switch (lang_plugin
->filetype
)
131 language_support_check_param_name (const gchar
* name
,
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
);
147 language_support_get_signal_parameter (const gchar
* type_name
, GList
** names
)
150 const gchar
* param_name
= NULL
;
151 GString
* param_string
;
153 /* Search for the second upper character */
154 for (c
= type_name
+ 1; *c
!= '\0'; c
++)
156 if (g_ascii_isupper (*c
))
162 if (param_name
&& strlen (param_name
))
164 param_string
= g_string_new (param_name
);
165 g_string_ascii_down (param_string
);
169 param_string
= g_string_new ("arg");
171 real_name
= language_support_check_param_name (g_string_free (param_string
, FALSE
), names
);
177 language_support_generate_c_signature (const gchar
* separator
,
181 const gchar
* handler
)
184 GString
* str
= g_string_new ("\n");
185 const gchar
* widget_param
= language_support_get_signal_parameter (widget
,
188 g_string_append (str
, g_type_name (query
.return_type
));
190 g_string_append_printf (str
, "%s%s (%s *%s",
191 separator
, handler
, widget
, widget_param
);
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
,
204 if (query
.param_types
[i
] <= G_TYPE_DOUBLE
)
206 g_string_append_printf (str
, ", %s %s", type_name
, param_name
);
210 g_string_append_printf (str
, ", %s *%s", type_name
, param_name
);
214 g_string_append (str
, ", gpointer user_data)");
216 g_string_append (str
, ")");
218 anjuta_util_glist_strings_free (names
);
223 const gchar
* SOURCE_EXT
[] =
234 const gchar
* HEADER_EXT
[] =
246 language_support_get_header_file (IAnjutaEditor
* editor
)
248 GFile
*file
, *parent
;
249 gchar
*parent_uri
, *basename
, *ext
;
252 file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), 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
, ".");
266 for (i
= 0; SOURCE_EXT
[i
] != NULL
; i
++)
268 if (g_str_equal (ext
, SOURCE_EXT
[i
]))
271 for (j
= 0; HEADER_EXT
[j
] != NULL
; j
++)
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
);
282 if (g_file_query_exists (new_file
, NULL
))
287 g_object_unref (new_file
);
291 if (g_str_equal (ext
, HEADER_EXT
[i
]))
294 for (j
= 0; SOURCE_EXT
[j
] != NULL
; j
++)
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
);
305 if (g_file_query_exists (new_file
, NULL
))
310 g_object_unref (new_file
);
324 static IAnjutaEditor
*
325 language_support_get_editor_from_file (CppJavaPlugin
* lang_plugin
,
328 IAnjutaDocumentManager
*document_manager
= anjuta_shell_get_interface (
329 ANJUTA_PLUGIN (lang_plugin
)->shell
,
330 IAnjutaDocumentManager
,
333 IAnjutaDocument
*document
= ianjuta_document_manager_find_document_with_file
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
),
353 search_start
, search_end
,
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
,
373 IAnjutaSymbolQuery
*symbol_query
= ianjuta_symbol_manager_create_query (
375 IANJUTA_SYMBOL_QUERY_SEARCH_FILE
,
376 IANJUTA_SYMBOL_QUERY_DB_PROJECT
,
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
),
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
);
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
),
409 search_start
, search_end
,
416 g_object_unref (result_start
);
418 prefix_end
= result_end
;
420 ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor
),
422 result_end
, search_end
,
426 suffix_start
= result_start
;
431 g_object_unref (result_end
);
433 return ianjuta_editor_get_text (editor
, prefix_end
, suffix_start
, NULL
);
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 ");
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 */");
455 if (!struct_string
) {
456 g_free (macro_string
);
458 return g_strdup_printf ("%s", C_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
);
473 language_support_get_callback_strings (gchar
** separator
,
477 IAnjutaEditor
* editor
,
478 CppFileType filetype
)
484 *separator
= C_SEPARATOR
;
485 *body
= prepare_callback_body (user_data
, editor
, offset
);
490 *separator
= CHDR_SEPARATOR
;
491 *body
= g_strdup_printf ("%s", CHDR_BODY
);
492 *offset
= CHDR_OFFSET
;
502 static IAnjutaIterable
*
503 language_support_get_header_editor_and_mark (CppJavaPlugin
* lang_plugin
,
504 IAnjutaEditor
* editor
,
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 */
514 *header_editor
= language_support_get_editor_from_file (lang_plugin
,
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
;
527 language_support_add_c_callback (CppJavaPlugin
* lang_plugin
,
528 IAnjutaEditor
* editor
,
529 IAnjutaIterable
* position
,
530 GStrv split_signal_data
,
531 CppFileType filetype
)
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
))
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
,
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
,
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
);
582 g_object_unref (symbol
);
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
);
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
),
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
);
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
,
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
);
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
);
677 generate_widget_member_decl_marker (gchar
* ui_filename
)
679 return g_strdup_printf (WIDGETS_DECLARATION_MARKER_PREFIX
"%s" WIDGETS_DECLARATION_MARKER_SUFFIX
,
684 generate_widget_member_init_marker (gchar
* ui_filename
)
686 return g_strdup_printf ("/* ANJUTA: Widgets initialization for %s - DO NOT REMOVE */", ui_filename
);
690 glade_widget_member_of_scope (gchar
*widget_name
, IAnjutaIterable
*members
)
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) {
699 } while (ianjuta_iterable_next (members
, NULL
));
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
);
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
);
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
);
740 query_members
= ianjuta_symbol_manager_create_query (symbol_manager
,
741 IANJUTA_SYMBOL_QUERY_SEARCH_MEMBERS
,
742 IANJUTA_SYMBOL_QUERY_DB_PROJECT
,
747 IAnjutaIterable
*members
= ianjuta_symbol_query_search_members (
749 IANJUTA_SYMBOL(scope
), NULL
);
750 g_object_unref(query_members
);
754 ret
= glade_widget_member_of_scope (widget_name
, members
);
755 g_object_unref(members
);
759 g_object_unref(scope
);
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
);
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
);
807 on_glade_callback_add (IAnjutaEditor
* editor
,
808 gchar
*widget_typename
,
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
);
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",
837 on_glade_drop (editor
, end
, signal_data
, lang_plugin
);
844 /* Enable/Disable language-support */
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
);
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
,
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
);
873 if (lang_plugin
->support_installed
)
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"))))
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
),
902 g_signal_connect (lang_plugin
->current_editor
,
903 "drop", G_CALLBACK (on_glade_drop
),
907 g_signal_connect (lang_plugin
->current_editor
,
908 "glade-callback-add",
909 G_CALLBACK (on_glade_callback_add
),
912 g_signal_connect (lang_plugin
->current_editor
,
914 G_CALLBACK (on_glade_member_add
),
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
;
925 uninstall_support (CppJavaPlugin
*lang_plugin
)
927 if (!lang_plugin
->support_installed
)
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
),
937 g_signal_handlers_disconnect_by_func (lang_plugin
->current_editor
,
938 G_CALLBACK (on_glade_callback_add
),
941 if (lang_plugin
->packages
)
943 g_object_unref (lang_plugin
->packages
);
944 lang_plugin
->packages
= NULL
;
946 lang_plugin
->support_installed
= FALSE
;
950 on_editor_language_changed (IAnjutaEditor
*editor
,
951 const gchar
*new_language
,
952 CppJavaPlugin
*plugin
)
954 uninstall_support (plugin
);
955 install_support (plugin
);
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
);
969 lang_plugin
->current_editor
= NULL
;
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
),
980 on_value_removed_current_editor (AnjutaPlugin
*plugin
, const gchar
*name
,
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
),
989 if (IANJUTA_IS_EDITOR(lang_plugin
->current_editor
))
990 uninstall_support (lang_plugin
);
991 lang_plugin
->current_editor
= NULL
;
995 on_swap_activate (GtkAction
* action
, gpointer data
)
998 CppJavaPlugin
*lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (data
);
999 IAnjutaDocumentManager
* docman
=
1000 anjuta_shell_get_interface (ANJUTA_PLUGIN(lang_plugin
)->shell
,
1001 IAnjutaDocumentManager
,
1003 if (!lang_plugin
->current_editor
|| !docman
)
1006 file
= language_support_get_header_file (
1007 IANJUTA_EDITOR (lang_plugin
->current_editor
));
1011 ianjuta_document_manager_goto_file_line (docman
,
1015 g_object_unref (file
);
1019 /* Automatic comments */
1022 is_commented_multiline (IAnjutaEditor
*editor
,
1023 IAnjutaIterable
*start
,
1024 IAnjutaIterable
*end
)
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
;
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
;
1044 text
= ianjuta_editor_get_text (editor
, start
, end
, NULL
);
1045 if (g_str_has_suffix (text
, "/*"))
1046 is_commented
= FALSE
;
1050 return is_commented
;
1054 toggle_comment_multiline (IAnjutaEditor
*editor
,
1055 IAnjutaIterable
*start
,
1056 IAnjutaIterable
*end
)
1058 IAnjutaIterable
*start_copy
, *end_copy
;
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
);
1069 ianjuta_editor_erase (editor
, start_copy
, end_copy
, NULL
);
1070 ianjuta_editor_insert (editor
, start_copy
, text
+ 2,
1071 (strlen (text
) - 4), NULL
);
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
);
1085 toggle_comment_singleline (CppJavaPlugin
*plugin
, IAnjutaEditor
*editor
,
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
);
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
);
1126 ianjuta_editor_insert (editor
, end
, "*/", -1, NULL
);
1127 ianjuta_editor_insert (editor
, begin
, "/*", -1, NULL
);
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
);
1141 ianjuta_editor_insert (editor
, begin
, "//", -1, NULL
);
1145 g_object_unref (begin
);
1146 g_object_unref (end
);
1148 g_free (text_stripped
);
1149 g_strfreev (text_diff
);
1154 on_toggle_comment (GtkAction
*action
, gpointer data
)
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
);
1170 IAnjutaIterable
*sel_start
, *sel_end
;
1171 sel_start
= ianjuta_editor_selection_get_start (IANJUTA_EDITOR_SELECTION (editor
),
1173 sel_end
= ianjuta_editor_selection_get_end (IANJUTA_EDITOR_SELECTION (editor
),
1175 toggle_comment_multiline (editor
, sel_start
, sel_end
);
1176 g_object_unref (sel_start
);
1177 g_object_unref (sel_end
);
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
);
1189 static GtkActionEntry actions
[] = {
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
)
1204 N_("Swap .h/.c"), NULL
,
1205 N_("Swap C header and source files"),
1206 G_CALLBACK (on_swap_activate
)
1211 register_stock_icons (AnjutaPlugin
*plugin
)
1213 static gboolean registered
= FALSE
;
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
);
1227 cpp_java_plugin_activate_plugin (AnjutaPlugin
*plugin
)
1230 CppJavaPlugin
*lang_plugin
;
1231 static gboolean initialized
= FALSE
;
1233 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1235 DEBUG_PRINT ("%s", "AnjutaLanguageCppJavaPlugin: Activating plugin ...");
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"),
1247 G_N_ELEMENTS (actions
),
1248 GETTEXT_PACKAGE
, TRUE
,
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
,
1259 initialized
= FALSE
;
1264 cpp_java_plugin_deactivate_plugin (AnjutaPlugin
*plugin
)
1267 CppJavaPlugin
*lang_plugin
;
1268 lang_plugin
= ANJUTA_PLUGIN_CPP_JAVA (plugin
);
1270 anjuta_plugin_remove_watch (plugin
,
1271 lang_plugin
->editor_watch_id
,
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.");
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
);
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
);
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;
1313 plugin
->settings
= g_settings_new (PREF_SCHEMA
);
1314 plugin
->packages
= NULL
;
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"
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);
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
,
1349 g_free (user_packages
);
1350 g_list_free (packages
);
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
),
1367 anjuta_pkg_config_chooser_show_active_only (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
1369 cpp_java_plugin_select_user_packages (plugin
, ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
));
1370 cpp_packages_load (plugin
->packages
, TRUE
);
1374 anjuta_pkg_config_chooser_set_active_packages (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
1376 anjuta_pkg_config_chooser_show_active_only (ANJUTA_PKG_CONFIG_CHOOSER (pkg_config
),
1382 cpp_java_plugin_update_user_packages (CppJavaPlugin
* plugin
,
1383 AnjutaPkgConfigChooser
* chooser
)
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
,
1399 g_string_free (pkg_string
, TRUE
);
1403 on_package_activated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
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
);
1417 on_package_deactivated (AnjutaPkgConfigChooser
*self
, const gchar
* package
,
1420 CppJavaPlugin
* plugin
;
1421 IAnjutaSymbolManager
*isymbol_manager
;
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
,
1431 version
= anjuta_pkg_config_get_version (package
);
1434 ianjuta_symbol_manager_deactivate_package (isymbol_manager
,
1441 cpp_java_plugin_update_user_packages (plugin
, self
);
1445 ipreferences_merge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
1448 GError
* error
= NULL
;
1449 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
1450 plugin
->bxml
= gtk_builder_new ();
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++)"),
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
),
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
),
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
);
1487 ipreferences_unmerge (IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
,
1490 CppJavaPlugin
* plugin
= ANJUTA_PLUGIN_CPP_JAVA (ipref
);
1491 anjuta_preferences_remove_page(prefs
, _("API Tags (C/C++)"));
1492 g_object_unref (plugin
->bxml
);
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
);
1506 ANJUTA_SIMPLE_PLUGIN (CppJavaPlugin
, cpp_java_plugin
);