1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Massimo Cora' 2007-2008 <maxcvs@email.it>
6 * plugin.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
13 * plugin.c is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with plugin.c. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
27 #include <libanjuta/anjuta-shell.h>
28 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/anjuta-utils.h>
30 #include <libanjuta/anjuta-tabber.h>
31 #include <libanjuta/interfaces/ianjuta-document-manager.h>
32 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
33 #include <libanjuta/interfaces/ianjuta-symbol.h>
34 #include <libanjuta/interfaces/ianjuta-project-manager.h>
35 #include <libanjuta/interfaces/ianjuta-file-manager.h>
36 #include <libanjuta/interfaces/ianjuta-file.h>
37 #include <libanjuta/interfaces/ianjuta-file-loader.h>
38 #include <libanjuta/interfaces/ianjuta-editor.h>
39 #include <libanjuta/interfaces/ianjuta-markable.h>
40 #include <libanjuta/interfaces/ianjuta-language.h>
41 #include <libanjuta/interfaces/ianjuta-iterable.h>
42 #include <libanjuta/interfaces/ianjuta-preferences.h>
45 #include "symbol-db-engine.h"
46 #include "symbol-db-prefs.h"
47 #include "symbol-db-views.h"
49 #define ICON_FILE "anjuta-symbol-db-plugin-48.png"
50 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-symbol-db-plugin.xml"
52 #define TIMEOUT_INTERVAL_SYMBOLS_UPDATE 10
53 #define TIMEOUT_SECONDS_AFTER_LAST_TIP 5
55 #define PROJECT_GLOBALS "/"
56 #define SESSION_SECTION "SymbolDB"
57 #define SESSION_KEY "SystemPackages"
59 #define ANJUTA_PIXMAP_GOTO_DECLARATION "element-interface"
60 #define ANJUTA_PIXMAP_GOTO_IMPLEMENTATION "element-method"
62 #define ANJUTA_STOCK_GOTO_DECLARATION "element-interface"
63 #define ANJUTA_STOCK_GOTO_IMPLEMENTATION "element-method"
65 static gpointer parent_class
;
77 TASK_IMPORT_PROJECT
= 1,
78 TASK_IMPORT_PROJECT_AFTER_ABORT
,
86 static unsigned int signals
[LAST_SIGNAL
] = { 0 };
89 register_stock_icons (AnjutaPlugin
*plugin
)
91 static gboolean registered
= FALSE
;
97 /* Register stock icons */
98 BEGIN_REGISTER_ICON (plugin
);
99 REGISTER_ICON (ICON_FILE
, "symbol-db-plugin-icon");
100 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_DECLARATION
, ANJUTA_STOCK_GOTO_DECLARATION
);
101 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_IMPLEMENTATION
, ANJUTA_STOCK_GOTO_IMPLEMENTATION
);
106 goto_file_line (AnjutaPlugin
*plugin
, const gchar
*filename
, gint lineno
)
108 IAnjutaDocumentManager
*docman
;
111 g_return_if_fail (filename
!= NULL
);
113 DEBUG_PRINT ("going to: file %s, line %d", filename
, lineno
);
115 /* Go to file and line number */
116 docman
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaDocumentManager
,
118 file
= g_file_new_for_path (filename
);
119 ianjuta_document_manager_goto_file_line (docman
, file
, lineno
, NULL
);
121 g_object_unref (file
);
124 /* Find an implementation (if impl == TRUE) or declaration (if impl == FALSE)
125 * from the given symbol iterator.
126 * If current_document != NULL it prefers matches from the currently open document
129 find_file_line (IAnjutaIterable
*iterator
, gboolean impl
, const gchar
*current_document
,
137 const gchar
*symbol_kind
;
139 IAnjutaSymbol
*iter_node
= IANJUTA_SYMBOL (iterator
);
141 if (iter_node
== NULL
)
143 /* not found or some error occurred */
147 symbol_kind
= ianjuta_symbol_get_string (iter_node
, IANJUTA_SYMBOL_FIELD_KIND
, NULL
);
148 is_decl
= g_strcmp0 (symbol_kind
, "prototype") == 0 ||
149 g_strcmp0 (symbol_kind
, "interface") == 0;
151 if (is_decl
== !impl
)
155 file
= ianjuta_symbol_get_file (iter_node
, NULL
);
156 /* if the path matches the current document we return immidiately */
157 _path
= g_file_get_path (file
);
158 g_object_unref (file
);
159 if (!current_document
|| g_strcmp0 (_path
, current_document
) == 0)
161 *line
= ianjuta_symbol_get_int (iter_node
,
162 IANJUTA_SYMBOL_FIELD_FILE_POS
,
168 /* we store the first match incase there is no match against the current document */
169 else if (_line
== -1)
172 _line
= ianjuta_symbol_get_int (iter_node
,
173 IANJUTA_SYMBOL_FIELD_FILE_POS
,
181 } while (ianjuta_iterable_next (iterator
, NULL
) == TRUE
);
190 goto_file_tag (SymbolDBPlugin
*sdb_plugin
, const gchar
*word
,
191 gboolean prefer_implementation
)
193 IAnjutaIterable
*iterator
;
197 gboolean found
= FALSE
;
198 SymbolDBEngine
*engine
;
200 for (i
= 0; i
< 2; i
++)
204 engine
= sdb_plugin
->sdbe_project
;
208 engine
= sdb_plugin
->sdbe_globals
;
212 if (symbol_db_engine_is_connected (engine
))
214 iterator
= ianjuta_symbol_query_search (sdb_plugin
->search_query
,
218 if (iterator
!= NULL
&& ianjuta_iterable_get_length (iterator
, NULL
) > 0)
220 gchar
*current_document
= NULL
;
221 /* FIXME: namespaces are not handled here, but they should. */
223 if (IANJUTA_IS_FILE (sdb_plugin
->current_editor
))
227 if ((file
= ianjuta_file_get_file (IANJUTA_FILE (sdb_plugin
->current_editor
),
230 current_document
= g_file_get_path (file
);
231 g_object_unref (file
);
235 path
= find_file_line (iterator
, prefer_implementation
, current_document
, &line
);
239 ianjuta_iterable_first (iterator
, NULL
);
240 path
= find_file_line (iterator
, !prefer_implementation
, current_document
,
246 goto_file_line (ANJUTA_PLUGIN (sdb_plugin
), path
, line
);
251 g_free (current_document
);
255 g_object_unref (iterator
);
257 /* have we found it in the project db? */
264 on_goto_file_tag_impl_activate (GtkAction
*action
, SymbolDBPlugin
*sdb_plugin
)
269 if (sdb_plugin
->current_editor
)
271 ed
= IANJUTA_EDITOR (sdb_plugin
->current_editor
);
272 word
= ianjuta_editor_get_current_word (ed
, NULL
);
275 goto_file_tag (sdb_plugin
, word
, TRUE
);
282 on_goto_file_tag_decl_activate (GtkAction
*action
, SymbolDBPlugin
*sdb_plugin
)
287 if (sdb_plugin
->current_editor
)
289 ed
= IANJUTA_EDITOR (sdb_plugin
->current_editor
);
290 word
= ianjuta_editor_get_current_word (ed
, NULL
);
293 goto_file_tag (sdb_plugin
, word
, FALSE
);
300 on_find_symbol (GtkAction
*action
, SymbolDBPlugin
*sdb_plugin
)
302 anjuta_shell_present_widget(ANJUTA_PLUGIN(sdb_plugin
)->shell
,
303 sdb_plugin
->dbv_main
, NULL
);
305 gtk_notebook_set_current_page (GTK_NOTEBOOK(sdb_plugin
->dbv_notebook
), 2);
306 gtk_widget_grab_focus (GTK_WIDGET (sdb_plugin
->search_entry
));
309 static GtkActionEntry actions
[] =
311 { "ActionMenuGoto", NULL
, N_("_Go to"), NULL
, NULL
, NULL
},
313 "ActionSymbolDBGotoDecl",
314 ANJUTA_STOCK_GOTO_DECLARATION
,
315 N_("Tag De_claration"),
317 N_("Go to symbol declaration"),
318 G_CALLBACK (on_goto_file_tag_decl_activate
)
321 "ActionSymbolDBGotoImpl",
322 ANJUTA_STOCK_GOTO_IMPLEMENTATION
,
323 /* Translators: Go to the line where the tag is implemented */
324 N_("Tag _Implementation"),
326 N_("Go to symbol definition"),
327 G_CALLBACK (on_goto_file_tag_impl_activate
)
331 static GtkActionEntry actions_search
[] = {
333 "ActionEditSearchFindSymbol", GTK_STOCK_FIND
, N_("_Find Symbol…"),
334 "<control>l", N_("Find Symbol"),
335 G_CALLBACK (on_find_symbol
)
340 on_editor_buffer_symbols_update_timeout (gpointer user_data
)
342 SymbolDBPlugin
*sdb_plugin
;
344 gchar
*current_buffer
= NULL
;
345 gsize buffer_size
= 0;
346 gdouble seconds_elapsed
;
349 GPtrArray
*real_files_list
;
350 GPtrArray
*text_buffers
;
351 GPtrArray
*buffer_sizes
;
355 g_return_val_if_fail (user_data
!= NULL
, FALSE
);
357 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
359 if (sdb_plugin
->current_editor
== NULL
)
362 /* check the timer. If it's elapsed enought time since the last time the user
363 * typed in something, than proceed with updating, elsewhere don't do nothing
365 if (sdb_plugin
->update_timer
== NULL
)
368 seconds_elapsed
= g_timer_elapsed (sdb_plugin
->update_timer
, NULL
);
370 if (seconds_elapsed
< TIMEOUT_SECONDS_AFTER_LAST_TIP
)
374 /* we won't proceed with the updating of the symbols if we didn't type in
376 if (sdb_plugin
->need_symbols_update
== FALSE
)
379 if (sdb_plugin
->current_editor
)
381 ed
= IANJUTA_EDITOR (sdb_plugin
->current_editor
);
383 buffer_size
= ianjuta_editor_get_length (ed
, NULL
);
384 current_buffer
= ianjuta_editor_get_text_all (ed
, NULL
);
386 file
= ianjuta_file_get_file (IANJUTA_FILE (ed
), NULL
);
394 /* take the path reference */
395 local_path
= g_file_get_path (file
);
397 /* ok that's good. Let's have a last check: is the current file present
398 * on the buffer_update_files?
400 for (i
= 0; i
< sdb_plugin
->buffer_update_files
->len
; i
++)
402 if (g_strcmp0 (g_ptr_array_index (sdb_plugin
->buffer_update_files
, i
),
405 /* hey we found it */
406 /* something is already scanning this buffer file. Drop the procedure now. */
407 DEBUG_PRINT ("something is already scanning the file %s", local_path
);
412 real_files_list
= g_ptr_array_new_with_free_func (g_free
);
413 g_ptr_array_add (real_files_list
, local_path
);
415 text_buffers
= g_ptr_array_new ();
416 g_ptr_array_add (text_buffers
, current_buffer
);
418 buffer_sizes
= g_ptr_array_new ();
419 g_ptr_array_add (buffer_sizes
, GINT_TO_POINTER (buffer_size
));
423 if (symbol_db_engine_is_connected (sdb_plugin
->sdbe_project
))
425 proc_id
= symbol_db_engine_update_buffer_symbols (sdb_plugin
->sdbe_project
,
426 sdb_plugin
->project_opened
,
434 /* good. All is ready for a buffer scan. Add the file_scan into the arrays */
435 gchar
* local_path_dup
= g_strdup (local_path
);
436 g_ptr_array_add (sdb_plugin
->buffer_update_files
, local_path_dup
);
438 g_ptr_array_add (sdb_plugin
->buffer_update_ids
, GINT_TO_POINTER (proc_id
));
440 /* add a task so that scan_end_manager can manage this */
441 g_tree_insert (sdb_plugin
->proc_id_tree
, GINT_TO_POINTER (proc_id
),
442 GINT_TO_POINTER (TASK_BUFFER_UPDATE
));
445 g_ptr_array_unref (real_files_list
);
446 g_free (current_buffer
);
447 g_object_unref (file
);
449 /* no need to free local_path, it'll be automatically freed later by the buffer_update
452 sdb_plugin
->need_symbols_update
= FALSE
;
454 return proc_id
> 0 ? TRUE
: FALSE
;
458 on_editor_buffer_symbol_update_scan_end (SymbolDBEngine
*dbe
, gint process_id
,
461 SymbolDBPlugin
*sdb_plugin
;
464 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (data
);
466 /* search for the proc id */
467 for (i
= 0; i
< sdb_plugin
->buffer_update_ids
->len
; i
++)
469 if (g_ptr_array_index (sdb_plugin
->buffer_update_ids
, i
) == GINT_TO_POINTER (process_id
))
472 /* hey we found it */
473 /* remove both the items */
474 g_ptr_array_remove_index (sdb_plugin
->buffer_update_ids
, i
);
476 str
= (gchar
*)g_ptr_array_remove_index (sdb_plugin
->buffer_update_files
,
481 /* was the updating of view-locals symbols blocked while we were scanning?
482 * e.g. was the editor switched? */
483 if (sdb_plugin
->buffer_update_semaphore
== TRUE
)
487 gboolean tags_update
;
488 if (!IANJUTA_IS_EDITOR (sdb_plugin
->current_editor
))
491 file
= ianjuta_file_get_file (IANJUTA_FILE (sdb_plugin
->current_editor
),
497 local_path
= g_file_get_path (file
);
499 if (local_path
== NULL
)
501 g_critical ("local_path == NULL");
505 /* add a default timeout to the updating of buffer symbols */
506 tags_update
= anjuta_preferences_get_bool (sdb_plugin
->prefs
, BUFFER_AUTOSCAN
);
510 sdb_plugin
->buf_update_timeout_id
=
511 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE
,
512 on_editor_buffer_symbols_update_timeout
,
517 sdb_plugin
->buffer_update_semaphore
= FALSE
;
522 on_editor_destroy (SymbolDBPlugin
*sdb_plugin
, IAnjutaEditor
*editor
)
525 DEBUG_PRINT ("%s", "on_editor_destroy ()");
526 if (!sdb_plugin
->editor_connected
)
528 DEBUG_PRINT ("%s", "on_editor_destroy (): returning….");
532 uri
= g_hash_table_lookup (sdb_plugin
->editor_connected
, G_OBJECT (editor
));
533 g_hash_table_remove (sdb_plugin
->editor_connected
, G_OBJECT (editor
));
535 if (g_hash_table_size (sdb_plugin
->editor_connected
) <= 0)
537 DEBUG_PRINT ("%s", "displaying nothing…");
538 g_object_set (sdb_plugin
->file_model
, "file-path", NULL
, NULL
);
543 on_editor_update_ui (IAnjutaEditor
*editor
, SymbolDBPlugin
*sdb_plugin
)
545 g_timer_reset (sdb_plugin
->update_timer
);
549 on_char_added (IAnjutaEditor
*editor
, IAnjutaIterable
*position
, gchar ch
,
550 SymbolDBPlugin
*sdb_plugin
)
552 g_timer_reset (sdb_plugin
->update_timer
);
554 /* Update when the user enters a newline */
556 sdb_plugin
->need_symbols_update
= TRUE
;
560 on_editor_saved (IAnjutaEditor
*editor
, GFile
* file
,
561 SymbolDBPlugin
*sdb_plugin
)
563 const gchar
*old_uri
;
564 gchar
*local_filename
;
566 GPtrArray
*files_array
;
570 local_filename
= g_file_get_path (file
);
571 /* Verify that it's local file */
572 g_return_if_fail (local_filename
!= NULL
);
574 saved_uri
= g_file_get_uri (file
);
576 for (i
= 0; i
< sdb_plugin
->buffer_update_files
->len
; i
++)
578 if (g_strcmp0 (g_ptr_array_index (sdb_plugin
->buffer_update_files
, i
),
579 local_filename
) == 0)
581 DEBUG_PRINT ("already scanning");
582 /* something is already scanning this buffer file. Drop the procedure now. */
587 files_array
= g_ptr_array_new();
588 g_ptr_array_add (files_array
, local_filename
);
589 /* no need to free local_filename now */
591 if (!sdb_plugin
->editor_connected
)
594 old_uri
= g_hash_table_lookup (sdb_plugin
->editor_connected
, editor
);
596 if (old_uri
&& strlen (old_uri
) <= 0)
599 /* files_array will be freed once updating has taken place */
601 if (symbol_db_engine_is_connected (sdb_plugin
->sdbe_project
))
603 proc_id
= symbol_db_engine_update_files_symbols (sdb_plugin
->sdbe_project
,
604 sdb_plugin
->project_root_dir
, files_array
, TRUE
);
609 /* add a task so that scan_end_manager can manage this */
610 g_tree_insert (sdb_plugin
->proc_id_tree
, GINT_TO_POINTER (proc_id
),
611 GINT_TO_POINTER (TASK_FILE_UPDATE
));
614 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
615 g_strdup (saved_uri
));
617 /* if we saved it we shouldn't update a second time */
618 sdb_plugin
->need_symbols_update
= FALSE
;
620 on_editor_update_ui (editor
, sdb_plugin
);
625 value_added_current_editor (AnjutaPlugin
*plugin
, const char *name
,
626 const GValue
*value
, gpointer data
)
629 gboolean tags_update
;
633 SymbolDBPlugin
*sdb_plugin
;
635 editor
= g_value_get_object (value
);
636 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
637 if (sdb_plugin
->session_loading
)
642 DEBUG_PRINT ("%s", "Updating symbols");
644 if (!sdb_plugin
->editor_connected
)
646 sdb_plugin
->editor_connected
= g_hash_table_new_full (g_direct_hash
,
650 sdb_plugin
->current_editor
= editor
;
652 if (!IANJUTA_IS_EDITOR (editor
))
655 file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), NULL
);
660 local_path
= g_file_get_path (file
);
661 uri
= g_file_get_uri (file
);
663 if (local_path
== NULL
)
665 g_critical ("local_path == NULL");
669 /* we can have a weird behaviour here if we're not paying the right attention:
670 * A timeout scan could have been launched and a millisecond later the user could
671 * have switched editor: we'll be getting the symbol inserted in the previous
672 * editor into the new one's view.
674 if (sdb_plugin
->buffer_update_files
->len
> 0)
676 sdb_plugin
->buffer_update_semaphore
= TRUE
;
680 g_object_set (sdb_plugin
->file_model
, "file-path", local_path
, NULL
);
682 /* add a default timeout to the updating of buffer symbols */
683 tags_update
= anjuta_preferences_get_bool (sdb_plugin
->prefs
, BUFFER_AUTOSCAN
);
687 sdb_plugin
->buf_update_timeout_id
=
688 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE
,
689 on_editor_buffer_symbols_update_timeout
,
694 if (g_hash_table_lookup (sdb_plugin
->editor_connected
, editor
) == NULL
)
696 g_object_weak_ref (G_OBJECT (editor
),
697 (GWeakNotify
) (on_editor_destroy
),
701 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
706 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
710 g_signal_connect (G_OBJECT (editor
), "saved",
711 G_CALLBACK (on_editor_saved
),
713 g_signal_connect (G_OBJECT (editor
), "char-added",
714 G_CALLBACK (on_char_added
),
716 g_signal_connect (G_OBJECT(editor
), "update_ui",
717 G_CALLBACK (on_editor_update_ui
),
723 sdb_plugin
->need_symbols_update
= FALSE
;
727 on_editor_foreach_disconnect (gpointer key
, gpointer value
, gpointer user_data
)
729 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
730 G_CALLBACK (on_editor_saved
),
732 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
733 G_CALLBACK (on_editor_update_ui
),
735 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
736 G_CALLBACK (on_char_added
),
738 g_object_weak_unref (G_OBJECT(key
),
739 (GWeakNotify
) (on_editor_destroy
),
744 value_removed_current_editor (AnjutaPlugin
*plugin
,
745 const char *name
, gpointer data
)
747 SymbolDBPlugin
*sdb_plugin
;
749 sdb_plugin
= (SymbolDBPlugin
*) plugin
;
751 DEBUG_PRINT ("%s", "value_removed_current_editor ()");
752 /* let's remove the timeout for symbols refresh */
753 if (sdb_plugin
->buf_update_timeout_id
)
754 g_source_remove (sdb_plugin
->buf_update_timeout_id
);
755 sdb_plugin
->buf_update_timeout_id
= 0;
756 sdb_plugin
->need_symbols_update
= FALSE
;
758 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
759 sdb_plugin
->current_editor
= NULL
;
763 * Perform the real add to the db and also checks that no dups are inserted.
764 * Return the real number of files added.
767 do_add_new_files (SymbolDBPlugin
*sdb_plugin
, const GPtrArray
*sources_array
,
770 GPtrArray
* languages_array
= NULL
;
771 GPtrArray
* to_scan_array
= NULL
;
772 GHashTable
* check_unique_file_hash
= NULL
;
773 IAnjutaLanguage
* lang_manager
;
774 AnjutaPlugin
*plugin
;
778 plugin
= ANJUTA_PLUGIN (sdb_plugin
);
780 /* create array of languages and the wannabe scanned files */
781 languages_array
= g_ptr_array_new_with_free_func (g_free
);
782 to_scan_array
= g_ptr_array_new_with_free_func (g_free
);
784 /* to speed the things up we must avoid the dups */
785 check_unique_file_hash
= g_hash_table_new_full (g_str_hash
,
786 g_str_equal
, NULL
, NULL
);
788 lang_manager
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaLanguage
,
793 g_critical ("LanguageManager not found");
797 for (i
=0; i
< sources_array
->len
; i
++)
799 const gchar
*file_mime
;
801 const gchar
*local_filename
;
803 GFileInfo
*gfile_info
;
804 IAnjutaLanguageId lang_id
;
806 if ( (local_filename
= g_ptr_array_index (sources_array
, i
)) == NULL
)
809 if ((gfile
= g_file_new_for_path (local_filename
)) == NULL
)
812 gfile_info
= g_file_query_info (gfile
,
813 "standard::content-type",
814 G_FILE_QUERY_INFO_NONE
,
817 if (gfile_info
== NULL
)
819 g_object_unref (gfile
);
823 /* check if it's already present in the list. This avoids
826 if (g_hash_table_lookup (check_unique_file_hash
,
827 local_filename
) == NULL
)
829 g_hash_table_insert (check_unique_file_hash
,
830 (gpointer
)local_filename
,
831 (gpointer
)local_filename
);
835 /* you're a dup! we don't want you */
839 file_mime
= g_file_info_get_attribute_string (gfile_info
,
840 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
);
842 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
,
847 g_object_unref (gfile
);
848 g_object_unref (gfile_info
);
852 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
854 /* test its existence */
855 if (g_file_test (local_filename
, G_FILE_TEST_EXISTS
) == FALSE
)
857 g_object_unref (gfile
);
858 g_object_unref (gfile_info
);
862 /* ok, we've just tested that the local_filename does exist.
863 * We can safely add it to the array.
865 g_ptr_array_add (languages_array
, g_strdup (lang
));
866 g_ptr_array_add (to_scan_array
, g_strdup (local_filename
));
867 g_object_unref (gfile
);
868 g_object_unref (gfile_info
);
871 /* last but not least check if we had some files in that GPtrArray. It that's not
872 * the case just pass over
874 if (to_scan_array
->len
> 0)
876 gint proc_id
= symbol_db_engine_add_new_files_full_async (sdb_plugin
->sdbe_project
,
877 sdb_plugin
->project_opened
, "1.0", to_scan_array
, languages_array
,
880 /* insert the proc id associated within the task */
881 g_tree_insert (sdb_plugin
->proc_id_tree
, GINT_TO_POINTER (proc_id
),
882 GINT_TO_POINTER (task
));
885 /* get the real added number of files */
886 added_num
= to_scan_array
->len
;
888 g_ptr_array_unref (languages_array
);
889 g_ptr_array_unref (to_scan_array
);
891 g_hash_table_destroy (check_unique_file_hash
);
897 on_project_element_added (IAnjutaProjectManager
*pm
, GFile
*gfile
,
898 SymbolDBPlugin
*sdb_plugin
)
902 GPtrArray
*files_array
;
904 g_return_if_fail (sdb_plugin
->project_root_uri
!= NULL
);
905 g_return_if_fail (sdb_plugin
->project_root_dir
!= NULL
);
907 filename
= g_file_get_path (gfile
);
909 files_array
= g_ptr_array_new_with_free_func (g_free
);
910 g_ptr_array_add (files_array
, filename
);
912 sdb_plugin
->is_adding_element
= TRUE
;
914 /* use a custom function to add the files to db */
915 real_added
= do_add_new_files (sdb_plugin
, files_array
, TASK_ELEMENT_ADDED
);
918 sdb_plugin
->is_adding_element
= FALSE
;
921 g_ptr_array_unref (files_array
);
925 on_project_element_removed (IAnjutaProjectManager
*pm
, GFile
*gfile
,
926 SymbolDBPlugin
*sdb_plugin
)
930 if (!sdb_plugin
->project_root_uri
)
933 filename
= g_file_get_path (gfile
);
937 DEBUG_PRINT ("%s", "on_project_element_removed");
938 symbol_db_engine_remove_file (sdb_plugin
->sdbe_project
,
939 sdb_plugin
->project_root_dir
,
940 symbol_db_util_get_file_db_path (sdb_plugin
->sdbe_project
,
948 on_system_scan_package_start (SymbolDBEngine
*dbe
, guint num_files
,
949 const gchar
*package
, gpointer user_data
)
951 SymbolDBPlugin
*sdb_plugin
;
952 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
954 sdb_plugin
->files_count_system_done
= 0;
955 sdb_plugin
->files_count_system
+= num_files
;
958 /* show the global bar */
959 gtk_widget_show (sdb_plugin
->progress_bar_system
);
960 if (sdb_plugin
->current_scanned_package
!= NULL
)
961 g_free (sdb_plugin
->current_scanned_package
);
962 sdb_plugin
->current_scanned_package
= g_strdup (package
);
964 DEBUG_PRINT ("********************* START [%s] with n %d files ", package
, num_files
);
968 on_system_scan_package_end (SymbolDBEngine
*dbe
, const gchar
*package
,
971 SymbolDBPlugin
*sdb_plugin
;
972 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
974 DEBUG_PRINT ("******************** END () [%s]", package
);
976 /* hide the progress bar */
977 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
979 sdb_plugin
->files_count_system_done
= 0;
980 sdb_plugin
->files_count_system
= 0;
984 on_system_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer data
)
986 AnjutaPlugin
*plugin
;
987 SymbolDBPlugin
*sdb_plugin
;
989 gdouble fraction
= 0;
991 plugin
= ANJUTA_PLUGIN (data
);
992 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
994 sdb_plugin
->files_count_system_done
++;
995 if (sdb_plugin
->files_count_system_done
>= sdb_plugin
->files_count_system
)
997 message
= g_strdup_printf (_("%s: Generating inheritances…"),
998 sdb_plugin
->current_scanned_package
);
1002 message
= g_strdup_printf (_("%s: %d files scanned out of %d"),
1003 sdb_plugin
->current_scanned_package
,
1004 sdb_plugin
->files_count_system_done
,
1005 sdb_plugin
->files_count_system
);
1008 if (sdb_plugin
->files_count_system
> 0)
1010 fraction
= (gdouble
) sdb_plugin
->files_count_system_done
/
1011 (gdouble
) sdb_plugin
->files_count_system
;
1013 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_system
),
1015 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_system
), message
);
1021 on_project_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer data
)
1023 AnjutaPlugin
*plugin
;
1024 SymbolDBPlugin
*sdb_plugin
;
1026 gdouble fraction
= 0;
1028 plugin
= ANJUTA_PLUGIN (data
);
1029 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1031 sdb_plugin
->files_count_project_done
++;
1032 if (sdb_plugin
->files_count_project_done
>= sdb_plugin
->files_count_project
)
1033 message
= g_strdup_printf (_("Generating inheritances…"));
1035 message
= g_strdup_printf (_("%d files scanned out of %d"),
1036 sdb_plugin
->files_count_project_done
, sdb_plugin
->files_count_project
);
1038 if (sdb_plugin
->files_count_project
> 0)
1040 fraction
= (gdouble
) sdb_plugin
->files_count_project_done
/
1041 (gdouble
) sdb_plugin
->files_count_project
;
1045 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
),
1047 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
), message
);
1048 gtk_widget_show (sdb_plugin
->progress_bar_project
);
1053 clear_project_progress_bar (SymbolDBEngine
*dbe
, gpointer data
)
1055 SymbolDBPlugin
*sdb_plugin
;
1057 g_return_if_fail (data
!= NULL
);
1059 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (data
);
1061 /* hide the progress bar */
1062 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
1066 on_check_offline_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer data
)
1068 on_project_single_file_scan_end (dbe
, data
);
1071 /* note the *system* word in the function */
1073 do_import_system_sources_after_abort (SymbolDBPlugin
*sdb_plugin
,
1074 const GPtrArray
*sources_array
)
1076 AnjutaPlugin
*plugin
;
1077 GPtrArray
* languages_array
= NULL
;
1078 GPtrArray
*to_scan_array
= NULL
;
1079 IAnjutaLanguage
* lang_manager
;
1082 plugin
= ANJUTA_PLUGIN (sdb_plugin
);
1084 lang_manager
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaLanguage
,
1087 /* create array of languages */
1088 languages_array
= g_ptr_array_new ();
1089 to_scan_array
= g_ptr_array_new ();
1093 g_critical ("LanguageManager not found");
1097 for (i
=0; i
< sources_array
->len
; i
++)
1099 const gchar
*file_mime
;
1101 const gchar
*local_filename
;
1103 GFileInfo
*gfile_info
;
1104 IAnjutaLanguageId lang_id
;
1106 local_filename
= g_ptr_array_index (sources_array
, i
);
1108 if (local_filename
== NULL
)
1111 gfile
= g_file_new_for_path (local_filename
);
1115 gfile_info
= g_file_query_info (gfile
,
1117 G_FILE_QUERY_INFO_NONE
,
1120 if (gfile_info
== NULL
)
1122 g_object_unref (gfile
);
1126 file_mime
= g_file_info_get_attribute_string (gfile_info
,
1127 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
);
1129 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
,
1134 g_object_unref (gfile
);
1135 g_object_unref (gfile_info
);
1139 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
1141 /* test its existence */
1142 if (g_file_test (local_filename
, G_FILE_TEST_EXISTS
) == FALSE
)
1144 g_object_unref (gfile
);
1145 g_object_unref (gfile_info
);
1149 g_ptr_array_add (languages_array
, g_strdup (lang
));
1150 g_ptr_array_add (to_scan_array
, g_strdup (local_filename
));
1151 g_object_unref (gfile
);
1152 g_object_unref (gfile_info
);
1155 symbol_db_system_parse_aborted_package (sdb_plugin
->sdbs
,
1159 /* no need to free the GPtrArray, Huston. They'll be auto-destroyed in that
1164 /* we assume that sources_array has already unique elements */
1165 /* note the *project* word in the function */
1167 do_import_project_sources_after_abort (AnjutaPlugin
*plugin
,
1168 const GPtrArray
*sources_array
)
1170 SymbolDBPlugin
*sdb_plugin
;
1173 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1175 sdb_plugin
->is_project_importing
= TRUE
;
1177 /* connect to receive signals on single file scan complete. We'll
1178 * update a status bar notifying the user about the status
1180 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "single-file-scan-end",
1181 G_CALLBACK (on_project_single_file_scan_end
), plugin
);
1183 real_added
= do_add_new_files (sdb_plugin
, sources_array
,
1184 TASK_IMPORT_PROJECT_AFTER_ABORT
);
1185 if (real_added
<= 0)
1187 sdb_plugin
->is_project_importing
= FALSE
;
1191 sdb_plugin
->files_count_project
+= real_added
;
1196 do_import_project_sources (AnjutaPlugin
*plugin
, IAnjutaProjectManager
*pm
,
1197 const gchar
*root_dir
)
1199 SymbolDBPlugin
*sdb_plugin
;
1200 GList
* prj_elements_list
;
1201 GPtrArray
* sources_array
;
1205 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1207 prj_elements_list
= ianjuta_project_manager_get_elements (pm
,
1208 ANJUTA_PROJECT_SOURCE
,
1211 if (prj_elements_list
== NULL
)
1213 g_critical ("No sources found within this project");
1217 /* if we're importing first shut off the signal receiving.
1218 * We'll re-enable that on scan-end
1220 sdb_plugin
->is_project_importing
= TRUE
;
1221 DEBUG_PRINT ("Retrieving %d gbf sources of the project…",
1222 g_list_length (prj_elements_list
));
1224 /* create the storage array. The file names will be strdup'd and put here.
1225 * This is just a sort of GList -> GPtrArray conversion.
1227 sources_array
= g_ptr_array_new_with_free_func (g_free
);
1228 for (i
=0; i
< g_list_length (prj_elements_list
); i
++)
1230 gchar
*local_filename
;
1231 GFile
*gfile
= NULL
;
1233 gfile
= g_list_nth_data (prj_elements_list
, i
);
1235 if ((local_filename
= g_file_get_path (gfile
)) == NULL
)
1240 g_ptr_array_add (sources_array
, local_filename
);
1243 /* connect to receive signals on single file scan complete. We'll
1244 * update a status bar notifying the user about the status
1246 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "single-file-scan-end",
1247 G_CALLBACK (on_project_single_file_scan_end
), plugin
);
1249 real_added
= do_add_new_files (sdb_plugin
, sources_array
, TASK_IMPORT_PROJECT
);
1250 if (real_added
<= 0)
1252 sdb_plugin
->is_project_importing
= FALSE
;
1254 sdb_plugin
->files_count_project
+= real_added
;
1257 /* free the ptr array */
1258 g_ptr_array_unref (sources_array
);
1260 /* and the list of project files */
1261 g_list_foreach (prj_elements_list
, (GFunc
) g_object_unref
, NULL
);
1262 g_list_free (prj_elements_list
);
1266 do_import_system_sources (SymbolDBPlugin
*sdb_plugin
)
1268 /* system's packages management */
1269 GList
*item
= sdb_plugin
->session_packages
;
1270 while (item
!= NULL
)
1272 /* the function will take care of checking if the package is already
1273 * scanned and present on db
1275 DEBUG_PRINT ("ianjuta_project_manager_get_packages: package required: %s",
1276 (gchar
*)item
->data
);
1277 symbol_db_system_scan_package (sdb_plugin
->sdbs
, item
->data
);
1282 /* the resume thing */
1283 GPtrArray
*sys_src_array
= NULL
;
1285 symbol_db_util_get_files_with_zero_symbols (sdb_plugin
->sdbe_globals
);
1287 if (sys_src_array
!= NULL
&& sys_src_array
->len
> 0)
1289 do_import_system_sources_after_abort (sdb_plugin
, sys_src_array
);
1291 g_ptr_array_unref (sys_src_array
);
1296 * @return TRUE if a scan is in progress, FALSE elsewhere.
1299 do_update_project_symbols (SymbolDBPlugin
*sdb_plugin
, const gchar
*root_dir
)
1302 /* Update the symbols */
1303 proc_id
= symbol_db_engine_update_project_symbols (sdb_plugin
->sdbe_project
,
1307 sdb_plugin
->is_project_updating
= TRUE
;
1309 /* insert the proc id associated within the task */
1310 g_tree_insert (sdb_plugin
->proc_id_tree
, GINT_TO_POINTER (proc_id
),
1311 GINT_TO_POINTER (TASK_PROJECT_UPDATE
));
1319 * @return TRUE is a scan process is started, FALSE elsewhere.
1322 do_check_offline_files_changed (SymbolDBPlugin
*sdb_plugin
)
1324 GList
* prj_elements_list
;
1325 IAnjutaProjectManager
*pm
;
1326 GHashTable
*prj_elements_hash
;
1327 GPtrArray
*to_add_files
= NULL
;
1329 gint real_added
= 0;
1331 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1332 IAnjutaProjectManager
, NULL
);
1334 prj_elements_list
= ianjuta_project_manager_get_elements (pm
,
1335 ANJUTA_PROJECT_SOURCE
,
1338 /* fill an hash table with all the items of the list just taken.
1339 * We won't g_strdup () the elements because they'll be freed later
1341 prj_elements_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
1344 for (i
= 0; i
< g_list_length (prj_elements_list
); i
++)
1349 gfile
= (GFile
*)g_list_nth_data (prj_elements_list
, i
);
1351 if ((filename
= g_file_get_path (gfile
)) == NULL
||
1352 g_strcmp0 (filename
, "") == 0)
1355 g_object_unref (gfile
);
1359 /* test its existence */
1360 if (g_file_query_exists (gfile
, NULL
) == FALSE
)
1363 g_object_unref (gfile
);
1367 g_hash_table_insert (prj_elements_hash
,
1368 (gpointer
) symbol_db_util_get_file_db_path
1369 (sdb_plugin
->sdbe_project
,
1372 g_object_unref (gfile
);
1376 /* some files may have added/removed editing Makefile.am while
1377 * Anjuta was offline. Check this case too.
1378 * FIXME: Get rid of data model here.
1380 GdaDataModel
*model
=
1381 symbol_db_engine_get_files_for_project (sdb_plugin
->sdbe_project
);
1382 GdaDataModelIter
*it
=
1383 gda_data_model_create_iter (model
);
1385 if (it
&& gda_data_model_iter_move_to_row (it
, 0))
1387 GPtrArray
*remove_array
;
1388 remove_array
= g_ptr_array_new_with_free_func (g_free
);
1390 const GValue
*val
= gda_data_model_iter_get_value_at (it
, 0);
1391 const gchar
* file
= g_value_get_string (val
);
1393 if (file
&& g_hash_table_remove (prj_elements_hash
, file
) == FALSE
)
1394 g_ptr_array_add (remove_array
, g_strdup (file
));
1396 } while (gda_data_model_iter_move_next (it
));
1398 symbol_db_engine_remove_files (sdb_plugin
->sdbe_project
,
1399 sdb_plugin
->project_opened
,
1401 g_ptr_array_unref (remove_array
);
1404 /* great, at this point we should have this situation:
1405 * remove array = files to remove, remaining items in the hash_table = files
1408 to_add_files
= g_ptr_array_new ();
1409 if (g_hash_table_size (prj_elements_hash
) > 0)
1412 GList
*keys
= g_hash_table_get_keys (prj_elements_hash
);
1414 /* get all the nodes from the hash table and add them to the wannabe-added
1417 for (i
= 0; i
< g_hash_table_size (prj_elements_hash
); i
++)
1419 /*DEBUG_PRINT ("ARRAY ADD %s", (gchar*)g_list_nth_data (keys, i));*/
1420 g_ptr_array_add (to_add_files
,
1421 g_hash_table_lookup (prj_elements_hash
,
1422 g_list_nth_data (keys
, i
)));
1426 /* good. Let's go on with add of new files. */
1427 if (to_add_files
->len
> 0)
1429 /* block the signals spreading from engine to local-view tab */
1430 sdb_plugin
->is_offline_scanning
= TRUE
;
1431 real_added
= do_add_new_files (sdb_plugin
, to_add_files
,
1432 TASK_OFFLINE_CHANGES
);
1434 DEBUG_PRINT ("going to do add %d files with TASK_OFFLINE_CHANGES",
1437 if (real_added
<= 0)
1439 sdb_plugin
->is_offline_scanning
= FALSE
;
1442 /* connect to receive signals on single file scan complete. We'll
1443 * update a status bar notifying the user about the status
1445 sdb_plugin
->files_count_project
+= real_added
;
1447 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "single-file-scan-end",
1448 G_CALLBACK (on_check_offline_single_file_scan_end
), ANJUTA_PLUGIN (sdb_plugin
));
1452 g_object_unref (it
);
1453 g_object_unref (model
);
1454 g_ptr_array_unref (to_add_files
);
1455 g_hash_table_destroy (prj_elements_hash
);
1457 return real_added
> 0 ? TRUE
: FALSE
;
1461 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
1462 AnjutaSession
*session
,
1463 SymbolDBPlugin
*sdb_plugin
)
1465 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
1468 DEBUG_PRINT ("%s", "SymbolDB: session_save");
1470 anjuta_session_set_string_list (session
,
1473 sdb_plugin
->session_packages
);
1477 on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
1478 AnjutaSession
*session
,
1479 SymbolDBPlugin
*sdb_plugin
)
1481 IAnjutaProjectManager
*pm
;
1482 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1483 IAnjutaProjectManager
, NULL
);
1485 if (phase
== ANJUTA_SESSION_PHASE_START
)
1487 sdb_plugin
->session_packages
= anjuta_session_get_string_list (session
,
1491 DEBUG_PRINT ("SymbolDB: session_loading started. Getting info from %s",
1492 anjuta_session_get_session_directory (session
));
1493 sdb_plugin
->session_loading
= TRUE
;
1495 if (sdb_plugin
->session_packages
== NULL
)
1497 /* hey, does user want to import system sources for this project? */
1498 gboolean automatic_scan
= anjuta_preferences_get_bool (sdb_plugin
->prefs
,
1501 if (automatic_scan
== TRUE
)
1503 sdb_plugin
->session_packages
= ianjuta_project_manager_get_packages (pm
, NULL
);
1507 /* get preferences about the parallel scan */
1508 gboolean parallel_scan
= anjuta_preferences_get_bool (sdb_plugin
->prefs
,
1511 if (parallel_scan
== TRUE
&&
1512 symbol_db_engine_is_connected (sdb_plugin
->sdbe_globals
) == TRUE
)
1514 /* we simulate a project-import-end signal received */
1515 do_import_system_sources (sdb_plugin
);
1518 else if (phase
== ANJUTA_SESSION_PHASE_END
)
1520 IAnjutaDocumentManager
* docman
;
1521 sdb_plugin
->session_loading
= FALSE
;
1522 DEBUG_PRINT ("SymbolDB: session_loading finished");
1524 /* Show the symbols for the current editor */
1525 docman
= anjuta_shell_get_interface (shell
, IAnjutaDocumentManager
, NULL
);
1528 IAnjutaDocument
* cur_doc
=
1529 ianjuta_document_manager_get_current_document (docman
, NULL
);
1532 GValue value
= {0, };
1533 g_value_init (&value
, G_TYPE_OBJECT
);
1534 g_value_set_object (&value
, cur_doc
);
1535 value_added_current_editor (ANJUTA_PLUGIN (sdb_plugin
),
1536 "document_manager_current_document",
1538 g_value_unset(&value
);
1542 if (sdb_plugin
->project_opened
== NULL
)
1544 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
1545 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
1550 /* add a new project */
1552 on_project_root_added (AnjutaPlugin
*plugin
, const gchar
*name
,
1553 const GValue
*value
, gpointer user_data
)
1555 IAnjutaProjectManager
*pm
;
1556 SymbolDBPlugin
*sdb_plugin
;
1557 const gchar
*root_uri
;
1561 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1564 * The Global System symbols thing
1567 /* is the global db connected? */
1568 if (symbol_db_engine_is_connected (sdb_plugin
->sdbe_globals
) == FALSE
)
1570 gchar
*anjuta_cache_path
;
1571 /* open the connection to global db */
1572 anjuta_cache_path
= anjuta_util_get_user_cache_file_path (".", NULL
);
1573 if (symbol_db_engine_open_db (sdb_plugin
->sdbe_globals
,
1575 PROJECT_GLOBALS
) == DB_OPEN_STATUS_FATAL
)
1577 g_error ("Opening global project under %s", anjuta_cache_path
);
1579 g_free (anjuta_cache_path
);
1581 /* unref and recreate the sdbs object */
1582 if (sdb_plugin
->sdbs
!= NULL
)
1583 g_object_unref (sdb_plugin
->sdbs
);
1585 sdb_plugin
->sdbs
= symbol_db_system_new (sdb_plugin
,
1586 sdb_plugin
->sdbe_globals
);
1589 /* Hide the progress bar. Default system tags thing: we'll import after abort even
1590 * if the preferences says not to automatically scan the packages.
1592 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
1594 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1595 IAnjutaProjectManager
, NULL
);
1601 g_free (sdb_plugin
->project_root_uri
);
1602 sdb_plugin
->project_root_uri
= NULL
;
1603 if ((root_uri
= g_value_get_string (value
)) == NULL
)
1605 DEBUG_PRINT ("Warning, root_uri for project is NULL");
1610 gfile
= g_file_new_for_uri (root_uri
);
1612 root_dir
= g_file_get_path (gfile
);
1613 DEBUG_PRINT ("Symbol-DB: added project root_dir %s, name %s", root_dir
,
1616 g_object_unref (gfile
);
1618 /* FIXME: where's the project name itself? */
1619 DEBUG_PRINT ("FIXME: where's the project name itself? using %s", root_dir
);
1620 sdb_plugin
->project_opened
= g_strdup (root_dir
);
1624 gboolean needs_sources_scan
= FALSE
;
1625 gboolean project_exist
= FALSE
;
1628 /* we'll use the same values for db_directory and project_directory */
1629 DEBUG_PRINT ("Opening db %s and project_dir %s", root_dir
, root_dir
);
1630 gint open_status
= symbol_db_engine_open_db (sdb_plugin
->sdbe_project
, root_dir
,
1633 /* is it a fresh-new project? is it an imported project with
1634 * no 'new' symbol-db database but the 'old' one symbol-browser?
1636 switch (open_status
)
1638 case DB_OPEN_STATUS_FATAL
:
1639 g_error ("*** Error in opening db ***");
1642 case DB_OPEN_STATUS_NORMAL
:
1643 project_exist
= TRUE
;
1646 case DB_OPEN_STATUS_CREATE
:
1647 case DB_OPEN_STATUS_UPGRADE
:
1648 needs_sources_scan
= TRUE
;
1649 project_exist
= FALSE
;
1656 /* if project did not exist add a new project */
1657 if (project_exist
== FALSE
)
1659 DEBUG_PRINT ("Creating new project.");
1660 symbol_db_engine_add_new_project (sdb_plugin
->sdbe_project
,
1661 NULL
, /* still no workspace logic */
1662 sdb_plugin
->project_opened
,
1667 * we need an initial import
1669 if (needs_sources_scan
== TRUE
)
1671 DEBUG_PRINT ("Importing sources.");
1672 do_import_project_sources (plugin
, pm
, root_dir
);
1677 * no import needed. But we may have aborted the scan of sources in
1678 * a previous session..
1680 GPtrArray
*sources_array
= NULL
;
1681 gboolean flag_offline
;
1682 gboolean flag_update
;
1686 symbol_db_util_get_files_with_zero_symbols (sdb_plugin
->sdbe_project
);
1688 if (sources_array
!= NULL
&& sources_array
->len
> 0)
1690 do_import_project_sources_after_abort (plugin
, sources_array
);
1691 g_ptr_array_unref (sources_array
);
1694 /* check for offline changes */
1695 flag_offline
= do_check_offline_files_changed (sdb_plugin
);
1697 /* update any files of the project which isn't up-to-date */
1698 flag_update
= do_update_project_symbols (sdb_plugin
, root_dir
);
1700 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
),
1701 _("Populating symbol database…"));
1702 id
= g_idle_add ((GSourceFunc
) gtk_progress_bar_pulse
,
1703 sdb_plugin
->progress_bar_project
);
1704 gtk_widget_show (sdb_plugin
->progress_bar_project
);
1705 g_source_remove (id
);
1706 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
1709 sdb_plugin
->project_root_dir
= root_dir
;
1712 sdb_plugin
->project_root_uri
= g_strdup (root_uri
);
1714 g_signal_connect (G_OBJECT (pm
), "element_added",
1715 G_CALLBACK (on_project_element_added
), sdb_plugin
);
1716 g_signal_connect (G_OBJECT (pm
), "element_removed",
1717 G_CALLBACK (on_project_element_removed
), sdb_plugin
);
1721 on_project_root_removed (AnjutaPlugin
*plugin
, const gchar
*name
,
1724 IAnjutaProjectManager
*pm
;
1725 SymbolDBPlugin
*sdb_plugin
;
1727 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1728 DEBUG_PRINT ("%s", "project_root_removed ()");
1729 /* Disconnect events from project manager */
1731 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1732 IAnjutaProjectManager
, NULL
);
1733 g_signal_handlers_disconnect_by_func (G_OBJECT (pm
),
1734 on_project_element_added
,
1736 g_signal_handlers_disconnect_by_func (G_OBJECT (pm
),
1737 on_project_element_removed
,
1740 /* don't forget to close the project */
1741 symbol_db_engine_close_db (sdb_plugin
->sdbe_project
);
1743 /* and the globals one */
1744 symbol_db_engine_close_db (sdb_plugin
->sdbe_globals
);
1746 /* stop any opened scanning process */
1747 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_system
), "");
1748 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
), "");
1749 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
1750 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
1752 sdb_plugin
->files_count_system_done
= 0;
1753 sdb_plugin
->files_count_system
= 0;
1755 sdb_plugin
->files_count_project_done
= 0;
1756 sdb_plugin
->files_count_project
= 0;
1759 g_free (sdb_plugin
->project_root_uri
);
1760 g_free (sdb_plugin
->project_root_dir
);
1761 g_free (sdb_plugin
->project_opened
);
1762 sdb_plugin
->project_root_uri
= NULL
;
1763 sdb_plugin
->project_root_dir
= NULL
;
1764 sdb_plugin
->project_opened
= NULL
;
1768 on_scan_end_manager (SymbolDBEngine
*dbe
, gint process_id
,
1771 SymbolDBPlugin
*sdb_plugin
;
1772 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (data
);
1773 gint task_registered
;
1775 task_registered
= GPOINTER_TO_INT (g_tree_lookup (sdb_plugin
->proc_id_tree
,
1776 GINT_TO_POINTER (process_id
)));
1777 /* hey, we haven't find anything */
1778 if (task_registered
<= 0)
1780 DEBUG_PRINT ("No task found, proc id was %d", process_id
);
1784 switch (task_registered
)
1786 case TASK_IMPORT_PROJECT
:
1787 case TASK_IMPORT_PROJECT_AFTER_ABORT
:
1789 DEBUG_PRINT ("received TASK_IMPORT_PROJECT (AFTER_ABORT)");
1791 /* re-enable signals receiving on local-view */
1792 sdb_plugin
->is_project_importing
= FALSE
;
1794 /* disconnect this coz it's not important after the process of importing */
1795 g_signal_handlers_disconnect_by_func (dbe
, on_project_single_file_scan_end
,
1798 /* get preferences about the parallel scan */
1799 gboolean parallel_scan
= anjuta_preferences_get_bool (sdb_plugin
->prefs
,
1802 /* check the system population has a parallel fashion or not. */
1803 if (parallel_scan
== FALSE
)
1804 do_import_system_sources (sdb_plugin
);
1808 case TASK_BUFFER_UPDATE
:
1809 DEBUG_PRINT ("received TASK_BUFFER_UPDATE");
1810 on_editor_buffer_symbol_update_scan_end (dbe
, process_id
, sdb_plugin
);
1813 case TASK_ELEMENT_ADDED
:
1814 DEBUG_PRINT ("received TASK_ELEMENT_ADDED");
1815 sdb_plugin
->is_adding_element
= FALSE
;
1818 case TASK_OFFLINE_CHANGES
:
1819 DEBUG_PRINT ("received TASK_OFFLINE_CHANGES");
1821 /* disconnect this coz it's not important after the process of importing */
1822 g_signal_handlers_disconnect_by_func (dbe
, on_check_offline_single_file_scan_end
,
1825 sdb_plugin
->is_offline_scanning
= FALSE
;
1828 case TASK_PROJECT_UPDATE
:
1829 DEBUG_PRINT ("received TASK_PROJECT_UPDATE");
1830 sdb_plugin
->is_project_updating
= FALSE
;
1833 case TASK_FILE_UPDATE
:
1834 DEBUG_PRINT ("received TASK_FILE_UPDATE");
1838 DEBUG_PRINT ("Don't know what to to with task_registered %d",
1842 /* ok, we're done. Remove the proc_id from the GTree coz we won't use it anymore */
1843 if (g_tree_remove (sdb_plugin
->proc_id_tree
, GINT_TO_POINTER (process_id
)) == FALSE
)
1844 g_warning ("Cannot remove proc_id from GTree");
1846 DEBUG_PRINT ("is_offline_scanning %d, is_project_importing %d, is_project_updating %d, "
1847 "is_adding_element %d", sdb_plugin
->is_offline_scanning
,
1848 sdb_plugin
->is_project_importing
, sdb_plugin
->is_project_updating
,
1849 sdb_plugin
->is_adding_element
);
1851 /* is the project still opened? */
1852 if (sdb_plugin
->project_opened
== NULL
)
1854 /* just return, the project may have been closed while we were waiting for the
1855 * scanning to finish
1861 * perform some checks on some booleans. If they're all successfully passed
1862 * then activate the display of local view
1864 if (sdb_plugin
->is_offline_scanning
== FALSE
&&
1865 sdb_plugin
->is_project_importing
== FALSE
&&
1866 sdb_plugin
->is_project_updating
== FALSE
&&
1867 sdb_plugin
->is_adding_element
== FALSE
)
1869 sdb_plugin
->files_count_project_done
= 0;
1870 sdb_plugin
->files_count_project
= 0;
1871 clear_project_progress_bar (dbe
, sdb_plugin
);
1876 on_isymbol_manager_prj_scan_end (SymbolDBEngine
*dbe
,
1878 IAnjutaSymbolManager
*sm
)
1880 g_signal_emit_by_name (sm
, "prj-scan-end", process_id
);
1884 on_isymbol_manager_sys_scan_end (SymbolDBEngine
*dbe
,
1886 IAnjutaSymbolManager
*sm
)
1888 g_signal_emit_by_name (sm
, "sys-scan-end", process_id
);
1892 symbol_db_activate (AnjutaPlugin
*plugin
)
1894 SymbolDBPlugin
*sdb_plugin
;
1895 gchar
*anjuta_cache_path
;
1897 GtkWidget
*view
, *label
;
1899 DEBUG_PRINT ("SymbolDBPlugin: Activating SymbolDBPlugin plugin …");
1901 /* Initialize gda library. */
1904 register_stock_icons (plugin
);
1906 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1907 sdb_plugin
->ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1908 sdb_plugin
->prefs
= anjuta_shell_get_preferences (plugin
->shell
, NULL
);
1909 sdb_plugin
->project_opened
= NULL
;
1913 /* leaving here this code. Maybe in future ctags-devs will include our patches
1914 * upstream and this can be useful again.
1916 if (ctags_path
== NULL
)
1918 DEBUG_PRINT ("ctags is not in preferences. Trying a default one %s",
1920 ctags_path
= g_strdup (CTAGS_PATH
);
1923 /* initialize the session packages to NULL. We'll store there the user
1924 * preferences for the session about global-system packages
1926 sdb_plugin
->session_packages
= NULL
;
1928 sdb_plugin
->buf_update_timeout_id
= 0;
1929 sdb_plugin
->need_symbols_update
= FALSE
;
1930 /* creates and start a new timer. */
1931 sdb_plugin
->update_timer
= g_timer_new ();
1933 /* these two arrays will maintain the same number of objects,
1934 * so that if you search, say on the first, an occurrence of a file,
1935 * you'll be able to get in O(1) the _index in the second array, where the
1936 * scan process ids are stored. This is true in the other way too.
1938 sdb_plugin
->buffer_update_files
= g_ptr_array_new_with_free_func (g_free
);
1939 sdb_plugin
->buffer_update_ids
= g_ptr_array_new ();
1940 sdb_plugin
->buffer_update_semaphore
= FALSE
;
1942 sdb_plugin
->is_offline_scanning
= FALSE
;
1943 sdb_plugin
->is_project_importing
= FALSE
;
1944 sdb_plugin
->is_project_updating
= FALSE
;
1945 sdb_plugin
->is_adding_element
= FALSE
;
1947 DEBUG_PRINT ("SymbolDBPlugin: Initializing engines with %s", ctags_path
);
1948 /* create SymbolDBEngine(s) */
1949 sdb_plugin
->sdbe_project
= symbol_db_engine_new (ctags_path
);
1950 if (sdb_plugin
->sdbe_project
== NULL
)
1952 g_critical ("sdbe_project == NULL");
1956 /* the globals one too */
1957 sdb_plugin
->sdbe_globals
= symbol_db_engine_new (ctags_path
);
1958 if (sdb_plugin
->sdbe_globals
== NULL
)
1960 g_critical ("sdbe_globals == NULL");
1964 g_free (ctags_path
);
1967 anjuta_cache_path
= anjuta_util_get_user_cache_file_path (".", NULL
);
1968 if (symbol_db_engine_open_db (sdb_plugin
->sdbe_globals
,
1970 PROJECT_GLOBALS
) == DB_OPEN_STATUS_FATAL
)
1972 g_error ("Opening global project under %s", anjuta_cache_path
);
1975 g_free (anjuta_cache_path
);
1977 /* create the object that'll manage the globals population */
1978 sdb_plugin
->sdbs
= symbol_db_system_new (sdb_plugin
, sdb_plugin
->sdbe_globals
);
1980 g_signal_connect (G_OBJECT (sdb_plugin
->sdbs
), "scan-package-start",
1981 G_CALLBACK (on_system_scan_package_start
), plugin
);
1983 g_signal_connect (G_OBJECT (sdb_plugin
->sdbs
), "scan-package-end",
1984 G_CALLBACK (on_system_scan_package_end
), plugin
);
1986 g_signal_connect (G_OBJECT (sdb_plugin
->sdbs
), "single-file-scan-end",
1987 G_CALLBACK (on_system_single_file_scan_end
), plugin
);
1989 /* beign necessary to listen to many scan-end signals, we'll build up a method
1990 * to manage them with just one signal connection
1992 sdb_plugin
->proc_id_tree
= g_tree_new_full ((GCompareDataFunc
)&symbol_db_gtree_compare_func
,
1997 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "scan-end",
1998 G_CALLBACK (on_scan_end_manager
), sdb_plugin
);
2000 /* connect signals for interface to receive them */
2001 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_globals
), "scan-end",
2002 G_CALLBACK (on_isymbol_manager_sys_scan_end
), sdb_plugin
);
2004 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "scan-end",
2005 G_CALLBACK (on_isymbol_manager_prj_scan_end
), sdb_plugin
);
2008 /* sets preferences to NULL, it'll be instantiated when required. */
2009 sdb_plugin
->sdbp
= NULL
;
2011 /* Create widgets */
2012 sdb_plugin
->dbv_main
= gtk_vbox_new(FALSE
, 5);
2013 sdb_plugin
->dbv_notebook
= gtk_notebook_new();
2014 gtk_notebook_set_show_border (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
), FALSE
);
2015 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
), FALSE
);
2016 sdb_plugin
->dbv_hbox
= gtk_hbox_new (FALSE
, 1);
2018 label
= gtk_label_new (_("Symbols"));
2019 gtk_misc_set_alignment (GTK_MISC (label
), 0.0f
, 0.5f
);
2020 gtk_box_pack_start (GTK_BOX(sdb_plugin
->dbv_hbox
),
2021 gtk_image_new_from_stock ("symbol-db-plugin-icon",
2022 GTK_ICON_SIZE_MENU
),
2024 gtk_box_pack_start (GTK_BOX(sdb_plugin
->dbv_hbox
), label
,
2027 sdb_plugin
->tabber
= anjuta_tabber_new (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
));
2028 label
= gtk_label_new (_("Local"));
2029 gtk_label_set_ellipsize (GTK_LABEL (label
),
2030 PANGO_ELLIPSIZE_END
);
2031 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin
->tabber
),
2033 label
= gtk_label_new (_("Global"));
2034 gtk_label_set_ellipsize (GTK_LABEL (label
),
2035 PANGO_ELLIPSIZE_END
);
2036 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin
->tabber
),
2038 label
= gtk_label_new (_("Search"));
2039 gtk_label_set_ellipsize (GTK_LABEL (label
),
2040 PANGO_ELLIPSIZE_END
);
2041 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin
->tabber
),
2043 gtk_box_pack_end (GTK_BOX(sdb_plugin
->dbv_hbox
), sdb_plugin
->tabber
,
2046 gtk_widget_show_all (sdb_plugin
->dbv_hbox
);
2048 sdb_plugin
->progress_bar_project
= gtk_progress_bar_new();
2049 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(sdb_plugin
->progress_bar_project
),
2050 PANGO_ELLIPSIZE_MIDDLE
);
2051 g_object_ref (sdb_plugin
->progress_bar_project
);
2053 sdb_plugin
->progress_bar_system
= gtk_progress_bar_new();
2054 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(sdb_plugin
->progress_bar_system
),
2055 PANGO_ELLIPSIZE_MIDDLE
);
2056 g_object_ref (sdb_plugin
->progress_bar_system
);
2058 gtk_box_pack_start (GTK_BOX (sdb_plugin
->dbv_main
), sdb_plugin
->dbv_notebook
,
2060 gtk_box_pack_start (GTK_BOX (sdb_plugin
->dbv_main
), sdb_plugin
->progress_bar_project
,
2062 gtk_box_pack_start (GTK_BOX (sdb_plugin
->dbv_main
), sdb_plugin
->progress_bar_system
,
2064 gtk_widget_show_all (sdb_plugin
->dbv_main
);
2067 view
= symbol_db_view_new (SYMBOL_DB_VIEW_FILE
, sdb_plugin
->sdbe_project
,
2069 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
),
2070 view
, gtk_label_new (_("Local")));
2071 sdb_plugin
->file_model
=
2072 gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN(view
))));
2074 g_object_add_weak_pointer (G_OBJECT (sdb_plugin
->file_model
),
2075 (gpointer
)&sdb_plugin
->file_model
);
2077 /* Global symbols */
2078 view
= symbol_db_view_new (SYMBOL_DB_VIEW_PROJECT
,
2079 sdb_plugin
->sdbe_project
,
2081 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
),
2082 view
, gtk_label_new (_("Global" )));
2084 /* Search symbols */
2085 view
= symbol_db_view_new (SYMBOL_DB_VIEW_SEARCH
,
2086 sdb_plugin
->sdbe_project
,
2088 sdb_plugin
->search_entry
= symbol_db_view_get_search_entry (view
);
2089 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
),
2090 view
, gtk_label_new (_("Search" )));
2092 gtk_widget_show_all (sdb_plugin
->dbv_notebook
);
2094 /* setting focus to the tree_view*/
2095 gtk_notebook_set_current_page (GTK_NOTEBOOK (sdb_plugin
->dbv_notebook
), 0);
2097 sdb_plugin
->editor_watch_id
=
2098 anjuta_plugin_add_watch (plugin
, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
2099 value_added_current_editor
,
2100 value_removed_current_editor
, NULL
);
2102 anjuta_shell_add_widget_custom (plugin
->shell
, sdb_plugin
->dbv_main
,
2103 "AnjutaSymbolDB", _("Symbols"),
2104 "symbol-db-plugin-icon",
2105 sdb_plugin
->dbv_hbox
,
2106 ANJUTA_SHELL_PLACEMENT_LEFT
, NULL
);
2108 /* Add action group */
2109 sdb_plugin
->popup_action_group
=
2110 anjuta_ui_add_action_group_entries (sdb_plugin
->ui
,
2111 "ActionGroupPopupSymbolDB",
2112 _("SymbolDb popup actions"),
2114 G_N_ELEMENTS (actions
),
2115 GETTEXT_PACKAGE
, FALSE
, plugin
);
2117 sdb_plugin
->menu_action_group
=
2118 anjuta_ui_add_action_group_entries (sdb_plugin
->ui
,
2119 "ActionGroupEditSearchSymbolDB",
2120 _("SymbolDb menu actions"),
2122 G_N_ELEMENTS (actions_search
),
2123 GETTEXT_PACKAGE
, FALSE
, plugin
);
2126 sdb_plugin
->merge_id
=
2127 anjuta_ui_merge (sdb_plugin
->ui
, UI_FILE
);
2129 /* set up project directory watch */
2130 sdb_plugin
->root_watch_id
= anjuta_plugin_add_watch (plugin
,
2131 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
2132 on_project_root_added
,
2133 on_project_root_removed
, NULL
);
2135 /* Determine session state */
2136 g_signal_connect (plugin
->shell
, "load-session",
2137 G_CALLBACK (on_session_load
), plugin
);
2139 g_signal_connect (plugin
->shell
, "save-session",
2140 G_CALLBACK (on_session_save
), plugin
);
2142 /* be sure to hide the progress bars in case no project has been opened. */
2143 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
2144 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
2146 static IAnjutaSymbolField search_fields
[] =
2148 IANJUTA_SYMBOL_FIELD_KIND
,
2149 IANJUTA_SYMBOL_FIELD_FILE_PATH
,
2150 IANJUTA_SYMBOL_FIELD_FILE_POS
2152 sdb_plugin
->search_query
=
2153 ianjuta_symbol_manager_create_query (IANJUTA_SYMBOL_MANAGER (sdb_plugin
),
2154 IANJUTA_SYMBOL_QUERY_SEARCH
,
2155 IANJUTA_SYMBOL_QUERY_DB_PROJECT
,
2157 ianjuta_symbol_query_set_fields (sdb_plugin
->search_query
,
2158 G_N_ELEMENTS (search_fields
),
2159 search_fields
, NULL
);
2164 symbol_db_deactivate (AnjutaPlugin
*plugin
)
2166 SymbolDBPlugin
*sdb_plugin
;
2168 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
2170 DEBUG_PRINT ("%s", "SymbolDBPlugin: Dectivating SymbolDBPlugin plugin …");
2173 gtk_ui_manager_remove_ui (GTK_UI_MANAGER (sdb_plugin
->ui
),
2174 sdb_plugin
->merge_id
);
2175 gtk_ui_manager_remove_action_group (GTK_UI_MANAGER (sdb_plugin
->ui
),
2176 sdb_plugin
->popup_action_group
);
2177 gtk_ui_manager_remove_action_group (GTK_UI_MANAGER (sdb_plugin
->ui
),
2178 sdb_plugin
->menu_action_group
);
2179 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin
->shell
),
2183 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin
->shell
),
2187 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbs
),
2188 on_system_scan_package_start
,
2191 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbs
),
2192 on_system_scan_package_end
,
2195 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbs
),
2196 on_system_single_file_scan_end
,
2199 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbs
),
2200 on_scan_end_manager
,
2203 /* disconnect the interface ones */
2204 /* connect signals for interface to receive them */
2205 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbe_globals
),
2206 G_CALLBACK (on_isymbol_manager_sys_scan_end
), plugin
);
2208 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->sdbe_project
),
2209 G_CALLBACK (on_isymbol_manager_prj_scan_end
), plugin
);
2211 if (sdb_plugin
->update_timer
)
2213 g_timer_destroy (sdb_plugin
->update_timer
);
2214 sdb_plugin
->update_timer
= NULL
;
2217 /* destroy objects */
2218 if (sdb_plugin
->sdbe_project
)
2220 DEBUG_PRINT ("Destroying project engine object. ");
2221 g_object_unref (sdb_plugin
->sdbe_project
);
2223 sdb_plugin
->sdbe_project
= NULL
;
2225 /* this must be done *before* destroying sdbe_globals */
2226 g_object_unref (sdb_plugin
->sdbs
);
2227 sdb_plugin
->sdbs
= NULL
;
2229 g_free (sdb_plugin
->current_scanned_package
);
2230 sdb_plugin
->current_scanned_package
= NULL
;
2232 DEBUG_PRINT ("Destroying global engine object. ");
2233 g_object_unref (sdb_plugin
->sdbe_globals
);
2234 sdb_plugin
->sdbe_globals
= NULL
;
2236 g_free (sdb_plugin
->project_opened
);
2237 sdb_plugin
->project_opened
= NULL
;
2239 if (sdb_plugin
->buffer_update_files
)
2241 g_ptr_array_unref (sdb_plugin
->buffer_update_files
);
2242 sdb_plugin
->buffer_update_files
= NULL
;
2245 if (sdb_plugin
->buffer_update_ids
)
2247 g_ptr_array_unref (sdb_plugin
->buffer_update_ids
);
2248 sdb_plugin
->buffer_update_ids
= NULL
;
2251 if (sdb_plugin
->session_packages
)
2253 g_list_foreach (sdb_plugin
->session_packages
, (GFunc
)g_free
, NULL
);
2254 g_list_free (sdb_plugin
->session_packages
);
2255 sdb_plugin
->session_packages
= NULL
;
2258 /* Ensure all editor cached info are released */
2259 if (sdb_plugin
->editor_connected
)
2261 g_hash_table_foreach (sdb_plugin
->editor_connected
,
2262 on_editor_foreach_disconnect
, plugin
);
2263 g_hash_table_destroy (sdb_plugin
->editor_connected
);
2264 sdb_plugin
->editor_connected
= NULL
;
2268 g_tree_destroy (sdb_plugin
->proc_id_tree
);
2270 /* Remove watches */
2271 anjuta_plugin_remove_watch (plugin
, sdb_plugin
->root_watch_id
, FALSE
);
2272 anjuta_plugin_remove_watch (plugin
, sdb_plugin
->editor_watch_id
, TRUE
);
2275 anjuta_ui_unmerge (sdb_plugin
->ui
, sdb_plugin
->merge_id
);
2277 /* Remove widgets: Widgets will be destroyed when dbv_main is removed */
2278 anjuta_shell_remove_widget (plugin
->shell
, sdb_plugin
->dbv_main
, NULL
);
2280 sdb_plugin
->root_watch_id
= 0;
2281 sdb_plugin
->editor_watch_id
= 0;
2282 sdb_plugin
->merge_id
= 0;
2283 sdb_plugin
->dbv_notebook
= NULL
;
2284 sdb_plugin
->progress_bar_project
= NULL
;
2285 sdb_plugin
->progress_bar_system
= NULL
;
2290 symbol_db_finalize (GObject
*obj
)
2292 DEBUG_PRINT ("Symbol-DB finalize");
2293 /* Finalization codes here */
2294 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
2298 symbol_db_dispose (GObject
*obj
)
2300 DEBUG_PRINT ("Symbol-DB dispose");
2301 /* Disposition codes */
2302 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
2306 symbol_db_instance_init (GObject
*obj
)
2308 SymbolDBPlugin
*plugin
= (SymbolDBPlugin
*)obj
;
2310 plugin
->files_count_project_done
= 0;
2311 plugin
->files_count_project
= 0;
2313 plugin
->files_count_system_done
= 0;
2314 plugin
->files_count_system
= 0;
2315 plugin
->current_scanned_package
= NULL
;
2319 symbol_db_class_init (GObjectClass
*klass
)
2321 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
2323 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
2324 parent_class
= g_type_class_peek_parent (klass
);
2326 plugin_class
->activate
= symbol_db_activate
;
2327 plugin_class
->deactivate
= symbol_db_deactivate
;
2328 klass
->finalize
= symbol_db_finalize
;
2329 klass
->dispose
= symbol_db_dispose
;
2331 signals
[PROJECT_IMPORT_END
]
2332 = g_signal_new ("project-import-end",
2333 G_OBJECT_CLASS_TYPE (object_class
),
2335 G_STRUCT_OFFSET (SymbolDBPluginClass
, project_import_end
),
2337 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
2339 signals
[GLOBALS_IMPORT_END
]
2340 = g_signal_new ("globals-import-end",
2341 G_OBJECT_CLASS_TYPE (object_class
),
2343 G_STRUCT_OFFSET (SymbolDBPluginClass
, globals_import_end
),
2345 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
2351 on_prefs_package_add (SymbolDBPrefs
*sdbp
, const gchar
*package
,
2354 SymbolDBPlugin
*sdb_plugin
;
2356 g_return_if_fail (package
!= NULL
);
2358 DEBUG_PRINT ("%s", "on_prefs_package_add");
2360 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
2362 sdb_plugin
->session_packages
= g_list_prepend (sdb_plugin
->session_packages
,
2363 g_strdup (package
));
2367 on_prefs_package_remove (SymbolDBPrefs
*sdbp
, const gchar
*package
,
2370 SymbolDBPlugin
*sdb_plugin
;
2372 g_return_if_fail (package
!= NULL
);
2374 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
2377 DEBUG_PRINT ("%s", "on_prefs_package_remove");
2378 if ((item
= g_list_find_custom (sdb_plugin
->session_packages
, package
,
2379 symbol_db_glist_compare_func
)) != NULL
)
2381 sdb_plugin
->session_packages
= g_list_remove_link (sdb_plugin
->session_packages
,
2384 /* ok, now think to the item left alone by its friends... */
2385 g_list_foreach (item
, (GFunc
)g_free
, NULL
);
2391 on_prefs_buffer_update_toggled (SymbolDBPrefs
*sdbp
, guint value
,
2394 SymbolDBPlugin
*sdb_plugin
;
2395 DEBUG_PRINT ("on_prefs_buffer_update_toggled () %d", value
);
2397 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
2401 if (sdb_plugin
->buf_update_timeout_id
)
2402 g_source_remove (sdb_plugin
->buf_update_timeout_id
);
2403 sdb_plugin
->buf_update_timeout_id
= 0;
2407 if (sdb_plugin
->buf_update_timeout_id
== 0)
2408 sdb_plugin
->buf_update_timeout_id
=
2409 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE
,
2410 on_editor_buffer_symbols_update_timeout
,
2417 ipreferences_merge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
2419 DEBUG_PRINT ("%s", "SymbolDB: ipreferences_merge");
2420 SymbolDBPlugin
*sdb_plugin
;
2422 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (ipref
);
2424 if (sdb_plugin
->sdbp
== NULL
)
2426 sdb_plugin
->sdbp
= symbol_db_prefs_new (sdb_plugin
->sdbs
,
2427 sdb_plugin
->sdbe_project
,
2428 sdb_plugin
->sdbe_globals
,
2430 sdb_plugin
->session_packages
);
2432 /* connect the signals to retrieve package modifications */
2433 g_signal_connect (G_OBJECT (sdb_plugin
->sdbp
), "package-add",
2434 G_CALLBACK (on_prefs_package_add
),
2436 g_signal_connect (G_OBJECT (sdb_plugin
->sdbp
), "package-remove",
2437 G_CALLBACK (on_prefs_package_remove
),
2439 g_signal_connect (G_OBJECT (sdb_plugin
->sdbp
), "buffer-update-toggled",
2440 G_CALLBACK (on_prefs_buffer_update_toggled
),
2446 ipreferences_unmerge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
2448 SymbolDBPlugin
*sdb_plugin
;
2450 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (ipref
);
2452 if (sdb_plugin
->sdbp
!= NULL
)
2454 g_object_unref (sdb_plugin
->sdbp
);
2455 sdb_plugin
->sdbp
= NULL
;
2460 ipreferences_iface_init(IAnjutaPreferencesIface
* iface
)
2462 DEBUG_PRINT ("%s", "SymbolDB: ipreferences_iface_init");
2463 iface
->merge
= ipreferences_merge
;
2464 iface
->unmerge
= ipreferences_unmerge
;
2467 /* IAnjutaSymbolManager implementation */
2468 static IAnjutaSymbolQuery
*
2469 isymbol_manager_create_query (IAnjutaSymbolManager
*isymbol_manager
,
2470 IAnjutaSymbolQueryName query_name
,
2471 IAnjutaSymbolQueryDb db
,
2474 SymbolDBPlugin
*sdb_plugin
;
2475 SymbolDBQuery
*query
;
2476 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager
);
2478 query
= symbol_db_query_new (sdb_plugin
->sdbe_globals
,
2479 sdb_plugin
->sdbe_project
, query_name
, db
);
2480 return IANJUTA_SYMBOL_QUERY (query
);
2484 isymbol_manager_add_package (IAnjutaSymbolManager
*isymbol_manager
,
2485 const gchar
* pkg_name
,
2486 const gchar
* pkg_version
,
2490 SymbolDBPlugin
*sdb_plugin
;
2491 SymbolDBQuery
*query
;
2492 IAnjutaLanguage
*lang_manager
;
2493 GPtrArray
*files_array
;
2496 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager
);
2497 lang_manager
=anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
, IAnjutaLanguage
,
2500 if (symbol_db_engine_add_new_project (sdb_plugin
->sdbe_globals
, NULL
, pkg_name
,
2501 pkg_version
) == FALSE
)
2506 files_array
= g_ptr_array_sized_new (g_list_length (files
));
2507 g_ptr_array_set_free_func (files_array
, g_free
);
2510 while (node
!= NULL
)
2512 g_ptr_array_add (files_array
, g_strdup (node
->data
));
2517 symbol_db_engine_add_new_files_async (sdb_plugin
->sdbe_globals
, lang_manager
,
2518 pkg_name
, pkg_version
, files_array
);
2520 g_ptr_array_unref (files_array
);
2526 isymbol_manager_activate_package (IAnjutaSymbolManager
*isymbol_manager
,
2527 const gchar
*pkg_name
,
2528 const gchar
*pkg_version
,
2535 isymbol_manager_deactivate_package (IAnjutaSymbolManager
*isymbol_manager
,
2536 const gchar
*pkg_name
,
2537 const gchar
*pkg_version
,
2545 isymbol_manager_iface_init (IAnjutaSymbolManagerIface
*iface
)
2547 iface
->create_query
= isymbol_manager_create_query
;
2548 iface
->add_package
= isymbol_manager_add_package
;
2549 iface
->activate_package
= isymbol_manager_activate_package
;
2550 iface
->deactivate_package
= isymbol_manager_deactivate_package
;
2553 ANJUTA_PLUGIN_BEGIN (SymbolDBPlugin
, symbol_db
);
2554 ANJUTA_PLUGIN_ADD_INTERFACE (isymbol_manager
, IANJUTA_TYPE_SYMBOL_MANAGER
);
2555 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences
, IANJUTA_TYPE_PREFERENCES
);
2558 ANJUTA_SIMPLE_PLUGIN (SymbolDBPlugin
, symbol_db
);