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.
26 #include <libgnomevfs/gnome-vfs-utils.h>
27 #include <libgnomevfs/gnome-vfs-mime-utils.h>
28 #include <libanjuta/anjuta-shell.h>
29 #include <libanjuta/anjuta-debug.h>
30 #include <libanjuta/anjuta-utils.h>
31 #include <libanjuta/interfaces/ianjuta-document-manager.h>
32 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
33 #include <libanjuta/interfaces/ianjuta-project-manager.h>
34 #include <libanjuta/interfaces/ianjuta-file-manager.h>
35 #include <libanjuta/interfaces/ianjuta-file.h>
36 #include <libanjuta/interfaces/ianjuta-file-loader.h>
37 #include <libanjuta/interfaces/ianjuta-editor.h>
38 #include <libanjuta/interfaces/ianjuta-markable.h>
39 #include <libanjuta/interfaces/ianjuta-language.h>
40 #include <libanjuta/interfaces/ianjuta-iterable.h>
41 #include <libanjuta/interfaces/ianjuta-preferences.h>
44 #include "symbol-db-view.h"
45 #include "symbol-db-view-locals.h"
46 #include "symbol-db-view-search.h"
47 #include "symbol-db-engine.h"
48 #include "symbol-db-engine-iterator.h"
49 #include "symbol-db-prefs.h"
51 #define ICON_FILE "anjuta-symbol-db-plugin-48.png"
53 #define TIMEOUT_INTERVAL_SYMBOLS_UPDATE 10000
54 #define TIMEOUT_SECONDS_AFTER_LAST_TIP 5
56 #define CHOOSER_WIDGET "preferences_folder:text:/:0:symboldb.root"
57 #define PROJECT_GLOBALS "/"
58 #define CTAGS_PREFS_KEY "symboldb.ctags"
59 #define SESSION_SECTION "SymbolDB"
60 #define SESSION_KEY "SystemPackages"
62 static gpointer parent_class
;
63 static gboolean need_symbols_update
= FALSE
;
64 static gint timeout_id
= 0;
65 static GTimer
*timer
= NULL
;
68 register_stock_icons (AnjutaPlugin
*plugin
)
70 static gboolean registered
= FALSE
;
76 /* Register stock icons */
77 BEGIN_REGISTER_ICON (plugin
);
78 REGISTER_ICON (ICON_FILE
, "symbol-db-plugin-icon");
83 on_editor_buffer_symbols_update_timeout (gpointer user_data
)
85 SymbolDBPlugin
*sdb_plugin
;
87 gchar
*current_buffer
= NULL
;
90 gdouble seconds_elapsed
;
92 g_return_val_if_fail (user_data
!= NULL
, FALSE
);
94 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
96 if (sdb_plugin
->current_editor
== NULL
)
99 /* check the timer. If it's elapsed enought time since the last time the user
100 * typed in something, than proceed with updating, elsewhere don't do nothing
105 seconds_elapsed
= g_timer_elapsed (timer
, NULL
);
107 /* DEBUG_PRINT ("seconds_elapsed %f", seconds_elapsed ); */
108 if (seconds_elapsed
< TIMEOUT_SECONDS_AFTER_LAST_TIP
)
112 /* we won't proceed with the updating of the symbols if we didn't type in
114 if (!need_symbols_update
)
117 DEBUG_PRINT ("on_editor_buffer_symbols_update_timeout()");
119 if (sdb_plugin
->current_editor
)
122 ed
= IANJUTA_EDITOR (sdb_plugin
->current_editor
);
124 buffer_size
= ianjuta_editor_get_length (ed
, NULL
);
125 current_buffer
= ianjuta_editor_get_text_all (ed
, NULL
);
127 file
= ianjuta_file_get_file (IANJUTA_FILE (ed
), NULL
);
128 uri
= g_file_get_uri (file
);
129 g_object_unref (file
);
136 DEBUG_PRINT ("uri for buffer updating: %s", uri
);
138 GPtrArray
*real_files_list
;
139 GPtrArray
*text_buffers
;
140 GPtrArray
*buffer_sizes
;
142 gchar
* local_path
= gnome_vfs_get_local_path_from_uri (uri
);
144 real_files_list
= g_ptr_array_new ();
145 g_ptr_array_add (real_files_list
, local_path
);
147 text_buffers
= g_ptr_array_new ();
148 g_ptr_array_add (text_buffers
, current_buffer
);
150 buffer_sizes
= g_ptr_array_new ();
151 g_ptr_array_add (buffer_sizes
, (gpointer
)buffer_size
);
153 symbol_db_engine_update_buffer_symbols (sdb_plugin
->sdbe_project
,
154 sdb_plugin
->project_opened
,
162 g_free (current_buffer
);
164 need_symbols_update
= FALSE
;
170 on_editor_destroy (SymbolDBPlugin
*sdb_plugin
, IAnjutaEditor
*editor
)
173 DEBUG_PRINT ("on_editor_destroy ()");
174 if (!sdb_plugin
->editor_connected
|| !sdb_plugin
->dbv_view_tree
)
177 uri
= g_hash_table_lookup (sdb_plugin
->editor_connected
, G_OBJECT (editor
));
178 g_hash_table_remove (sdb_plugin
->editor_connected
, G_OBJECT (editor
));
182 on_editor_update_ui (IAnjutaEditor
*editor
, SymbolDBPlugin
*sdb_plugin
)
186 /* creates and start a new timer. */
187 timer
= g_timer_new ();
191 g_timer_reset (timer
);
196 on_char_added (IAnjutaEditor
*editor
, IAnjutaIterable
*position
, gchar ch
,
197 SymbolDBPlugin
*sdb_plugin
)
201 /* creates and start a new timer. */
202 timer
= g_timer_new ();
206 g_timer_reset (timer
);
209 /* Update when the user enters a newline */
211 need_symbols_update
= TRUE
;
216 on_editor_saved (IAnjutaEditor
*editor
, GFile
* file
,
217 SymbolDBPlugin
*sdb_plugin
)
219 const gchar
*old_uri
;
220 gboolean tags_update
;
221 /* FIXME: Do this only if automatic tags update is enabled */
223 anjuta_preferences_get_int (te->preferences, AUTOMATIC_TAGS_UPDATE);
228 gchar
*local_filename
= g_file_get_path (file
);
229 gchar
*saved_uri
= g_file_get_uri (file
);
230 GPtrArray
*files_array
;
232 /* Verify that it's local file */
233 g_return_if_fail (local_filename
!= NULL
);
235 files_array
= g_ptr_array_new();
236 DEBUG_PRINT ("local_filename saved is %s", local_filename
);
237 g_ptr_array_add (files_array
, local_filename
);
238 /* no need to free local_filename now */
240 if (!sdb_plugin
->editor_connected
)
243 old_uri
= g_hash_table_lookup (sdb_plugin
->editor_connected
, editor
);
245 if (old_uri
&& strlen (old_uri
) <= 0)
248 /* files_array will be freed once updating has taken place */
249 symbol_db_engine_update_files_symbols (sdb_plugin
->sdbe_project
,
250 sdb_plugin
->project_root_dir
, files_array
, TRUE
);
251 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
252 g_strdup (saved_uri
));
254 on_editor_update_ui (editor
, sdb_plugin
);
260 value_added_current_editor (AnjutaPlugin
*plugin
, const char *name
,
261 const GValue
*value
, gpointer data
)
267 SymbolDBPlugin
*sdb_plugin
;
269 editor
= g_value_get_object (value
);
270 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
272 if (sdb_plugin
->session_loading
)
274 DEBUG_PRINT ("session_loading");
278 DEBUG_PRINT ("Updating symbols");
280 if (!sdb_plugin
->editor_connected
)
282 sdb_plugin
->editor_connected
= g_hash_table_new_full (g_direct_hash
,
286 sdb_plugin
->current_editor
= editor
;
288 if (!IANJUTA_IS_EDITOR (editor
))
291 file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), NULL
);
296 local_path
= g_file_get_path (file
);
297 uri
= g_file_get_uri (file
);
298 DEBUG_PRINT ("value_added_current_editor () gonna refresh local syms: local_path %s "
299 "uri %s", local_path
, uri
);
300 if (local_path
== NULL
)
302 g_critical ("FIXME local_path == NULL");
306 if (strstr (local_path
, "//") != NULL
)
308 g_critical ("WARNING FIXME: bad file uri passed to symbol-db from editor. There's "
309 "a trailing slash left. Please fix this at editor side");
312 symbol_db_view_locals_update_list (
313 SYMBOL_DB_VIEW_LOCALS (sdb_plugin
->dbv_view_tree_locals
),
314 sdb_plugin
->sdbe_project
, local_path
);
316 if (g_hash_table_lookup (sdb_plugin
->editor_connected
, editor
) == NULL
)
318 g_object_weak_ref (G_OBJECT (editor
),
319 (GWeakNotify
) (on_editor_destroy
),
323 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
328 g_hash_table_insert (sdb_plugin
->editor_connected
, editor
,
332 g_signal_connect (G_OBJECT (editor
), "saved",
333 G_CALLBACK (on_editor_saved
),
335 g_signal_connect (G_OBJECT (editor
), "char-added",
336 G_CALLBACK (on_char_added
),
338 g_signal_connect (G_OBJECT(editor
), "update_ui",
339 G_CALLBACK (on_editor_update_ui
),
345 /* add a default timeout to the updating of buffer symbols */
346 timeout_id
= g_timeout_add (TIMEOUT_INTERVAL_SYMBOLS_UPDATE
,
347 on_editor_buffer_symbols_update_timeout
,
349 need_symbols_update
= FALSE
;
353 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
354 AnjutaSession
*session
,
355 SymbolDBPlugin
*sdb_plugin
)
357 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
360 DEBUG_PRINT ("SymbolDB: session_save");
362 anjuta_session_set_string_list (session
,
365 sdb_plugin
->session_packages
);
369 on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
370 AnjutaSession
*session
,
371 SymbolDBPlugin
*sdb_plugin
)
373 IAnjutaProjectManager
*pm
;
374 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
375 IAnjutaProjectManager
, NULL
);
377 if (phase
== ANJUTA_SESSION_PHASE_START
)
379 DEBUG_PRINT ("SymbolDB: session_loading started. Getting info from %s",
380 anjuta_session_get_session_directory (session
));
381 sdb_plugin
->session_loading
= TRUE
;
383 GList
*session_packages
= anjuta_session_get_string_list (session
,
387 GList
*to_scan_packages
= NULL
;
389 if (session_packages
== NULL
)
391 GList
*project_default_packages
=
392 ianjuta_project_manager_get_packages (pm
, NULL
);
394 /* take the project's defaults */
395 to_scan_packages
= project_default_packages
;
399 to_scan_packages
= session_packages
;
402 /* system's packages management */
403 GList
*item
= to_scan_packages
;
406 /* the function will take care of checking if the package is already
407 * scanned and present on db
409 DEBUG_PRINT ("ianjuta_project_manager_get_packages: package required: %s",
411 symbol_db_system_scan_package (sdb_plugin
->sdbs
, item
->data
);
416 sdb_plugin
->session_packages
= to_scan_packages
;
418 /* no need to free the GList(s) */
420 else if (phase
== ANJUTA_SESSION_PHASE_END
)
422 IAnjutaDocumentManager
* docman
;
423 sdb_plugin
->session_loading
= FALSE
;
424 DEBUG_PRINT ("SymbolDB: session_loading finished");
426 /* Show the symbols for the current editor */
427 docman
= anjuta_shell_get_interface (shell
, IAnjutaDocumentManager
, NULL
);
430 IAnjutaDocument
* cur_doc
=
431 ianjuta_document_manager_get_current_document (docman
, NULL
);
434 GValue value
= {0, };
435 g_value_init (&value
, G_TYPE_OBJECT
);
436 g_value_set_object (&value
, cur_doc
);
437 value_added_current_editor (ANJUTA_PLUGIN (sdb_plugin
),
438 "document_manager_current_editor",
440 g_value_unset(&value
);
447 on_editor_foreach_disconnect (gpointer key
, gpointer value
, gpointer user_data
)
449 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
450 G_CALLBACK (on_editor_saved
),
452 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
453 G_CALLBACK (on_editor_update_ui
),
455 g_signal_handlers_disconnect_by_func (G_OBJECT(key
),
456 G_CALLBACK (on_char_added
),
458 g_object_weak_unref (G_OBJECT(key
),
459 (GWeakNotify
) (on_editor_destroy
),
464 goto_file_line (AnjutaPlugin
*plugin
, const gchar
*filename
, gint lineno
)
466 IAnjutaDocumentManager
*docman
;
469 g_return_if_fail (filename
!= NULL
);
471 /* Go to file and line number */
472 docman
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaDocumentManager
,
474 file
= g_file_new_for_path (filename
);
475 ianjuta_document_manager_goto_file_line (docman
, file
, lineno
, NULL
);
477 g_object_unref (file
);
482 goto_local_tree_iter (SymbolDBPlugin
*sdb_plugin
, GtkTreeIter
*iter
)
486 line
= symbol_db_view_locals_get_line (SYMBOL_DB_VIEW_LOCALS (
487 sdb_plugin
->dbv_view_tree_locals
),
488 sdb_plugin
->sdbe_project
,
491 DEBUG_PRINT ("got line %d", line
);
493 if (line
> 0 && sdb_plugin
->current_editor
)
495 /* Goto line number */
496 ianjuta_editor_goto_line (IANJUTA_EDITOR (sdb_plugin
->current_editor
),
498 if (IANJUTA_IS_MARKABLE (sdb_plugin
->current_editor
))
500 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (sdb_plugin
->current_editor
),
501 IANJUTA_MARKABLE_LINEMARKER
,
504 ianjuta_markable_mark (IANJUTA_MARKABLE (sdb_plugin
->current_editor
),
505 line
, IANJUTA_MARKABLE_LINEMARKER
, NULL
);
511 goto_global_tree_iter (SymbolDBPlugin
*sdb_plugin
, GtkTreeIter
*iter
)
516 if (symbol_db_view_get_file_and_line (
517 SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
), sdb_plugin
->sdbe_project
,
518 iter
, &line
, &file
) == FALSE
)
520 g_warning ("goto_global_tree_iter (): error while trying to get file/line");
525 DEBUG_PRINT ("got line %d and file %s", line
, file
);
527 if (line
> 0 && sdb_plugin
->current_editor
)
529 goto_file_line (ANJUTA_PLUGIN (sdb_plugin
), file
, line
);
530 if (IANJUTA_IS_MARKABLE (sdb_plugin
->current_editor
))
532 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (sdb_plugin
->current_editor
),
533 IANJUTA_MARKABLE_LINEMARKER
,
536 ianjuta_markable_mark (IANJUTA_MARKABLE (sdb_plugin
->current_editor
),
537 line
, IANJUTA_MARKABLE_LINEMARKER
, NULL
);
545 * will manage the click of mouse and other events on search->hitlist treeview
548 on_treesearch_symbol_selected_event (SymbolDBViewSearch
*search
,
551 SymbolDBPlugin
*sdb_plugin
)
554 DEBUG_PRINT ("on_treesearch_symbol_selected_event (), %s %d", file
, line
);
555 goto_file_line (ANJUTA_PLUGIN (sdb_plugin
), file
, line
);
560 on_local_treeview_row_activated (GtkTreeView
*view
, GtkTreePath
*arg1
,
561 GtkTreeViewColumn
*arg2
,
562 SymbolDBPlugin
*sdb_plugin
)
565 GtkTreeSelection
*selection
;
568 DEBUG_PRINT ("on_local_treeview_row_activated ()");
569 selection
= gtk_tree_view_get_selection (view
);
570 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
574 goto_local_tree_iter (sdb_plugin
, &iter
);
578 on_global_treeview_row_activated (GtkTreeView
*view
, GtkTreePath
*arg1
,
579 GtkTreeViewColumn
*arg2
,
580 SymbolDBPlugin
*sdb_plugin
)
583 GtkTreeSelection
*selection
;
586 DEBUG_PRINT ("on_global_treeview_row_activated ()");
587 selection
= gtk_tree_view_get_selection (view
);
588 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
593 goto_global_tree_iter (sdb_plugin
, &iter
);
597 on_global_treeview_row_expanded (GtkTreeView
*tree_view
,
600 SymbolDBPlugin
*user_data
)
602 DEBUG_PRINT ("on_global_treeview_row_expanded ()");
604 symbol_db_view_row_expanded (SYMBOL_DB_VIEW (user_data
->dbv_view_tree
),
605 user_data
->sdbe_project
, iter
);
609 on_global_treeview_row_collapsed (GtkTreeView
*tree_view
,
612 SymbolDBPlugin
*user_data
)
614 DEBUG_PRINT ("on_global_treeview_row_collapsed ()");
616 symbol_db_view_row_collapsed (SYMBOL_DB_VIEW (user_data
->dbv_view_tree
),
617 user_data
->sdbe_project
, iter
);
622 value_removed_current_editor (AnjutaPlugin
*plugin
,
623 const char *name
, gpointer data
)
625 SymbolDBPlugin
*sdb_plugin
;
627 if (!IANJUTA_IS_EDITOR (data
))
630 DEBUG_PRINT ("value_removed_current_editor ()");
631 /* let's remove the timeout for symbols refresh */
632 g_source_remove (timeout_id
);
633 need_symbols_update
= FALSE
;
635 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
636 sdb_plugin
->current_editor
= NULL
;
641 on_project_element_added (IAnjutaProjectManager
*pm
, const gchar
*uri
,
642 SymbolDBPlugin
*sdb_plugin
)
645 IAnjutaLanguage
* lang_manager
;
647 g_return_if_fail (sdb_plugin
->project_root_uri
!= NULL
);
648 g_return_if_fail (sdb_plugin
->project_root_dir
!= NULL
);
650 lang_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN(sdb_plugin
)->shell
,
651 IAnjutaLanguage
, NULL
);
653 g_return_if_fail (lang_manager
!= NULL
);
655 DEBUG_PRINT ("on_project_element_added");
657 filename
= gnome_vfs_get_local_path_from_uri (uri
);
660 GPtrArray
*files_array
;
661 GPtrArray
*languages_array
;
662 const gchar
* file_mime
;
663 IAnjutaLanguageId lang_id
;
665 file_mime
= gnome_vfs_get_mime_type_for_name (filename
);
667 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
, file_mime
,
670 /* No supported language... */
677 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
678 files_array
= g_ptr_array_new();
679 languages_array
= g_ptr_array_new();
681 g_ptr_array_add (files_array
, filename
);
682 g_ptr_array_add (languages_array
, g_strdup (lang
));
684 symbol_db_engine_add_new_files (sdb_plugin
->sdbe_project
,
685 sdb_plugin
->project_opened
, files_array
, languages_array
, TRUE
);
688 g_ptr_array_free (files_array
, TRUE
);
690 g_ptr_array_foreach (languages_array
, (GFunc
)g_free
, NULL
);
691 g_ptr_array_free (languages_array
, TRUE
);
696 on_project_element_removed (IAnjutaProjectManager
*pm
, const gchar
*uri
,
697 SymbolDBPlugin
*sdb_plugin
)
701 if (!sdb_plugin
->project_root_uri
)
704 filename
= gnome_vfs_get_local_path_from_uri (uri
);
707 DEBUG_PRINT ("on_project_element_removed");
708 DEBUG_PRINT ("project_root_dir %s", sdb_plugin
->project_root_dir
);
709 symbol_db_engine_remove_file (sdb_plugin
->sdbe_project
,
710 sdb_plugin
->project_root_dir
, filename
);
717 sources_array_free (gpointer data
)
719 GPtrArray
* sources
= (GPtrArray
*) data
;
720 g_ptr_array_foreach (sources
, (GFunc
)g_free
, NULL
);
721 g_ptr_array_free (sources
, TRUE
);
726 on_system_scan_package_start (SymbolDBEngine
*dbe
, guint num_files
,
727 const gchar
*package
, gpointer user_data
)
729 SymbolDBPlugin
*sdb_plugin
;
730 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
732 sdb_plugin
->files_count_system_done
= 0;
733 sdb_plugin
->files_count_system
= num_files
;
735 DEBUG_PRINT ("on_system_scan_package_start () [%s]", package
);
737 /* show the global bar */
738 gtk_widget_show (sdb_plugin
->progress_bar_system
);
740 if (sdb_plugin
->current_scanned_package
!= NULL
)
741 g_free (sdb_plugin
->current_scanned_package
);
742 sdb_plugin
->current_scanned_package
= g_strdup (package
);
746 on_system_scan_package_end (SymbolDBEngine
*dbe
, const gchar
*package
,
749 SymbolDBPlugin
*sdb_plugin
;
750 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
752 DEBUG_PRINT ("on_system_scan_package_end () [%s]", package
);
754 /* hide the progress bar */
755 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
757 sdb_plugin
->files_count_system_done
= 0;
758 sdb_plugin
->files_count_system
= 0;
762 on_system_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer data
)
764 AnjutaPlugin
*plugin
;
765 SymbolDBPlugin
*sdb_plugin
;
767 gdouble fraction
= 0;
769 plugin
= ANJUTA_PLUGIN (data
);
770 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
772 DEBUG_PRINT ("on_system_single_file_scan_end ()");
774 sdb_plugin
->files_count_system_done
++;
775 if (sdb_plugin
->files_count_system_done
>= sdb_plugin
->files_count_system
)
776 message
= g_strdup_printf (_("%s: Generating inheritances..."),
777 sdb_plugin
->current_scanned_package
);
779 message
= g_strdup_printf (_("%s: %d files scanned out of %d"),
780 sdb_plugin
->current_scanned_package
,
781 sdb_plugin
->files_count_system_done
,
782 sdb_plugin
->files_count_system
);
784 if (sdb_plugin
->files_count_system
> 0)
786 fraction
= (gdouble
) sdb_plugin
->files_count_system_done
/
787 (gdouble
) sdb_plugin
->files_count_system
;
789 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_system
),
791 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_system
), message
);
792 gtk_widget_show (sdb_plugin
->progress_bar_system
);
797 on_project_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer data
)
799 AnjutaPlugin
*plugin
;
800 SymbolDBPlugin
*sdb_plugin
;
802 gdouble fraction
= 0;
804 plugin
= ANJUTA_PLUGIN (data
);
805 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
807 sdb_plugin
->files_count_project_done
++;
808 if (sdb_plugin
->files_count_project_done
>= sdb_plugin
->files_count_project
)
809 message
= g_strdup_printf (_("Generating inheritances..."));
811 message
= g_strdup_printf (_("%d files scanned out of %d"),
812 sdb_plugin
->files_count_project_done
, sdb_plugin
->files_count_project
);
814 if (sdb_plugin
->files_count_project
> 0)
816 fraction
= (gdouble
) sdb_plugin
->files_count_project_done
/
817 (gdouble
) sdb_plugin
->files_count_project
;
819 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
),
821 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
), message
);
822 gtk_widget_show (sdb_plugin
->progress_bar_project
);
827 on_importing_project_end (SymbolDBEngine
*dbe
, gpointer data
)
829 SymbolDBPlugin
*sdb_plugin
;
831 g_return_if_fail (data
!= NULL
);
833 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (data
);
835 DEBUG_PRINT ("on_importing_project_end ()");
837 /* hide the progress bar */
838 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
840 /* re-enable signals receiving on local-view */
841 symbol_db_view_locals_recv_signals_from_engine (
842 SYMBOL_DB_VIEW_LOCALS (sdb_plugin
->dbv_view_tree_locals
),
843 sdb_plugin
->sdbe_project
, TRUE
);
845 /* and on global view */
846 symbol_db_view_recv_signals_from_engine (SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
),
847 sdb_plugin
->sdbe_project
, TRUE
);
849 /* re-active global symbols */
850 symbol_db_view_open (SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
), sdb_plugin
->sdbe_project
);
852 /* disconnect this coz it's not important after the process of importing */
853 g_signal_handlers_disconnect_by_func (dbe
, on_project_single_file_scan_end
, data
);
855 /* disconnect it as we don't need it anymore. */
856 g_signal_handlers_disconnect_by_func (dbe
, on_importing_project_end
, data
);
858 sdb_plugin
->files_count_project_done
= 0;
859 sdb_plugin
->files_count_project
= 0;
863 do_import_system_src_after_abort (AnjutaPlugin
*plugin
,
864 const GPtrArray
*sources_array
)
866 SymbolDBPlugin
*sdb_plugin
;
867 GPtrArray
* languages_array
= NULL
;
868 GPtrArray
*to_scan_array
= NULL
;
869 IAnjutaLanguage
* lang_manager
;
872 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
874 lang_manager
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaLanguage
,
877 DEBUG_PRINT ("do_import_system_src_after_abort %d", sources_array
->len
);
878 /* create array of languages */
879 languages_array
= g_ptr_array_new ();
880 to_scan_array
= g_ptr_array_new ();
884 g_critical ("LanguageManager not found");
888 for (i
=0; i
< sources_array
->len
; i
++)
890 const gchar
*file_mime
;
892 const gchar
*local_filename
;
893 IAnjutaLanguageId lang_id
;
895 local_filename
= g_ptr_array_index (sources_array
, i
);
897 if (local_filename
== NULL
)
899 file_mime
= gnome_vfs_get_mime_type_for_name (local_filename
);
901 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
,
907 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
909 /* test its existence */
910 if (g_file_test (local_filename
, G_FILE_TEST_EXISTS
) == FALSE
)
913 g_ptr_array_add (languages_array
, g_strdup (lang
));
914 g_ptr_array_add (to_scan_array
, g_strdup (local_filename
));
917 symbol_db_parse_aborted_package (sdb_plugin
->sdbs
,
921 /* no need to free the GPtrArray, Huston. They'll be auto-destroyed in that
926 /* we assume that sources_array has already unique elements */
928 do_import_project_src_after_abort (AnjutaPlugin
*plugin
,
929 const GPtrArray
*sources_array
)
931 SymbolDBPlugin
*sdb_plugin
;
932 GPtrArray
* languages_array
= NULL
;
933 GPtrArray
*to_scan_array
= NULL
;
934 IAnjutaLanguage
* lang_manager
;
937 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
940 lang_manager
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaLanguage
,
943 /* create array of languages */
944 languages_array
= g_ptr_array_new ();
945 to_scan_array
= g_ptr_array_new ();
949 g_critical ("LanguageManager not found");
953 for (i
=0; i
< sources_array
->len
; i
++)
955 const gchar
*file_mime
;
957 const gchar
*local_filename
;
958 IAnjutaLanguageId lang_id
;
960 local_filename
= g_ptr_array_index (sources_array
, i
);
962 if (local_filename
== NULL
)
964 file_mime
= gnome_vfs_get_mime_type_for_name (local_filename
);
966 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
,
974 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
976 /* test its existence */
977 if (g_file_test (local_filename
, G_FILE_TEST_EXISTS
) == FALSE
)
982 sdb_plugin
->files_count_project
++;
983 g_ptr_array_add (languages_array
, g_strdup (lang
));
984 g_ptr_array_add (to_scan_array
, g_strdup (local_filename
));
987 /* connect to receive signals on single file scan complete. We'll
988 * update a status bar notifying the user about the status
990 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "single-file-scan-end",
991 G_CALLBACK (on_project_single_file_scan_end
), plugin
);
993 symbol_db_engine_add_new_files (sdb_plugin
->sdbe_project
, sdb_plugin
->project_opened
,
994 sources_array
, languages_array
, TRUE
);
996 g_ptr_array_foreach (languages_array
, (GFunc
)g_free
, NULL
);
997 g_ptr_array_free (languages_array
, TRUE
);
999 g_ptr_array_foreach (to_scan_array
, (GFunc
)g_free
, NULL
);
1000 g_ptr_array_free (to_scan_array
, TRUE
);
1004 do_import_sources (AnjutaPlugin
*plugin
, IAnjutaProjectManager
*pm
,
1005 const gchar
*root_dir
)
1007 SymbolDBPlugin
*sdb_plugin
;
1008 GList
* prj_elements_list
;
1009 GPtrArray
* sources_array
= NULL
;
1010 GPtrArray
* languages_array
= NULL
;
1011 GHashTable
*check_unique_file
;
1012 IAnjutaLanguage
* lang_manager
;
1015 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1017 /* if we're importing first shut off the signal receiving.
1018 * We'll re-enable that on scan-end
1020 symbol_db_view_locals_recv_signals_from_engine (
1021 SYMBOL_DB_VIEW_LOCALS (sdb_plugin
->dbv_view_tree_locals
),
1022 sdb_plugin
->sdbe_project
, FALSE
);
1024 symbol_db_view_recv_signals_from_engine (
1025 SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
),
1026 sdb_plugin
->sdbe_project
, FALSE
);
1028 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "scan-end",
1029 G_CALLBACK (on_importing_project_end
), plugin
);
1031 lang_manager
= anjuta_shell_get_interface (plugin
->shell
, IAnjutaLanguage
,
1036 g_critical ("LanguageManager not found");
1040 prj_elements_list
= ianjuta_project_manager_get_elements (pm
,
1041 IANJUTA_PROJECT_MANAGER_SOURCE
,
1044 /* to speed the things up we must avoid the dups */
1045 check_unique_file
= g_hash_table_new_full (g_str_hash
,
1046 g_str_equal
, g_free
, g_free
);
1048 DEBUG_PRINT ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
1049 DEBUG_PRINT ("Retrieving %d gbf sources of the project...",
1050 g_list_length (prj_elements_list
));
1052 for (i
=0; i
< g_list_length (prj_elements_list
); i
++)
1054 gchar
*local_filename
;
1055 const gchar
*file_mime
;
1057 IAnjutaLanguageId lang_id
;
1060 gnome_vfs_get_local_path_from_uri (g_list_nth_data (
1061 prj_elements_list
, i
));
1063 if (local_filename
== NULL
)
1066 /* check if it's already present in the list. This avoids
1069 if (g_hash_table_lookup (check_unique_file
,
1070 local_filename
) == NULL
)
1072 g_hash_table_insert (check_unique_file
,
1073 g_strdup (local_filename
),
1074 g_strdup (local_filename
));
1078 /* you're a dup! we don't want you */
1079 g_free (local_filename
);
1083 file_mime
= gnome_vfs_get_mime_type_for_name (local_filename
);
1085 lang_id
= ianjuta_language_get_from_mime_type (lang_manager
,
1090 g_free (local_filename
);
1094 lang
= ianjuta_language_get_name (lang_manager
, lang_id
, NULL
);
1095 DEBUG_PRINT ("Language of %s is %s", local_filename
, file_mime
);
1096 /* test its existence */
1097 if (g_file_test (local_filename
, G_FILE_TEST_EXISTS
) == FALSE
)
1099 g_free (local_filename
);
1104 sources_array
= g_ptr_array_new ();
1106 if (!languages_array
)
1107 languages_array
= g_ptr_array_new ();
1109 sdb_plugin
->files_count_project
++;
1110 g_ptr_array_add (sources_array
, local_filename
);
1111 g_ptr_array_add (languages_array
, g_strdup (lang
));
1114 DEBUG_PRINT ("calling symbol_db_engine_add_new_files with root_dir %s",
1117 /* connect to receive signals on single file scan complete. We'll
1118 * update a status bar notifying the user about the status
1120 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
), "single-file-scan-end",
1121 G_CALLBACK (on_project_single_file_scan_end
), plugin
);
1123 symbol_db_engine_add_new_files (sdb_plugin
->sdbe_project
,
1124 sdb_plugin
->project_opened
,
1125 sources_array
, languages_array
, TRUE
);
1127 g_hash_table_unref (check_unique_file
);
1129 g_ptr_array_foreach (sources_array
, (GFunc
)g_free
, NULL
);
1130 g_ptr_array_free (sources_array
, TRUE
);
1132 g_ptr_array_foreach (languages_array
, (GFunc
)g_free
, NULL
);
1133 g_ptr_array_free (languages_array
, TRUE
);
1136 /* add a new project */
1138 on_project_root_added (AnjutaPlugin
*plugin
, const gchar
*name
,
1139 const GValue
*value
, gpointer user_data
)
1141 IAnjutaProjectManager
*pm
;
1142 SymbolDBPlugin
*sdb_plugin
;
1143 const gchar
*root_uri
;
1145 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1147 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1148 IAnjutaProjectManager
, NULL
);
1150 g_free (sdb_plugin
->project_root_uri
);
1151 sdb_plugin
->project_root_uri
= NULL
;
1152 root_uri
= g_value_get_string (value
);
1156 gchar
*root_dir
= gnome_vfs_get_local_path_from_uri (root_uri
);
1157 DEBUG_PRINT ("Symbol-DB: added project root_dir %s, name %s", root_dir
,
1160 /* FIXME: where's the project name itself? */
1161 DEBUG_PRINT ("FIXME: where's the project name itself? ");
1162 sdb_plugin
->project_opened
= g_strdup (root_dir
);
1166 gboolean needs_sources_scan
= FALSE
;
1167 gboolean project_exist
= FALSE
;
1168 GHashTable
* lang_hash
;
1171 lang_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
,
1172 sources_array_free
);
1174 /* is it a fresh-new project? is it an imported project with
1175 * no 'new' symbol-db database but the 'old' one symbol-browser?
1177 if (symbol_db_engine_db_exists (sdb_plugin
->sdbe_project
,
1180 DEBUG_PRINT ("Symbol-DB: project did not exist");
1181 needs_sources_scan
= TRUE
;
1182 project_exist
= FALSE
;
1186 project_exist
= TRUE
;
1189 /* we'll use the same values for db_directory and project_directory */
1190 DEBUG_PRINT ("opening db %s and project_dir %s", root_dir
, root_dir
);
1191 if (symbol_db_engine_open_db (sdb_plugin
->sdbe_project
, root_dir
,
1193 g_error ("Symbol-DB: error in opening db");
1195 /* if project did not exist add a new project */
1196 if (project_exist
== FALSE
)
1198 DEBUG_PRINT ("Symbol-DB: creating new project.");
1199 symbol_db_engine_add_new_project (sdb_plugin
->sdbe_project
,
1200 NULL
, /* still no workspace logic */
1201 sdb_plugin
->project_opened
);
1204 /* we need an import */
1205 if (needs_sources_scan
== TRUE
)
1207 DEBUG_PRINT ("Symbol-DB: importing sources...");
1208 do_import_sources (plugin
, pm
, root_dir
);
1210 else /* no import needed. */
1212 /* we may have aborted the scan of sources ..*/
1213 GPtrArray
*sources_array
= NULL
;
1216 symbol_db_engine_get_files_with_zero_symbols (sdb_plugin
->sdbe_project
);
1218 if (sources_array
!= NULL
&& sources_array
->len
> 0)
1220 /* if we're importing first shut off the signal receiving.
1221 * We'll re-enable that on scan-end
1223 symbol_db_view_locals_recv_signals_from_engine (
1224 SYMBOL_DB_VIEW_LOCALS (sdb_plugin
->dbv_view_tree_locals
),
1225 sdb_plugin
->sdbe_project
, FALSE
);
1227 symbol_db_view_recv_signals_from_engine (
1228 SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
),
1229 sdb_plugin
->sdbe_project
, FALSE
);
1231 g_signal_connect (G_OBJECT (sdb_plugin
->sdbe_project
),
1232 "scan-end", G_CALLBACK (on_importing_project_end
), plugin
);
1234 do_import_project_src_after_abort (plugin
, sources_array
);
1236 g_ptr_array_foreach (sources_array
, (GFunc
)g_free
, NULL
);
1237 g_ptr_array_free (sources_array
, TRUE
);
1240 /* Update the symbols */
1241 symbol_db_engine_update_project_symbols (sdb_plugin
->sdbe_project
,
1244 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin
->progress_bar_project
),
1245 _("Populating symbols' db..."));
1246 id
= g_idle_add ((GSourceFunc
) gtk_progress_bar_pulse
,
1247 sdb_plugin
->progress_bar_project
);
1248 gtk_widget_show (sdb_plugin
->progress_bar_project
);
1250 symbol_db_view_open (SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
),
1251 sdb_plugin
->sdbe_project
);
1252 g_source_remove (id
);
1253 gtk_widget_hide (sdb_plugin
->progress_bar_project
);
1256 sdb_plugin
->project_root_dir
= root_dir
;
1258 g_hash_table_unref (lang_hash
);
1261 sdb_plugin
->project_root_uri
= g_strdup (root_uri
);
1264 g_signal_connect (G_OBJECT (pm
), "element_added",
1265 G_CALLBACK (on_project_element_added
), sdb_plugin
);
1266 g_signal_connect (G_OBJECT (pm
), "element_removed",
1267 G_CALLBACK (on_project_element_removed
), sdb_plugin
);
1270 /* hide it. Default */
1271 /* system tags thing */
1272 gtk_widget_hide (sdb_plugin
->progress_bar_system
);
1274 GPtrArray
*sys_src_array
= NULL
;
1277 symbol_db_engine_get_files_with_zero_symbols (sdb_plugin
->sdbe_globals
);
1279 if (sys_src_array
!= NULL
&& sys_src_array
->len
> 0)
1281 do_import_system_src_after_abort (plugin
, sys_src_array
);
1283 g_ptr_array_foreach (sys_src_array
, (GFunc
)g_free
, NULL
);
1284 g_ptr_array_free (sys_src_array
, TRUE
);
1289 on_project_root_removed (AnjutaPlugin
*plugin
, const gchar
*name
,
1292 IAnjutaProjectManager
*pm
;
1293 SymbolDBPlugin
*sdb_plugin
;
1295 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1296 DEBUG_PRINT ("project_root_removed ()");
1297 /* Disconnect events from project manager */
1299 /* FIXME: There should be a way to ensure that this project manager
1300 * is indeed the one that has opened the project_uri
1302 pm
= anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin
)->shell
,
1303 IAnjutaProjectManager
, NULL
);
1304 g_signal_handlers_disconnect_by_func (G_OBJECT (pm
),
1305 on_project_element_added
,
1307 g_signal_handlers_disconnect_by_func (G_OBJECT (pm
),
1308 on_project_element_removed
,
1311 /* clear locals symbols and the associated cache*/
1312 symbol_db_view_locals_clear_cache (SYMBOL_DB_VIEW_LOCALS (
1313 sdb_plugin
->dbv_view_tree_locals
));
1315 /* clear global symbols */
1316 symbol_db_view_clear_cache (SYMBOL_DB_VIEW (sdb_plugin
->dbv_view_tree
));
1318 /* don't forget to close the project */
1319 symbol_db_engine_close_db (sdb_plugin
->sdbe_project
);
1321 g_free (sdb_plugin
->project_root_uri
);
1322 g_free (sdb_plugin
->project_root_dir
);
1323 g_free (sdb_plugin
->project_opened
);
1324 sdb_plugin
->project_root_uri
= NULL
;
1325 sdb_plugin
->project_root_dir
= NULL
;
1326 sdb_plugin
->project_opened
= NULL
;
1330 symbol_db_activate (AnjutaPlugin
*plugin
)
1332 SymbolDBPlugin
*symbol_db
;
1333 gchar
*anjuta_cache_path
;
1336 DEBUG_PRINT ("SymbolDBPlugin: Activating SymbolDBPlugin plugin ...");
1338 /* Initialize gda library. */
1341 register_stock_icons (plugin
);
1343 symbol_db
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1344 symbol_db
->ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1345 symbol_db
->prefs
= anjuta_shell_get_preferences (plugin
->shell
, NULL
);
1346 symbol_db
->project_opened
= NULL
;
1348 ctags_path
= anjuta_preferences_get (symbol_db
->prefs
, CTAGS_PREFS_KEY
);
1350 if (ctags_path
== NULL
)
1352 g_warning ("ctags is not in preferences. Trying a default one %s",
1354 ctags_path
= g_strdup (CTAGS_PATH
);
1357 /* initialize the session packages to NULL. We'll store there the user
1358 * preferences for the session about global-system packages
1360 symbol_db
->session_packages
= NULL
;
1362 /* create SymbolDBEngine(s) */
1363 symbol_db
->sdbe_project
= symbol_db_engine_new (ctags_path
);
1365 /* the globals one too */
1366 symbol_db
->sdbe_globals
= symbol_db_engine_new (ctags_path
);
1368 g_free (ctags_path
);
1371 anjuta_cache_path
= anjuta_util_get_user_cache_file_path (".", NULL
);
1372 symbol_db_engine_open_db (symbol_db
->sdbe_globals
,
1376 g_free (anjuta_cache_path
);
1378 /* create the object that'll manage the globals population */
1379 symbol_db
->sdbs
= symbol_db_system_new (symbol_db
, symbol_db
->sdbe_globals
);
1381 g_signal_connect (G_OBJECT (symbol_db
->sdbs
), "scan-package-start",
1382 G_CALLBACK (on_system_scan_package_start
), plugin
);
1384 g_signal_connect (G_OBJECT (symbol_db
->sdbs
), "scan-package-end",
1385 G_CALLBACK (on_system_scan_package_end
), plugin
);
1387 g_signal_connect (G_OBJECT (symbol_db
->sdbs
), "single-file-scan-end",
1388 G_CALLBACK (on_system_single_file_scan_end
), plugin
);
1390 /* sets preferences to NULL, it'll be instantiated when required.\ */
1391 symbol_db
->sdbp
= NULL
;
1393 /* Create widgets */
1394 symbol_db
->dbv_main
= gtk_vbox_new(FALSE
, 5);
1395 symbol_db
->dbv_notebook
= gtk_notebook_new();
1396 symbol_db
->progress_bar_project
= gtk_progress_bar_new();
1397 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(symbol_db
->progress_bar_project
),
1398 PANGO_ELLIPSIZE_END
);
1399 g_object_ref (symbol_db
->progress_bar_project
);
1401 symbol_db
->progress_bar_system
= gtk_progress_bar_new();
1402 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(symbol_db
->progress_bar_system
),
1403 PANGO_ELLIPSIZE_END
);
1405 g_object_ref (symbol_db
->progress_bar_system
);
1407 gtk_box_pack_start (GTK_BOX (symbol_db
->dbv_main
), symbol_db
->dbv_notebook
,
1409 gtk_box_pack_start (GTK_BOX (symbol_db
->dbv_main
), symbol_db
->progress_bar_project
,
1411 gtk_box_pack_start (GTK_BOX (symbol_db
->dbv_main
), symbol_db
->progress_bar_system
,
1413 gtk_widget_show_all (symbol_db
->dbv_main
);
1416 symbol_db
->scrolled_locals
= gtk_scrolled_window_new (NULL
, NULL
);
1417 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (symbol_db
->scrolled_locals
),
1419 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (symbol_db
->scrolled_locals
),
1420 GTK_POLICY_AUTOMATIC
,
1421 GTK_POLICY_AUTOMATIC
);
1423 symbol_db
->dbv_view_locals_tab_label
= gtk_label_new (_("Local" ));
1424 symbol_db
->dbv_view_tree_locals
= symbol_db_view_locals_new ();
1425 /* activate signals receiving by default */
1426 symbol_db_view_locals_recv_signals_from_engine (
1427 SYMBOL_DB_VIEW_LOCALS (symbol_db
->dbv_view_tree_locals
),
1428 symbol_db
->sdbe_project
, TRUE
);
1430 g_object_add_weak_pointer (G_OBJECT (symbol_db
->dbv_view_tree_locals
),
1431 (gpointer
)&symbol_db
->dbv_view_tree_locals
);
1432 g_signal_connect (G_OBJECT (symbol_db
->dbv_view_tree_locals
), "row-activated",
1433 G_CALLBACK (on_local_treeview_row_activated
), plugin
);
1435 gtk_container_add (GTK_CONTAINER(symbol_db
->scrolled_locals
),
1436 symbol_db
->dbv_view_tree_locals
);
1439 /* Global symbols */
1440 symbol_db
->scrolled_global
= gtk_scrolled_window_new (NULL
, NULL
);
1441 gtk_scrolled_window_set_shadow_type (
1442 GTK_SCROLLED_WINDOW (symbol_db
->scrolled_global
),
1444 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (symbol_db
->scrolled_global
),
1445 GTK_POLICY_AUTOMATIC
,
1446 GTK_POLICY_AUTOMATIC
);
1448 symbol_db
->dbv_view_tab_label
= gtk_label_new (_("Global" ));
1449 symbol_db
->dbv_view_tree
= symbol_db_view_new ();
1450 g_object_add_weak_pointer (G_OBJECT (symbol_db
->dbv_view_tree
),
1451 (gpointer
)&symbol_db
->dbv_view_tree
);
1452 /* activate signals receiving by default */
1453 symbol_db_view_recv_signals_from_engine (
1454 SYMBOL_DB_VIEW (symbol_db
->dbv_view_tree
),
1455 symbol_db
->sdbe_project
, TRUE
);
1457 g_signal_connect (G_OBJECT (symbol_db
->dbv_view_tree
), "row-activated",
1458 G_CALLBACK (on_global_treeview_row_activated
), plugin
);
1460 g_signal_connect (G_OBJECT (symbol_db
->dbv_view_tree
), "row-expanded",
1461 G_CALLBACK (on_global_treeview_row_expanded
), plugin
);
1463 g_signal_connect (G_OBJECT (symbol_db
->dbv_view_tree
), "row-collapsed",
1464 G_CALLBACK (on_global_treeview_row_collapsed
), plugin
);
1466 gtk_container_add (GTK_CONTAINER(symbol_db
->scrolled_global
),
1467 symbol_db
->dbv_view_tree
);
1469 /* Search symbols */
1470 symbol_db
->dbv_view_tree_search
=
1471 (GtkWidget
*) symbol_db_view_search_new (symbol_db
->sdbe_project
);
1472 symbol_db
->dbv_view_search_tab_label
= gtk_label_new (_("Search" ));
1474 g_signal_connect (G_OBJECT (symbol_db
->dbv_view_tree_search
), "symbol-selected",
1475 G_CALLBACK (on_treesearch_symbol_selected_event
),
1478 g_object_add_weak_pointer (G_OBJECT (symbol_db
->dbv_view_tree_search
),
1479 (gpointer
)&symbol_db
->dbv_view_tree_search
);
1481 /* add the scrolled windows to the notebook */
1482 gtk_notebook_append_page (GTK_NOTEBOOK (symbol_db
->dbv_notebook
),
1483 symbol_db
->scrolled_locals
,
1484 symbol_db
->dbv_view_locals_tab_label
);
1486 gtk_notebook_append_page (GTK_NOTEBOOK (symbol_db
->dbv_notebook
),
1487 symbol_db
->scrolled_global
,
1488 symbol_db
->dbv_view_tab_label
);
1490 gtk_notebook_append_page (GTK_NOTEBOOK (symbol_db
->dbv_notebook
),
1491 symbol_db
->dbv_view_tree_search
,
1492 symbol_db
->dbv_view_search_tab_label
);
1494 gtk_widget_show_all (symbol_db
->dbv_notebook
);
1496 /* setting focus to the tree_view*/
1497 gtk_notebook_set_current_page (GTK_NOTEBOOK (symbol_db
->dbv_notebook
), 0);
1499 symbol_db
->editor_watch_id
=
1500 anjuta_plugin_add_watch (plugin
, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
1501 value_added_current_editor
,
1502 value_removed_current_editor
, NULL
);
1504 anjuta_shell_add_widget (plugin
->shell
, symbol_db
->dbv_main
,
1505 "AnjutaSymbolDB", _("Symbols"),
1506 "symbol-db-plugin-icon",
1507 ANJUTA_SHELL_PLACEMENT_LEFT
, NULL
);
1509 /* set up project directory watch */
1510 symbol_db
->root_watch_id
= anjuta_plugin_add_watch (plugin
,
1511 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
1512 on_project_root_added
,
1513 on_project_root_removed
, NULL
);
1515 /* Determine session state */
1516 g_signal_connect (plugin
->shell
, "load-session",
1517 G_CALLBACK (on_session_load
), plugin
);
1519 g_signal_connect (plugin
->shell
, "save-session",
1520 G_CALLBACK (on_session_save
), plugin
);
1526 symbol_db_deactivate (AnjutaPlugin
*plugin
)
1528 SymbolDBPlugin
*sdb_plugin
;
1530 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (plugin
);
1532 DEBUG_PRINT ("SymbolDBPlugin: Dectivating SymbolDBPlugin plugin ...");
1533 DEBUG_PRINT ("SymbolDBPlugin: destroying engine ...");
1534 g_object_unref (sdb_plugin
->sdbe_project
);
1535 sdb_plugin
->sdbe_project
= NULL
;
1537 /* this must be done *bedore* destroying sdbe_globals */
1538 g_object_unref (sdb_plugin
->sdbs
);
1539 sdb_plugin
->sdbs
= NULL
;
1540 g_free (sdb_plugin
->current_scanned_package
);
1542 g_object_unref (sdb_plugin
->sdbe_globals
);
1543 sdb_plugin
->sdbe_globals
= NULL
;
1545 g_free (sdb_plugin
->project_opened
);
1546 sdb_plugin
->project_opened
= NULL
;
1548 if (sdb_plugin
->session_packages
)
1550 g_list_foreach (sdb_plugin
->session_packages
, (GFunc
)g_free
, NULL
);
1551 g_list_free (sdb_plugin
->session_packages
);
1552 sdb_plugin
->session_packages
= NULL
;
1555 /* disconnect some signals */
1556 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->dbv_view_tree_locals
),
1557 on_local_treeview_row_activated
,
1560 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin
->dbv_view_tree_search
),
1561 on_treesearch_symbol_selected_event
,
1564 /* Ensure all editor cached info are released */
1565 if (sdb_plugin
->editor_connected
)
1567 g_hash_table_foreach (sdb_plugin
->editor_connected
,
1568 on_editor_foreach_disconnect
, plugin
);
1569 g_hash_table_destroy (sdb_plugin
->editor_connected
);
1570 sdb_plugin
->editor_connected
= NULL
;
1573 /* Remove watches */
1574 anjuta_plugin_remove_watch (plugin
, sdb_plugin
->root_watch_id
, FALSE
);
1575 anjuta_plugin_remove_watch (plugin
, sdb_plugin
->editor_watch_id
, TRUE
);
1577 /* Remove widgets: Widgets will be destroyed when dbv_main is removed */
1578 g_object_unref (sdb_plugin
->progress_bar_project
);
1579 g_object_unref (sdb_plugin
->progress_bar_system
);
1580 anjuta_shell_remove_widget (plugin
->shell
, sdb_plugin
->dbv_main
, NULL
);
1582 sdb_plugin
->root_watch_id
= 0;
1583 sdb_plugin
->editor_watch_id
= 0;
1584 sdb_plugin
->dbv_notebook
= NULL
;
1585 sdb_plugin
->scrolled_global
= NULL
;
1586 sdb_plugin
->scrolled_locals
= NULL
;
1587 sdb_plugin
->dbv_view_tree
= NULL
;
1588 sdb_plugin
->dbv_view_tab_label
= NULL
;
1589 sdb_plugin
->dbv_view_tree_locals
= NULL
;
1590 sdb_plugin
->dbv_view_locals_tab_label
= NULL
;
1591 sdb_plugin
->dbv_view_tree_search
= NULL
;
1592 sdb_plugin
->dbv_view_search_tab_label
= NULL
;
1593 sdb_plugin
->progress_bar_project
= NULL
;
1594 sdb_plugin
->progress_bar_system
= NULL
;
1599 symbol_db_finalize (GObject
*obj
)
1601 DEBUG_PRINT ("Symbol-DB finalize");
1602 /* Finalization codes here */
1603 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
1607 symbol_db_dispose (GObject
*obj
)
1609 /* Disposition codes */
1610 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
1614 symbol_db_instance_init (GObject
*obj
)
1616 SymbolDBPlugin
*plugin
= (SymbolDBPlugin
*)obj
;
1618 plugin
->files_count_project_done
= 0;
1619 plugin
->files_count_project
= 0;
1621 plugin
->files_count_system_done
= 0;
1622 plugin
->files_count_system
= 0;
1623 plugin
->current_scanned_package
= NULL
;
1627 symbol_db_class_init (GObjectClass
*klass
)
1629 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
1631 parent_class
= g_type_class_peek_parent (klass
);
1633 plugin_class
->activate
= symbol_db_activate
;
1634 plugin_class
->deactivate
= symbol_db_deactivate
;
1635 klass
->finalize
= symbol_db_finalize
;
1636 klass
->dispose
= symbol_db_dispose
;
1639 static IAnjutaIterable
*
1640 isymbol_manager_search (IAnjutaSymbolManager
*sm
,
1641 IAnjutaSymbolType match_types
,
1642 gboolean include_types
,
1643 IAnjutaSymbolField info_fields
,
1644 const gchar
*match_name
,
1645 gboolean partial_name_match
,
1646 gboolean global_symbols_search
,
1647 gboolean global_tags_search
,
1649 gint results_offset
,
1652 SymbolDBEngineIterator
*iterator
= NULL
;
1653 SymbolDBPlugin
*sdb_plugin
;
1654 SymbolDBEngine
*dbe_project
;
1655 SymbolDBEngine
*dbe_globals
;
1656 GPtrArray
*filter_array
;
1658 gboolean exact_match
= !partial_name_match
;
1660 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (sm
);
1661 dbe_project
= SYMBOL_DB_ENGINE (sdb_plugin
->sdbe_project
);
1662 dbe_globals
= SYMBOL_DB_ENGINE (sdb_plugin
->sdbe_globals
);
1664 if (match_types
& IANJUTA_SYMBOL_TYPE_MAX
)
1666 filter_array
= NULL
;
1670 filter_array
= symbol_db_engine_fill_type_array (match_types
);
1673 if (exact_match
== FALSE
)
1674 pattern
= g_strdup_printf ("%s%%", match_name
);
1676 pattern
= g_strdup_printf ("%s", match_name
);
1678 /* should we lookup for project of system tags? */
1679 /* DEBUG_PRINT ("tags scan [%s] [exact_match %d] [global %d]", pattern,
1680 exact_match, global_symbols_search); */
1682 symbol_db_engine_find_symbol_by_name_pattern_filtered (
1683 global_tags_search
== FALSE
? dbe_project
: dbe_globals
,
1688 global_symbols_search
,
1696 g_ptr_array_foreach (filter_array
, (GFunc
)g_free
, NULL
);
1697 g_ptr_array_free (filter_array
, TRUE
);
1699 return IANJUTA_ITERABLE (iterator
);
1702 static IAnjutaIterable
*
1703 isymbol_manager_get_members (IAnjutaSymbolManager
*sm
,
1704 IAnjutaSymbol
*symbol
,
1705 IAnjutaSymbolField info_fields
,
1706 gboolean global_search
,
1709 SymbolDBEngineIteratorNode
*node
;
1710 SymbolDBPlugin
*sdb_plugin
;
1711 SymbolDBEngine
*dbe
;
1713 SymbolDBEngineIterator
*iterator
;
1715 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (sm
);
1716 dbe
= SYMBOL_DB_ENGINE (sdb_plugin
->sdbe_project
);
1718 node
= SYMBOL_DB_ENGINE_ITERATOR_NODE (symbol
);
1720 sym_id
= symbol_db_engine_iterator_node_get_symbol_id (node
);
1722 iterator
= symbol_db_engine_get_scope_members_by_symbol_id (dbe
,
1727 return IANJUTA_ITERABLE (iterator
);
1730 static IAnjutaIterable
*
1731 isymbol_manager_get_class_parents (IAnjutaSymbolManager
*sm
,
1732 IAnjutaSymbol
*symbol
,
1733 IAnjutaSymbolField info_fields
,
1736 SymbolDBEngineIteratorNode
*node
;
1737 SymbolDBPlugin
*sdb_plugin
;
1738 SymbolDBEngine
*dbe
;
1740 SymbolDBEngineIterator
*iterator
;
1742 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (sm
);
1743 dbe
= SYMBOL_DB_ENGINE (sdb_plugin
->sdbe_project
);
1745 node
= SYMBOL_DB_ENGINE_ITERATOR_NODE (symbol
);
1747 sym_id
= symbol_db_engine_iterator_node_get_symbol_id (node
);
1749 iterator
= symbol_db_engine_get_class_parents_by_symbol_id (dbe
,
1752 return IANJUTA_ITERABLE (iterator
);
1756 isymbol_manager_iface_init (IAnjutaSymbolManagerIface
*iface
)
1758 iface
->search
= isymbol_manager_search
;
1759 iface
->get_members
= isymbol_manager_get_members
;
1760 iface
->get_class_parents
= isymbol_manager_get_class_parents
;
1764 g_list_compare (gconstpointer a
, gconstpointer b
)
1766 return strcmp ((const gchar
*)a
, (const gchar
*)b
);
1770 on_prefs_package_add (SymbolDBPrefs
*sdbp
, const gchar
*package
,
1773 SymbolDBPlugin
*sdb_plugin
;
1775 g_return_if_fail (package
!= NULL
);
1777 DEBUG_PRINT ("on_prefs_package_add");
1779 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
1781 sdb_plugin
->session_packages
= g_list_prepend (sdb_plugin
->session_packages
,
1782 g_strdup (package
));
1786 on_prefs_package_remove (SymbolDBPrefs
*sdbp
, const gchar
*package
,
1789 SymbolDBPlugin
*sdb_plugin
;
1791 g_return_if_fail (package
!= NULL
);
1793 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (user_data
);
1796 DEBUG_PRINT ("on_prefs_package_remove");
1797 if ((item
= g_list_find_custom (sdb_plugin
->session_packages
, package
,
1798 g_list_compare
)) != NULL
)
1800 sdb_plugin
->session_packages
= g_list_remove_link (sdb_plugin
->session_packages
,
1803 /* ok, now think to the item left alone by its friends... */
1804 g_list_foreach (item
, (GFunc
)g_free
, NULL
);
1810 ipreferences_merge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
1812 DEBUG_PRINT ("SymbolDB: ipreferences_merge");
1813 SymbolDBPlugin
*sdb_plugin
;
1815 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (ipref
);
1817 if (sdb_plugin
->sdbp
== NULL
)
1819 sdb_plugin
->sdbp
= symbol_db_prefs_new (sdb_plugin
->sdbs
,
1820 sdb_plugin
->sdbe_project
,
1821 sdb_plugin
->sdbe_globals
,
1823 sdb_plugin
->session_packages
);
1825 /* connect the signals to retrieve package modifications */
1826 g_signal_connect (G_OBJECT (sdb_plugin
->sdbp
), "package-add",
1827 G_CALLBACK (on_prefs_package_add
),
1829 g_signal_connect (G_OBJECT (sdb_plugin
->sdbp
), "package-remove",
1830 G_CALLBACK (on_prefs_package_remove
),
1836 ipreferences_unmerge(IAnjutaPreferences
* ipref
, AnjutaPreferences
* prefs
, GError
** e
)
1838 SymbolDBPlugin
*sdb_plugin
;
1840 sdb_plugin
= ANJUTA_PLUGIN_SYMBOL_DB (ipref
);
1842 if (sdb_plugin
->sdbp
!= NULL
)
1844 g_object_unref (sdb_plugin
->sdbp
);
1845 sdb_plugin
->sdbp
= NULL
;
1850 ipreferences_iface_init(IAnjutaPreferencesIface
* iface
)
1852 DEBUG_PRINT ("SymbolDB: ipreferences_iface_init");
1853 iface
->merge
= ipreferences_merge
;
1854 iface
->unmerge
= ipreferences_unmerge
;
1858 ANJUTA_PLUGIN_BEGIN (SymbolDBPlugin
, symbol_db
);
1859 ANJUTA_PLUGIN_ADD_INTERFACE (isymbol_manager
, IANJUTA_TYPE_SYMBOL_MANAGER
);
1860 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences
, IANJUTA_TYPE_PREFERENCES
);
1863 ANJUTA_SIMPLE_PLUGIN (SymbolDBPlugin
, symbol_db
);