Fix Spanish translation header
[anjuta.git] / plugins / symbol-db / plugin.c
blobf31db20fd57f0d7544a083c6d1ea8464188f4618
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * plugin.c
4 * Copyright (C) Massimo Cora' 2007-2008 <maxcvs@email.it>
5 *
6 * plugin.c is free software.
7 *
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)
11 * any later version.
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.
25 #include <config.h>
26 #include <gio/gio.h>
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/anjuta-project.h>
32 #include <libanjuta/interfaces/ianjuta-document-manager.h>
33 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
34 #include <libanjuta/interfaces/ianjuta-symbol.h>
35 #include <libanjuta/interfaces/ianjuta-project-manager.h>
36 #include <libanjuta/interfaces/ianjuta-project.h>
37 #include <libanjuta/interfaces/ianjuta-file-manager.h>
38 #include <libanjuta/interfaces/ianjuta-file.h>
39 #include <libanjuta/interfaces/ianjuta-file-loader.h>
40 #include <libanjuta/interfaces/ianjuta-editor.h>
41 #include <libanjuta/interfaces/ianjuta-markable.h>
42 #include <libanjuta/interfaces/ianjuta-language.h>
43 #include <libanjuta/interfaces/ianjuta-iterable.h>
44 #include <libanjuta/interfaces/ianjuta-preferences.h>
46 #include "plugin.h"
47 #include "symbol-db-engine.h"
48 #include "symbol-db-views.h"
50 #define ICON_FILE "anjuta-symbol-db-plugin-48.png"
51 #define UI_FILE PACKAGE_DATA_DIR\
52 "/ui/anjuta-symbol-db-plugin.xml"
54 #define BUILDER_FILE PACKAGE_DATA_DIR\
55 "/glade/anjuta-symbol-db.ui"
56 #define BUILDER_ROOT "symbol_prefs"
57 #define ICON_FILE "anjuta-symbol-db-plugin-48.png"
58 #define BUFFER_UPDATE "symboldb-buffer-update"
59 #define PARALLEL_SCAN "symboldb-parallel-scan"
60 #define PREFS_BUFFER_UPDATE "preferences_toggle:bool:1:1:symboldb-buffer-update"
61 #define PREFS_PARALLEL_SCAN "preferences_toggle:bool:1:1:symboldb-parallel-scan"
63 #define TIMEOUT_INTERVAL_SYMBOLS_UPDATE 10
64 #define TIMEOUT_SECONDS_AFTER_LAST_TIP 5
66 #define PROJECT_GLOBALS "/"
67 #define SESSION_SECTION "SymbolDB"
68 #define SESSION_KEY "SystemPackages"
69 #define PROJECT_ROOT_NAME_DEFAULT "localprj"
71 #define ANJUTA_PIXMAP_GOTO_DECLARATION "element-interface"
72 #define ANJUTA_PIXMAP_GOTO_IMPLEMENTATION "element-method"
74 #define ANJUTA_STOCK_GOTO_DECLARATION "element-interface"
75 #define ANJUTA_STOCK_GOTO_IMPLEMENTATION "element-method"
77 #define PREF_SCHEMA "org.gnome.anjuta.symbol-db"
81 static gpointer parent_class;
83 /* signals */
84 enum
86 PROJECT_IMPORT_END,
87 GLOBALS_IMPORT_END,
88 LAST_SIGNAL
91 typedef enum
93 TASK_IMPORT_PROJECT = 1,
94 TASK_IMPORT_PROJECT_AFTER_ABORT,
95 TASK_BUFFER_UPDATE,
96 TASK_ELEMENT_ADDED,
97 TASK_OFFLINE_CHANGES,
98 TASK_PROJECT_UPDATE,
99 TASK_FILE_UPDATE
100 } ProcTask;
102 static unsigned int signals[LAST_SIGNAL] = { 0 };
104 static void
105 register_stock_icons (AnjutaPlugin *plugin)
107 static gboolean registered = FALSE;
109 if (registered)
110 return;
111 registered = TRUE;
113 /* Register stock icons */
114 BEGIN_REGISTER_ICON (plugin);
115 REGISTER_ICON (ICON_FILE, "symbol-db-plugin-icon");
116 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_DECLARATION, ANJUTA_STOCK_GOTO_DECLARATION);
117 REGISTER_ICON_FULL (ANJUTA_PIXMAP_GOTO_IMPLEMENTATION, ANJUTA_STOCK_GOTO_IMPLEMENTATION);
118 END_REGISTER_ICON;
121 static void
122 goto_file_line (AnjutaPlugin *plugin, const gchar *filename, gint lineno)
124 IAnjutaDocumentManager *docman;
125 GFile* file;
127 g_return_if_fail (filename != NULL);
129 DEBUG_PRINT ("going to: file %s, line %d", filename, lineno);
131 /* Go to file and line number */
132 docman = anjuta_shell_get_interface (plugin->shell, IAnjutaDocumentManager,
133 NULL);
134 file = g_file_new_for_path (filename);
135 ianjuta_document_manager_goto_file_line (docman, file, lineno, NULL);
137 g_object_unref (file);
140 /* Find an implementation (if impl == TRUE) or declaration (if impl == FALSE)
141 * from the given symbol iterator.
142 * If current_document != NULL it prefers matches from the currently open document
144 static gchar *
145 find_file_line (IAnjutaIterable *iterator, gboolean impl, const gchar *current_document,
146 gint *line)
148 gchar *path = NULL;
149 gint _line = -1;
153 const gchar *symbol_kind;
154 gboolean is_decl;
155 IAnjutaSymbol *iter_node = IANJUTA_SYMBOL (iterator);
157 if (iter_node == NULL)
159 /* not found or some error occurred */
160 break;
163 symbol_kind = ianjuta_symbol_get_string (iter_node, IANJUTA_SYMBOL_FIELD_KIND, NULL);
164 is_decl = g_strcmp0 (symbol_kind, "prototype") == 0 ||
165 g_strcmp0 (symbol_kind, "interface") == 0;
167 if (is_decl == !impl)
169 GFile *file;
170 gchar *_path;
171 file = ianjuta_symbol_get_file (iter_node, NULL);
172 /* if the path matches the current document we return immidiately */
173 _path = g_file_get_path (file);
174 g_object_unref (file);
175 if (!current_document || g_strcmp0 (_path, current_document) == 0)
177 *line = ianjuta_symbol_get_int (iter_node,
178 IANJUTA_SYMBOL_FIELD_FILE_POS,
179 NULL);
180 g_free (path);
182 return _path;
184 /* we store the first match incase there is no match against the current document */
185 else if (_line == -1)
187 path = _path;
188 _line = ianjuta_symbol_get_int (iter_node,
189 IANJUTA_SYMBOL_FIELD_FILE_POS,
190 NULL);
192 else
194 g_free (_path);
197 } while (ianjuta_iterable_next (iterator, NULL) == TRUE);
199 if (_line != -1)
200 *line = _line;
202 return path;
205 static void
206 goto_file_tag (SymbolDBPlugin *sdb_plugin, const gchar *word,
207 gboolean prefer_implementation)
209 IAnjutaIterable *iterator;
210 gchar *path = NULL;
211 gint line;
212 gint i;
213 gboolean found = FALSE;
214 SymbolDBEngine *engine;
216 for (i = 0; i < 2; i++)
218 if (i == 0)
220 engine = sdb_plugin->sdbe_project;
222 else
224 engine = sdb_plugin->sdbe_globals;
227 iterator = NULL;
228 if (symbol_db_engine_is_connected (engine))
230 iterator = ianjuta_symbol_query_search (sdb_plugin->search_query,
231 word, NULL);
234 if (iterator != NULL && ianjuta_iterable_get_length (iterator, NULL) > 0)
236 gchar *current_document = NULL;
237 /* FIXME: namespaces are not handled here, but they should. */
239 if (IANJUTA_IS_FILE (sdb_plugin->current_editor))
241 GFile *file;
243 if ((file = ianjuta_file_get_file (IANJUTA_FILE (sdb_plugin->current_editor),
244 NULL)))
246 current_document = g_file_get_path (file);
247 g_object_unref (file);
251 path = find_file_line (iterator, prefer_implementation, current_document, &line);
252 if (!path)
254 /* reset iterator */
255 ianjuta_iterable_first (iterator, NULL);
256 path = find_file_line (iterator, !prefer_implementation, current_document,
257 &line);
260 if (path)
262 goto_file_line (ANJUTA_PLUGIN (sdb_plugin), path, line);
263 g_free (path);
264 found = TRUE;
267 g_free (current_document);
270 if (iterator)
271 g_object_unref (iterator);
273 /* have we found it in the project db? */
274 if (found)
275 break;
279 static void
280 on_goto_file_tag_impl_activate (GtkAction *action, SymbolDBPlugin *sdb_plugin)
282 IAnjutaEditor *ed;
283 gchar *word;
285 if (sdb_plugin->current_editor)
287 ed = IANJUTA_EDITOR (sdb_plugin->current_editor);
288 word = ianjuta_editor_get_current_word (ed, NULL);
289 if (word)
291 goto_file_tag (sdb_plugin, word, TRUE);
292 g_free (word);
297 static void
298 on_goto_file_tag_decl_activate (GtkAction *action, SymbolDBPlugin *sdb_plugin)
300 IAnjutaEditor *ed;
301 gchar *word;
303 if (sdb_plugin->current_editor)
305 ed = IANJUTA_EDITOR (sdb_plugin->current_editor);
306 word = ianjuta_editor_get_current_word (ed, NULL);
307 if (word)
309 goto_file_tag (sdb_plugin, word, FALSE);
310 g_free (word);
315 static void
316 on_find_symbol (GtkAction *action, SymbolDBPlugin *sdb_plugin)
318 anjuta_shell_present_widget(ANJUTA_PLUGIN(sdb_plugin)->shell,
319 sdb_plugin->dbv_main, NULL);
321 gtk_notebook_set_current_page (GTK_NOTEBOOK(sdb_plugin->dbv_notebook), 2);
322 gtk_widget_grab_focus (GTK_WIDGET (sdb_plugin->search_entry));
325 static GtkActionEntry actions[] =
327 { "ActionMenuGoto", NULL, N_("_Go to"), NULL, NULL, NULL},
329 "ActionSymbolDBGotoDecl",
330 ANJUTA_STOCK_GOTO_DECLARATION,
331 N_("Tag De_claration"),
332 "<shift><control>d",
333 N_("Go to symbol declaration"),
334 G_CALLBACK (on_goto_file_tag_decl_activate)
337 "ActionSymbolDBGotoImpl",
338 ANJUTA_STOCK_GOTO_IMPLEMENTATION,
339 /* Translators: Go to the line where the tag is implemented */
340 N_("Tag _Implementation"),
341 "<control>d",
342 N_("Go to symbol definition"),
343 G_CALLBACK (on_goto_file_tag_impl_activate)
347 static GtkActionEntry actions_search[] = {
349 "ActionEditSearchFindSymbol", GTK_STOCK_FIND, N_("_Find Symbol…"),
350 "<control>l", N_("Find Symbol"),
351 G_CALLBACK (on_find_symbol)
355 static gboolean
356 editor_buffer_symbols_update (IAnjutaEditor *editor, SymbolDBPlugin *sdb_plugin)
358 gchar *current_buffer = NULL;
359 gsize buffer_size = 0;
360 GFile* file;
361 gchar * local_path;
362 GPtrArray *real_files_list;
363 GPtrArray *text_buffers;
364 GPtrArray *buffer_sizes;
365 gint i;
366 gint proc_id ;
368 /* we won't proceed with the updating of the symbols if we didn't type in
369 anything */
371 if (sdb_plugin->need_symbols_update == FALSE)
372 return FALSE;
374 if (editor)
376 buffer_size = ianjuta_editor_get_length (editor, NULL);
377 current_buffer = ianjuta_editor_get_text_all (editor, NULL);
379 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
381 else
382 return FALSE;
384 if (file == NULL)
385 return FALSE;
387 /* take the path reference */
388 local_path = g_file_get_path (file);
390 /* ok that's good. Let's have a last check: is the current file present
391 * on the buffer_update_files?
393 for (i = 0; i < sdb_plugin->buffer_update_files->len; i++)
395 if (g_strcmp0 (g_ptr_array_index (sdb_plugin->buffer_update_files, i),
396 local_path) == 0)
398 /* hey we found it */
399 /* something is already scanning this buffer file. Drop the procedure now. */
400 DEBUG_PRINT ("something is already scanning the file %s", local_path);
401 return FALSE;
405 real_files_list = g_ptr_array_new_with_free_func (g_free);
406 g_ptr_array_add (real_files_list, local_path);
408 text_buffers = g_ptr_array_new ();
409 g_ptr_array_add (text_buffers, current_buffer);
411 buffer_sizes = g_ptr_array_new ();
412 g_ptr_array_add (buffer_sizes, GINT_TO_POINTER (buffer_size));
415 proc_id = 0;
416 if (symbol_db_engine_is_connected (sdb_plugin->sdbe_project))
418 proc_id = symbol_db_engine_update_buffer_symbols (sdb_plugin->sdbe_project,
419 sdb_plugin->project_opened,
420 real_files_list,
421 text_buffers,
422 buffer_sizes);
425 if (proc_id > 0)
427 /* good. All is ready for a buffer scan. Add the file_scan into the arrays */
428 gchar * local_path_dup = g_strdup (local_path);
429 g_ptr_array_add (sdb_plugin->buffer_update_files, local_path_dup);
430 /* add the id too */
431 g_ptr_array_add (sdb_plugin->buffer_update_ids, GINT_TO_POINTER (proc_id));
433 /* add a task so that scan_end_manager can manage this */
434 g_tree_insert (sdb_plugin->proc_id_tree, GINT_TO_POINTER (proc_id),
435 GINT_TO_POINTER (TASK_BUFFER_UPDATE));
437 if(sdb_plugin->editors){
438 g_hash_table_insert(sdb_plugin->editors, GINT_TO_POINTER (proc_id), editor);
442 g_ptr_array_unref (real_files_list);
443 g_free (current_buffer);
444 g_object_unref (file);
446 /* no need to free local_path, it'll be automatically freed later by the buffer_update
447 * function */
449 if(sdb_plugin->buffer_update_files->len > 0)
450 sdb_plugin->need_symbols_update = TRUE;
452 return !sdb_plugin->need_symbols_update;
454 static gboolean
455 on_editor_buffer_symbols_update_timeout (gpointer user_data)
457 SymbolDBPlugin *sdb_plugin;
458 gdouble seconds_elapsed;
460 g_return_val_if_fail (user_data != NULL, FALSE);
462 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
463 if (sdb_plugin->current_editor == NULL)
465 sdb_plugin->buf_update_timeout_id = 0;
466 return FALSE;
469 /* check the timer. If it's elapsed enought time since the last time the user
470 * typed in something, than proceed with updating, elsewhere don't do nothing
472 if (sdb_plugin->update_timer == NULL)
473 return TRUE;
475 seconds_elapsed = g_timer_elapsed (sdb_plugin->update_timer, NULL);
477 if (seconds_elapsed < TIMEOUT_SECONDS_AFTER_LAST_TIP)
478 return TRUE;
480 editor_buffer_symbols_update (IANJUTA_EDITOR (sdb_plugin->current_editor),
481 sdb_plugin);
483 return TRUE;
486 static void
487 on_editor_buffer_symbol_update_scan_end (SymbolDBEngine *dbe, gint process_id,
488 gpointer data)
490 SymbolDBPlugin *sdb_plugin;
491 gint i;
493 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);
495 /* search for the proc id */
496 for (i = 0; i < sdb_plugin->buffer_update_ids->len; i++)
498 if (g_ptr_array_index (sdb_plugin->buffer_update_ids, i) == GINT_TO_POINTER (process_id))
500 /* hey we found it */
501 /* remove both the items */
502 g_ptr_array_remove_index (sdb_plugin->buffer_update_ids, i);
504 g_ptr_array_remove_index (sdb_plugin->buffer_update_files, i);
506 /* no need to free the string coz the g_ptr_array is built with
507 * g_ptr_array_new_with_free_func (g_free)
512 IAnjutaEditor *editor = g_hash_table_lookup(sdb_plugin->editors, GINT_TO_POINTER (process_id));
513 g_hash_table_remove(sdb_plugin->editors, GINT_TO_POINTER (process_id));
515 if (!editor)
516 return;
518 /* was the updating of view-locals symbols blocked while we were scanning?
519 * e.g. was the editor switched? */
520 if (sdb_plugin->buffer_update_semaphore == TRUE)
522 GFile *file;
523 gchar *local_path;
524 gboolean tags_update;
525 if (!IANJUTA_IS_EDITOR (editor))
526 return;
528 file = ianjuta_file_get_file (IANJUTA_FILE (editor),
529 NULL);
531 if (file == NULL)
532 return;
534 local_path = g_file_get_path (file);
536 if (local_path == NULL)
538 g_critical ("local_path == NULL");
539 return;
542 /* add a default timeout to the updating of buffer symbols */
543 tags_update = g_settings_get_boolean (sdb_plugin->settings, BUFFER_UPDATE);
545 if (tags_update)
547 sdb_plugin->buf_update_timeout_id =
548 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
549 on_editor_buffer_symbols_update_timeout,
550 sdb_plugin);
553 g_free (local_path);
554 sdb_plugin->buffer_update_semaphore = FALSE;
558 static void
559 on_editor_destroy (SymbolDBPlugin *sdb_plugin, IAnjutaEditor *editor)
561 if (!sdb_plugin->editor_connected)
563 DEBUG_PRINT ("%s", "on_editor_destroy (): returning….");
564 return;
567 g_hash_table_remove (sdb_plugin->editor_connected, G_OBJECT (editor));
569 if (g_hash_table_size (sdb_plugin->editor_connected) <= 0)
571 DEBUG_PRINT ("%s", "displaying nothing…");
572 if (sdb_plugin->file_model)
573 g_object_set (sdb_plugin->file_model, "file-path", NULL, NULL);
577 static void
578 on_editor_update_ui (IAnjutaEditor *editor, SymbolDBPlugin *sdb_plugin)
580 g_timer_reset (sdb_plugin->update_timer);
583 static void
584 on_code_added (IAnjutaEditor *editor, IAnjutaIterable *position, gchar *code,
585 SymbolDBPlugin *sdb_plugin)
587 IAnjutaEditor *old_editor = sdb_plugin->current_editor;
588 sdb_plugin->current_editor = editor;
589 sdb_plugin->need_symbols_update = TRUE;
590 editor_buffer_symbols_update (editor, sdb_plugin);
591 sdb_plugin->current_editor = old_editor;
594 static void
595 on_char_added (IAnjutaEditor *editor, IAnjutaIterable *position, gchar ch,
596 SymbolDBPlugin *sdb_plugin)
598 g_timer_reset (sdb_plugin->update_timer);
600 /* Update when the user enters a newline */
601 if (ch == '\n')
602 sdb_plugin->need_symbols_update = TRUE;
605 static void
606 on_editor_saved (IAnjutaEditor *editor, GFile* file,
607 SymbolDBPlugin *sdb_plugin)
609 const gchar *old_uri;
610 gchar *local_filename;
611 gchar *saved_uri;
612 GPtrArray *files_array;
613 gint proc_id;
614 gint i;
616 local_filename = g_file_get_path (file);
617 /* Verify that it's local file */
618 g_return_if_fail (local_filename != NULL);
620 saved_uri = g_file_get_uri (file);
622 for (i = 0; i < sdb_plugin->buffer_update_files->len; i++)
624 if (g_strcmp0 (g_ptr_array_index (sdb_plugin->buffer_update_files, i),
625 local_filename) == 0)
627 DEBUG_PRINT ("already scanning");
628 /* something is already scanning this buffer file. Drop the procedure now. */
629 return;
633 files_array = g_ptr_array_new();
634 g_ptr_array_add (files_array, local_filename);
635 /* no need to free local_filename now */
637 if (!sdb_plugin->editor_connected)
638 return;
640 old_uri = g_hash_table_lookup (sdb_plugin->editor_connected, editor);
642 if (old_uri && strlen (old_uri) <= 0)
643 old_uri = NULL;
645 /* files_array will be freed once updating has taken place */
646 proc_id = 0;
647 if (symbol_db_engine_is_connected (sdb_plugin->sdbe_project))
649 proc_id = symbol_db_engine_update_files_symbols (sdb_plugin->sdbe_project,
650 sdb_plugin->project_root_dir, files_array, TRUE);
653 if (proc_id > 0)
655 /* add a task so that scan_end_manager can manage this */
656 g_tree_insert (sdb_plugin->proc_id_tree, GINT_TO_POINTER (proc_id),
657 GINT_TO_POINTER (TASK_FILE_UPDATE));
660 g_hash_table_insert (sdb_plugin->editor_connected, editor,
661 g_strdup (saved_uri));
663 /* if we saved it we shouldn't update a second time */
664 sdb_plugin->need_symbols_update = FALSE;
666 on_editor_update_ui (editor, sdb_plugin);
667 g_free (saved_uri);
670 static void
671 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
672 const GValue *value, gpointer data)
674 gchar *uri;
675 gboolean tags_update;
676 GFile* file;
677 gchar *local_path;
678 GObject *editor;
679 SymbolDBPlugin *sdb_plugin;
681 editor = g_value_get_object (value);
682 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
683 if (sdb_plugin->session_loading)
685 return;
687 else
688 DEBUG_PRINT ("%s", "Updating symbols");
690 if (!sdb_plugin->editor_connected)
692 sdb_plugin->editor_connected = g_hash_table_new_full (g_direct_hash,
693 g_direct_equal,
694 NULL, g_free);
696 sdb_plugin->current_editor = editor;
698 if (!sdb_plugin->editors)
700 sdb_plugin->editors = g_hash_table_new (NULL, NULL);
703 if (!IANJUTA_IS_EDITOR (editor))
704 return;
706 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
708 if (file == NULL)
709 return;
711 local_path = g_file_get_path (file);
712 uri = g_file_get_uri (file);
714 if (local_path == NULL)
716 g_critical ("local_path == NULL");
717 return;
720 /* we can have a weird behaviour here if we're not paying the right attention:
721 * A timeout scan could have been launched and a millisecond later the user could
722 * have switched editor: we'll be getting the symbol inserted in the previous
723 * editor into the new one's view.
725 if (sdb_plugin->buffer_update_files->len > 0)
727 sdb_plugin->buffer_update_semaphore = TRUE;
729 else
731 g_object_set (sdb_plugin->file_model, "file-path", local_path, NULL);
733 /* add a default timeout to the updating of buffer symbols */
734 tags_update = g_settings_get_boolean (sdb_plugin->settings, BUFFER_UPDATE);
737 if (tags_update)
739 sdb_plugin->buf_update_timeout_id =
740 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
741 on_editor_buffer_symbols_update_timeout,
742 plugin);
746 if (g_hash_table_lookup (sdb_plugin->editor_connected, editor) == NULL)
748 g_object_weak_ref (G_OBJECT (editor),
749 (GWeakNotify) (on_editor_destroy),
750 sdb_plugin);
751 if (uri)
753 g_hash_table_insert (sdb_plugin->editor_connected, editor,
754 g_strdup (uri));
756 else
758 g_hash_table_insert (sdb_plugin->editor_connected, editor,
759 g_strdup (""));
762 g_signal_connect (G_OBJECT (editor), "saved",
763 G_CALLBACK (on_editor_saved),
764 sdb_plugin);
765 g_signal_connect (G_OBJECT (editor), "char-added",
766 G_CALLBACK (on_char_added),
767 sdb_plugin);
768 g_signal_connect (G_OBJECT (editor), "code-changed",
769 G_CALLBACK (on_code_added),
770 sdb_plugin);
771 g_signal_connect (G_OBJECT(editor), "update_ui",
772 G_CALLBACK (on_editor_update_ui),
773 sdb_plugin);
775 g_free (uri);
776 g_free (local_path);
778 sdb_plugin->need_symbols_update = FALSE;
781 static void
782 on_editor_foreach_disconnect (gpointer key, gpointer value, gpointer user_data)
784 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
785 G_CALLBACK (on_editor_saved),
786 user_data);
787 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
788 G_CALLBACK (on_editor_update_ui),
789 user_data);
790 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
791 G_CALLBACK (on_char_added),
792 user_data);
793 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
794 G_CALLBACK (on_code_added),
795 user_data);
796 g_object_weak_unref (G_OBJECT(key),
797 (GWeakNotify) (on_editor_destroy),
798 user_data);
801 static gboolean
802 same_editor (gpointer key, gpointer value, gpointer user_data)
804 return value == user_data;
807 static void
808 value_removed_current_editor (AnjutaPlugin *plugin,
809 const char *name, gpointer data)
811 SymbolDBPlugin *sdb_plugin;
813 sdb_plugin = (SymbolDBPlugin *) plugin;
815 DEBUG_PRINT ("%s", "value_removed_current_editor ()");
816 /* let's remove the timeout for symbols refresh */
817 if (sdb_plugin->buf_update_timeout_id)
818 g_source_remove (sdb_plugin->buf_update_timeout_id);
819 sdb_plugin->buf_update_timeout_id = 0;
820 sdb_plugin->need_symbols_update = FALSE;
822 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
825 /* Remove editor from list of editors */
826 if(sdb_plugin->editors)
827 g_hash_table_foreach_remove (sdb_plugin->editors, same_editor, sdb_plugin->current_editor);
829 sdb_plugin->current_editor = NULL;
833 * Perform the real add to the db and also checks that no dups are inserted.
834 * Return the real number of files added or -1 on error.
836 static gint
837 do_add_new_files (SymbolDBPlugin *sdb_plugin, const GPtrArray *sources_array,
838 ProcTask task)
840 GPtrArray* languages_array = NULL;
841 GPtrArray* to_scan_array = NULL;
842 GHashTable* check_unique_file_hash = NULL;
843 IAnjutaLanguage* lang_manager;
844 AnjutaPlugin *plugin;
845 gint added_num;
846 gint i;
847 gint proc_id;
849 plugin = ANJUTA_PLUGIN (sdb_plugin);
851 /* create array of languages and the wannabe scanned files */
852 languages_array = g_ptr_array_new_with_free_func (g_free);
853 to_scan_array = g_ptr_array_new_with_free_func (g_free);
855 /* to speed the things up we must avoid the dups */
856 check_unique_file_hash = g_hash_table_new_full (g_str_hash,
857 g_str_equal, NULL, NULL);
859 lang_manager = anjuta_shell_get_interface (plugin->shell, IAnjutaLanguage,
860 NULL);
862 if (!lang_manager)
864 g_critical ("LanguageManager not found");
865 return -1;
868 for (i=0; i < sources_array->len; i++)
870 const gchar *file_mime;
871 const gchar *lang;
872 const gchar *local_filename;
873 GFile *gfile;
874 GFileInfo *gfile_info;
875 IAnjutaLanguageId lang_id;
877 if ( (local_filename = g_ptr_array_index (sources_array, i)) == NULL)
878 continue;
880 if ((gfile = g_file_new_for_path (local_filename)) == NULL)
881 continue;
883 gfile_info = g_file_query_info (gfile,
884 "standard::content-type",
885 G_FILE_QUERY_INFO_NONE,
886 NULL,
887 NULL);
888 if (gfile_info == NULL)
890 g_object_unref (gfile);
891 continue;
894 /* check if it's already present in the list. This avoids
895 * duplicates.
897 if (g_hash_table_lookup (check_unique_file_hash,
898 local_filename) == NULL)
900 g_hash_table_insert (check_unique_file_hash,
901 (gpointer)local_filename,
902 (gpointer)local_filename);
904 else
906 /* you're a dup! we don't want you */
907 continue;
910 file_mime = g_file_info_get_attribute_string (gfile_info,
911 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
913 lang_id = ianjuta_language_get_from_mime_type (lang_manager,
914 file_mime, NULL);
916 if (!lang_id)
918 g_object_unref (gfile);
919 g_object_unref (gfile_info);
920 continue;
923 lang = ianjuta_language_get_name (lang_manager, lang_id, NULL);
925 /* test its existence */
926 if (g_file_test (local_filename, G_FILE_TEST_EXISTS) == FALSE)
928 g_object_unref (gfile);
929 g_object_unref (gfile_info);
930 continue;
933 /* ok, we've just tested that the local_filename does exist.
934 * We can safely add it to the array.
936 g_ptr_array_add (languages_array, g_strdup (lang));
937 g_ptr_array_add (to_scan_array, g_strdup (local_filename));
938 g_object_unref (gfile);
939 g_object_unref (gfile_info);
942 /* last but not least check if we had some files in that GPtrArray. It that's not
943 * the case just pass over
945 proc_id = 0;
946 if (to_scan_array->len > 0)
948 proc_id = symbol_db_engine_add_new_files_full_async (sdb_plugin->sdbe_project,
949 sdb_plugin->project_opened, "1.0", to_scan_array, languages_array,
950 TRUE);
953 if (proc_id > 0)
955 /* insert the proc id associated within the task */
956 g_tree_insert (sdb_plugin->proc_id_tree, GINT_TO_POINTER (proc_id),
957 GINT_TO_POINTER (task));
960 /* get the real added number of files */
961 added_num = to_scan_array->len;
963 g_ptr_array_unref (languages_array);
964 g_ptr_array_unref (to_scan_array);
966 g_hash_table_destroy (check_unique_file_hash);
968 return proc_id > 0 ? added_num : -1;
971 static void
972 on_project_element_added (IAnjutaProjectManager *pm, GFile *gfile,
973 SymbolDBPlugin *sdb_plugin)
975 gchar *filename;
976 gint real_added;
977 GPtrArray *files_array;
979 g_return_if_fail (sdb_plugin->project_root_uri != NULL);
980 g_return_if_fail (sdb_plugin->project_root_dir != NULL);
982 filename = g_file_get_path (gfile);
984 files_array = g_ptr_array_new_with_free_func (g_free);
985 g_ptr_array_add (files_array, filename);
987 sdb_plugin->is_adding_element = TRUE;
989 /* use a custom function to add the files to db */
990 real_added = do_add_new_files (sdb_plugin, files_array, TASK_ELEMENT_ADDED);
991 if (real_added <= 0)
993 sdb_plugin->is_adding_element = FALSE;
996 g_ptr_array_unref (files_array);
999 static void
1000 on_project_element_removed (IAnjutaProjectManager *pm, GFile *gfile,
1001 SymbolDBPlugin *sdb_plugin)
1003 gchar *filename;
1005 if (!sdb_plugin->project_root_uri)
1006 return;
1008 filename = g_file_get_path (gfile);
1010 if (filename)
1012 DEBUG_PRINT ("%s", "on_project_element_removed");
1013 symbol_db_engine_remove_file (sdb_plugin->sdbe_project,
1014 sdb_plugin->project_root_dir,
1015 symbol_db_util_get_file_db_path (sdb_plugin->sdbe_project,
1016 filename));
1018 g_free (filename);
1022 static void
1023 on_system_scan_package_start (SymbolDBEngine *dbe, guint num_files,
1024 const gchar *package, gpointer user_data)
1026 SymbolDBPlugin *sdb_plugin;
1027 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
1029 sdb_plugin->files_count_system_done = 0;
1030 sdb_plugin->files_count_system += num_files;
1033 /* show the global bar */
1034 gtk_widget_show (sdb_plugin->progress_bar_system);
1035 if (sdb_plugin->current_scanned_package != NULL)
1036 g_free (sdb_plugin->current_scanned_package);
1037 sdb_plugin->current_scanned_package = g_strdup (package);
1039 DEBUG_PRINT ("********************* START [%s] with n %d files ", package, num_files);
1042 static void
1043 on_system_scan_package_end (SymbolDBEngine *dbe, const gchar *package,
1044 gpointer user_data)
1046 SymbolDBPlugin *sdb_plugin;
1047 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
1049 DEBUG_PRINT ("******************** END () [%s]", package);
1051 /* hide the progress bar */
1052 gtk_widget_hide (sdb_plugin->progress_bar_system);
1054 sdb_plugin->files_count_system_done = 0;
1055 sdb_plugin->files_count_system = 0;
1058 static void
1059 on_system_single_file_scan_end (SymbolDBEngine *dbe, gpointer data)
1061 AnjutaPlugin *plugin;
1062 SymbolDBPlugin *sdb_plugin;
1063 gchar *message;
1064 gdouble fraction = 0;
1066 plugin = ANJUTA_PLUGIN (data);
1067 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
1069 sdb_plugin->files_count_system_done++;
1070 if (sdb_plugin->files_count_system_done >= sdb_plugin->files_count_system)
1072 message = g_strdup_printf (_("%s: Generating inheritances…"),
1073 sdb_plugin->current_scanned_package);
1075 else
1077 /* Translators: %s is the name of a system library */
1078 message = g_strdup_printf (ngettext ("%s: %d file scanned out of %d", "%s: %d files scanned out of %d", sdb_plugin->files_count_system_done),
1079 sdb_plugin->current_scanned_package,
1080 sdb_plugin->files_count_system_done,
1081 sdb_plugin->files_count_system);
1084 if (sdb_plugin->files_count_system > 0)
1086 fraction = (gdouble) sdb_plugin->files_count_system_done /
1087 (gdouble) sdb_plugin->files_count_system;
1089 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_system),
1090 fraction);
1091 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_system), message);
1093 g_free (message);
1096 static void
1097 on_project_single_file_scan_end (SymbolDBEngine *dbe, gpointer data)
1099 AnjutaPlugin *plugin;
1100 SymbolDBPlugin *sdb_plugin;
1101 gchar *message;
1102 gdouble fraction = 0;
1104 plugin = ANJUTA_PLUGIN (data);
1105 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
1107 sdb_plugin->files_count_project_done++;
1108 if (sdb_plugin->files_count_project_done >= sdb_plugin->files_count_project)
1109 message = g_strdup_printf (_("Generating inheritances…"));
1110 else
1111 message = g_strdup_printf (ngettext ("%d file scanned out of %d", "%d files scanned out of %d", sdb_plugin->files_count_project_done),
1112 sdb_plugin->files_count_project_done, sdb_plugin->files_count_project);
1114 if (sdb_plugin->files_count_project > 0)
1116 fraction = (gdouble) sdb_plugin->files_count_project_done /
1117 (gdouble) sdb_plugin->files_count_project;
1118 if (fraction > 1.0)
1119 fraction = 1.0;
1121 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project),
1122 fraction);
1123 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project), message);
1124 gtk_widget_show (sdb_plugin->progress_bar_project);
1125 g_free (message);
1128 static void
1129 clear_project_progress_bar (SymbolDBEngine *dbe, gpointer data)
1131 SymbolDBPlugin *sdb_plugin;
1133 g_return_if_fail (data != NULL);
1135 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);
1137 /* hide the progress bar */
1138 gtk_widget_hide (sdb_plugin->progress_bar_project);
1141 static void
1142 on_check_offline_single_file_scan_end (SymbolDBEngine *dbe, gpointer data)
1144 on_project_single_file_scan_end (dbe, data);
1147 /* note the *system* word in the function */
1148 static void
1149 do_import_system_sources_after_abort (SymbolDBPlugin *sdb_plugin,
1150 const GPtrArray *sources_array)
1152 AnjutaPlugin *plugin;
1153 GPtrArray* languages_array = NULL;
1154 GPtrArray *to_scan_array = NULL;
1155 IAnjutaLanguage* lang_manager;
1156 gint i;
1158 plugin = ANJUTA_PLUGIN (sdb_plugin);
1160 lang_manager = anjuta_shell_get_interface (plugin->shell, IAnjutaLanguage,
1161 NULL);
1163 /* create array of languages */
1164 languages_array = g_ptr_array_new_with_free_func (g_free);
1165 to_scan_array = g_ptr_array_new_with_free_func (g_free);
1167 if (!lang_manager)
1169 g_critical ("LanguageManager not found");
1170 return;
1173 for (i=0; i < sources_array->len; i++)
1175 const gchar *file_mime;
1176 const gchar *lang;
1177 const gchar *local_filename;
1178 GFile *gfile;
1179 GFileInfo *gfile_info;
1180 IAnjutaLanguageId lang_id;
1182 local_filename = g_ptr_array_index (sources_array, i);
1184 if (local_filename == NULL)
1185 continue;
1187 gfile = g_file_new_for_path (local_filename);
1188 if (gfile == NULL)
1189 continue;
1191 gfile_info = g_file_query_info (gfile,
1192 "*",
1193 G_FILE_QUERY_INFO_NONE,
1194 NULL,
1195 NULL);
1196 if (gfile_info == NULL)
1198 g_object_unref (gfile);
1199 continue;
1202 file_mime = g_file_info_get_attribute_string (gfile_info,
1203 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
1205 lang_id = ianjuta_language_get_from_mime_type (lang_manager,
1206 file_mime, NULL);
1208 if (!lang_id)
1210 g_object_unref (gfile);
1211 g_object_unref (gfile_info);
1212 continue;
1215 lang = ianjuta_language_get_name (lang_manager, lang_id, NULL);
1217 /* test its existence */
1218 if (g_file_test (local_filename, G_FILE_TEST_EXISTS) == FALSE)
1220 g_object_unref (gfile);
1221 g_object_unref (gfile_info);
1222 continue;
1225 g_ptr_array_add (languages_array, g_strdup (lang));
1226 g_ptr_array_add (to_scan_array, g_strdup (local_filename));
1227 g_object_unref (gfile);
1228 g_object_unref (gfile_info);
1231 /* FIXME HERE currently disabled */
1232 #if 0
1233 symbol_db_system_parse_aborted_package (sdb_plugin->sdbs,
1234 to_scan_array,
1235 languages_array);
1236 #endif
1238 g_ptr_array_unref(to_scan_array);
1239 g_ptr_array_unref(languages_array);
1242 /* we assume that sources_array has already unique elements */
1243 /* note the *project* word in the function */
1244 static void
1245 do_import_project_sources_after_abort (SymbolDBPlugin *sdb_plugin,
1246 const GPtrArray *sources_array)
1248 gint real_added;
1250 sdb_plugin->is_project_importing = TRUE;
1252 /* connect to receive signals on single file scan complete. We'll
1253 * update a status bar notifying the user about the status
1255 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "single-file-scan-end",
1256 G_CALLBACK (on_project_single_file_scan_end), sdb_plugin);
1258 real_added = do_add_new_files (sdb_plugin, sources_array,
1259 TASK_IMPORT_PROJECT_AFTER_ABORT);
1260 if (real_added <= 0)
1262 sdb_plugin->is_project_importing = FALSE;
1264 else
1266 sdb_plugin->files_count_project += real_added;
1270 static void
1271 do_import_project_sources (SymbolDBPlugin *sdb_plugin, IAnjutaProjectManager *pm,
1272 const gchar *root_dir)
1274 GList* prj_elements_list;
1275 GPtrArray* sources_array;
1276 gint i;
1277 gint real_added;
1279 prj_elements_list = ianjuta_project_manager_get_elements (pm,
1280 ANJUTA_PROJECT_SOURCE | ANJUTA_PROJECT_PROJECT,
1281 NULL);
1283 if (prj_elements_list == NULL)
1285 g_warning ("No sources found within this project");
1286 return;
1289 /* if we're importing first shut off the signal receiving.
1290 * We'll re-enable that on scan-end
1292 sdb_plugin->is_project_importing = TRUE;
1293 DEBUG_PRINT ("Retrieving %d gbf sources of the project…",
1294 g_list_length (prj_elements_list));
1296 /* create the storage array. The file names will be strdup'd and put here.
1297 * This is just a sort of GList -> GPtrArray conversion.
1299 sources_array = g_ptr_array_new_with_free_func (g_free);
1300 for (i=0; i < g_list_length (prj_elements_list); i++)
1302 gchar *local_filename;
1303 GFile *gfile = NULL;
1305 gfile = g_list_nth_data (prj_elements_list, i);
1307 if ((local_filename = g_file_get_path (gfile)) == NULL)
1309 continue;
1312 g_ptr_array_add (sources_array, local_filename);
1315 /* connect to receive signals on single file scan complete. We'll
1316 * update a status bar notifying the user about the status
1318 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "single-file-scan-end",
1319 G_CALLBACK (on_project_single_file_scan_end), sdb_plugin);
1321 real_added = do_add_new_files (sdb_plugin, sources_array, TASK_IMPORT_PROJECT);
1322 if (real_added <= 0)
1324 sdb_plugin->is_project_importing = FALSE;
1326 sdb_plugin->files_count_project += real_added;
1329 /* free the ptr array */
1330 g_ptr_array_unref (sources_array);
1332 /* and the list of project files */
1333 g_list_foreach (prj_elements_list, (GFunc) g_object_unref, NULL);
1334 g_list_free (prj_elements_list);
1338 * This function will call do_import_project_sources_after_abort ().
1339 * The list of files for sysstem packages enqueued on the first scan aren't
1340 * persisted on session for later retrieval. So we can only rely
1341 * on fixing the zero-symbols file.
1343 static void
1344 do_import_system_sources (SymbolDBPlugin *sdb_plugin)
1346 /* the resume thing */
1347 GPtrArray *sys_src_array = NULL;
1348 sys_src_array =
1349 symbol_db_util_get_files_with_zero_symbols (sdb_plugin->sdbe_globals);
1351 if (sys_src_array != NULL && sys_src_array->len > 0)
1353 do_import_system_sources_after_abort (sdb_plugin, sys_src_array);
1355 g_ptr_array_unref (sys_src_array);
1360 * @return TRUE if a scan is in progress, FALSE elsewhere.
1362 static gboolean
1363 do_update_project_symbols (SymbolDBPlugin *sdb_plugin, const gchar *root_dir)
1365 gint proc_id;
1366 /* Update the symbols */
1367 proc_id = symbol_db_engine_update_project_symbols (sdb_plugin->sdbe_project,
1368 root_dir, FALSE);
1369 if (proc_id > 0)
1371 sdb_plugin->is_project_updating = TRUE;
1373 /* insert the proc id associated within the task */
1374 g_tree_insert (sdb_plugin->proc_id_tree, GINT_TO_POINTER (proc_id),
1375 GINT_TO_POINTER (TASK_PROJECT_UPDATE));
1376 return TRUE;
1379 return FALSE;
1383 * do_check_offline_files_changed:
1384 * @sdb_plugin: self
1386 * Returns: TRUE if a scan process is started, FALSE elsewhere.
1388 static gboolean
1389 do_check_offline_files_changed (SymbolDBPlugin *sdb_plugin)
1391 GList * prj_elements_list;
1392 GList *node;
1393 IAnjutaProjectManager *pm;
1394 GHashTable *prj_elements_hash;
1395 GPtrArray *to_add_files = NULL;
1396 gint real_added = 0;
1398 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
1399 IAnjutaProjectManager, NULL);
1401 prj_elements_list = ianjuta_project_manager_get_elements (pm,
1402 ANJUTA_PROJECT_SOURCE | ANJUTA_PROJECT_PROJECT,
1403 NULL);
1405 /* fill an hash table with all the items of the list just taken.
1406 * We won't g_strdup () the elements because they'll be freed later
1408 prj_elements_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
1409 NULL, g_free);
1411 for (node = prj_elements_list; node != NULL; node = g_list_next (node))
1413 GFile *gfile;
1414 gchar *filename;
1415 const gchar *db_path;
1417 gfile = node->data;
1418 if (!gfile)
1419 continue;
1421 if ((filename = g_file_get_path (gfile)) == NULL ||
1422 !strlen (filename))
1424 g_object_unref (gfile);
1426 continue;
1429 /* test its existence */
1430 if (g_file_query_exists (gfile, NULL) == FALSE)
1432 g_object_unref (gfile);
1434 continue;
1437 /* Use g_hash_table_replace instead of g_hash_table_insert because the key
1438 * and the value use the same block of memory, both must be changed at
1439 * the same time. */
1440 db_path = symbol_db_util_get_file_db_path (sdb_plugin->sdbe_project,
1441 filename);
1443 if (db_path)
1444 g_hash_table_replace (prj_elements_hash,
1445 (gchar *)db_path,
1446 (gchar *)filename);
1447 g_object_unref (gfile);
1450 g_list_free(prj_elements_list);
1452 /* some files may have added/removed editing Makefile.am while
1453 * Anjuta was offline. Check this case too.
1454 * FIXME: Get rid of data model here.
1456 GdaDataModel *model =
1457 symbol_db_engine_get_files_for_project (sdb_plugin->sdbe_project);
1458 GdaDataModelIter *it =
1459 gda_data_model_create_iter (model);
1461 if (it && gda_data_model_iter_move_to_row (it, 0))
1463 GPtrArray *remove_array;
1464 remove_array = g_ptr_array_new_with_free_func (g_free);
1465 do {
1466 const GValue *val = gda_data_model_iter_get_value_at (it, 0);
1467 const gchar * file = g_value_get_string (val);
1469 if (file && g_hash_table_remove (prj_elements_hash, file) == FALSE)
1470 g_ptr_array_add (remove_array, g_strdup (file));
1472 } while (gda_data_model_iter_move_next (it));
1474 symbol_db_engine_remove_files (sdb_plugin->sdbe_project,
1475 sdb_plugin->project_opened,
1476 remove_array);
1477 g_ptr_array_unref (remove_array);
1480 /* great, at this point we should have this situation:
1481 * remove array = files to remove, remaining items in the hash_table = files
1482 * to add.
1484 to_add_files = g_ptr_array_new ();
1485 if (g_hash_table_size (prj_elements_hash) > 0)
1487 gint i;
1488 GList *keys = g_hash_table_get_keys (prj_elements_hash);
1490 /* get all the nodes from the hash table and add them to the wannabe-added
1491 * array
1493 for (i = 0; i < g_hash_table_size (prj_elements_hash); i++)
1495 /*DEBUG_PRINT ("ARRAY ADD %s", (gchar*)g_list_nth_data (keys, i));*/
1496 g_ptr_array_add (to_add_files,
1497 g_hash_table_lookup (prj_elements_hash,
1498 g_list_nth_data (keys, i)));
1502 /* good. Let's go on with add of new files. */
1503 if (to_add_files->len > 0)
1505 /* block the signals spreading from engine to local-view tab */
1506 sdb_plugin->is_offline_scanning = TRUE;
1507 real_added = do_add_new_files (sdb_plugin, to_add_files,
1508 TASK_OFFLINE_CHANGES);
1510 DEBUG_PRINT ("going to do add %d files with TASK_OFFLINE_CHANGES",
1511 real_added);
1513 if (real_added <= 0)
1515 sdb_plugin->is_offline_scanning = FALSE;
1517 else {
1518 /* connect to receive signals on single file scan complete. We'll
1519 * update a status bar notifying the user about the status
1521 sdb_plugin->files_count_project += real_added;
1523 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "single-file-scan-end",
1524 G_CALLBACK (on_check_offline_single_file_scan_end), ANJUTA_PLUGIN (sdb_plugin));
1528 /*if (it != NULL) g_object_unref (it);*/
1529 g_object_unref (it);
1530 g_object_unref (model);
1531 g_ptr_array_unref (to_add_files);
1532 g_hash_table_destroy (prj_elements_hash);
1534 return real_added > 0 ? TRUE : FALSE;
1537 static void
1538 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
1539 AnjutaSession *session,
1540 SymbolDBPlugin *sdb_plugin)
1542 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
1543 return;
1545 DEBUG_PRINT ("%s", "SymbolDB: session_save");
1548 static void
1549 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
1550 AnjutaSession *session,
1551 SymbolDBPlugin *sdb_plugin)
1553 if (phase == ANJUTA_SESSION_PHASE_START)
1555 DEBUG_PRINT ("SymbolDB: session_loading started. Getting info from %s",
1556 anjuta_session_get_session_directory (session));
1557 sdb_plugin->session_loading = TRUE;
1559 /* get preferences about the parallel scan */
1560 gboolean parallel_scan = g_settings_get_boolean (sdb_plugin->settings,
1561 PARALLEL_SCAN);
1563 if (parallel_scan == TRUE &&
1564 symbol_db_engine_is_connected (sdb_plugin->sdbe_globals) == TRUE)
1566 /* we simulate a project-import-end signal received */
1567 do_import_system_sources (sdb_plugin);
1570 else if (phase == ANJUTA_SESSION_PHASE_END)
1572 IAnjutaDocumentManager* docman;
1573 sdb_plugin->session_loading = FALSE;
1574 DEBUG_PRINT ("SymbolDB: session_loading finished");
1576 /* Show the symbols for the current editor */
1577 docman = anjuta_shell_get_interface (shell, IAnjutaDocumentManager, NULL);
1578 if (docman)
1580 IAnjutaDocument* cur_doc =
1581 ianjuta_document_manager_get_current_document (docman, NULL);
1582 if (cur_doc)
1584 GValue value = {0, };
1585 g_value_init (&value, G_TYPE_OBJECT);
1586 g_value_set_object (&value, cur_doc);
1587 value_added_current_editor (ANJUTA_PLUGIN (sdb_plugin),
1588 "document_manager_current_document",
1589 &value, NULL);
1590 g_value_unset(&value);
1594 if (sdb_plugin->project_opened == NULL)
1596 gtk_widget_hide (sdb_plugin->progress_bar_project);
1597 gtk_widget_hide (sdb_plugin->progress_bar_system);
1602 static void
1603 on_project_loaded (IAnjutaProjectManager *pm, GError *error,
1604 SymbolDBPlugin *sdb_plugin)
1606 g_return_if_fail (sdb_plugin->project_root_uri != NULL);
1607 g_return_if_fail (sdb_plugin->project_root_dir != NULL);
1609 /* Malformed project abort */
1610 if (error != NULL) return;
1613 * we need an initial import
1615 if (sdb_plugin->needs_sources_scan == TRUE)
1617 DEBUG_PRINT ("Importing sources.");
1618 do_import_project_sources (sdb_plugin, pm, sdb_plugin->project_root_dir);
1620 else
1623 * no import needed. But we may have aborted the scan of sources in
1624 * a previous session..
1626 GPtrArray *sources_array = NULL;
1628 DEBUG_PRINT ("Checking for files with zero symbols.");
1629 sources_array =
1630 symbol_db_util_get_files_with_zero_symbols (sdb_plugin->sdbe_project);
1632 if (sources_array != NULL && sources_array->len > 0)
1634 DEBUG_PRINT ("Importing files after abort.");
1635 do_import_project_sources_after_abort (sdb_plugin, sources_array);
1637 g_ptr_array_unref (sources_array);
1640 DEBUG_PRINT ("Checking for offline changes.");
1641 /* check for offline changes */
1642 if (do_check_offline_files_changed (sdb_plugin) == FALSE)
1644 DEBUG_PRINT ("no changes. Skipping.");
1647 DEBUG_PRINT ("Updating project symbols.");
1648 /* update any files of the project which isn't up-to-date */
1649 if (do_update_project_symbols (sdb_plugin, sdb_plugin->project_opened) == FALSE)
1651 DEBUG_PRINT ("no changes. Skipping.");
1656 /* add a new project */
1657 static void
1658 on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
1659 const GValue *value, gpointer user_data)
1661 SymbolDBPlugin *sdb_plugin;
1662 const gchar *root_uri;
1663 gchar *root_dir;
1664 GFile *gfile;
1665 GError *error = NULL;
1667 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
1670 * The Global System symbols thing
1673 /* is the global db connected? */
1674 if (symbol_db_engine_is_connected (sdb_plugin->sdbe_globals) == FALSE)
1676 gchar *anjuta_cache_path;
1677 /* open the connection to global db */
1678 anjuta_cache_path = anjuta_util_get_user_cache_file_path (".", NULL);
1679 if (symbol_db_engine_open_db (sdb_plugin->sdbe_globals,
1680 anjuta_cache_path,
1681 PROJECT_GLOBALS,
1682 &error) == DB_OPEN_STATUS_FATAL)
1684 g_error ("Opening global project under %s: %s", anjuta_cache_path, error->message);
1686 g_free (anjuta_cache_path);
1688 /* unref and recreate the sdbs object */
1689 if (sdb_plugin->sdbs != NULL)
1690 g_object_unref (sdb_plugin->sdbs);
1692 sdb_plugin->sdbs = symbol_db_system_new (sdb_plugin,
1693 sdb_plugin->sdbe_globals);
1696 /* Hide the progress bar. Default system tags thing: we'll import after abort even
1697 * if the preferences says not to automatically scan the packages.
1699 gtk_widget_hide (sdb_plugin->progress_bar_system);
1703 * The Project thing
1706 g_free (sdb_plugin->project_root_uri);
1707 sdb_plugin->project_root_uri = NULL;
1708 if ((root_uri = g_value_get_string (value)) == NULL)
1710 DEBUG_PRINT ("Warning, root_uri for project is NULL");
1711 return;
1715 gfile = g_file_new_for_uri (root_uri);
1717 root_dir = g_file_get_path (gfile);
1718 DEBUG_PRINT ("Symbol-DB: added project root_dir %s, name %s", root_dir,
1719 name);
1721 g_object_unref (gfile);
1723 /* let the project be something like "." to avoid problems when renaming the
1724 * project dir */
1725 sdb_plugin->project_opened = g_strdup (PROJECT_ROOT_NAME_DEFAULT);
1727 if (root_dir)
1729 gboolean project_exist = FALSE;
1730 guint id;
1732 /* we'll use the same values for db_directory and project_directory */
1733 DEBUG_PRINT ("Opening db %s and project_dir %s", root_dir, root_dir);
1734 gint open_status = symbol_db_engine_open_db (sdb_plugin->sdbe_project, root_dir,
1735 root_dir, &error);
1737 /* is it a fresh-new project? is it an imported project with
1738 * no 'new' symbol-db database but the 'old' one symbol-browser?
1740 sdb_plugin->needs_sources_scan = FALSE;
1741 switch (open_status)
1743 case DB_OPEN_STATUS_FATAL:
1744 g_warning ("*** Error in opening db: %s***", error->message);
1745 return;
1747 case DB_OPEN_STATUS_NORMAL:
1748 project_exist = TRUE;
1749 break;
1751 case DB_OPEN_STATUS_CREATE:
1752 case DB_OPEN_STATUS_UPGRADE:
1753 sdb_plugin->needs_sources_scan = TRUE;
1754 project_exist = FALSE;
1755 break;
1757 default:
1758 break;
1761 /* if project did not exist add a new project */
1762 if (project_exist == FALSE)
1764 DEBUG_PRINT ("Creating new project.");
1765 symbol_db_engine_add_new_project (sdb_plugin->sdbe_project,
1766 NULL, /* still no workspace logic */
1767 sdb_plugin->project_opened,
1768 "1.0");
1771 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project),
1772 _("Populating symbol database…"));
1773 id = g_idle_add ((GSourceFunc) gtk_progress_bar_pulse,
1774 sdb_plugin->progress_bar_project);
1775 gtk_widget_show (sdb_plugin->progress_bar_project);
1776 g_source_remove (id);
1777 gtk_widget_hide (sdb_plugin->progress_bar_project);
1779 /* root dir */
1780 sdb_plugin->project_root_dir = root_dir;
1782 /* this is uri */
1783 sdb_plugin->project_root_uri = g_strdup (root_uri);
1786 static void
1787 on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
1788 gpointer user_data)
1790 IAnjutaProjectManager *pm;
1791 SymbolDBPlugin *sdb_plugin;
1793 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
1794 DEBUG_PRINT ("%s", "project_root_removed ()");
1795 /* Disconnect events from project manager */
1797 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
1798 IAnjutaProjectManager, NULL);
1799 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
1800 on_project_element_added,
1801 sdb_plugin);
1802 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
1803 on_project_element_removed,
1804 sdb_plugin);
1806 /* don't forget to close the project */
1807 symbol_db_engine_close_db (sdb_plugin->sdbe_project);
1809 /* and the globals one */
1810 symbol_db_engine_close_db (sdb_plugin->sdbe_globals);
1812 /* stop any opened scanning process */
1813 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_system), "");
1814 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project), "");
1815 gtk_widget_hide (sdb_plugin->progress_bar_system);
1816 gtk_widget_hide (sdb_plugin->progress_bar_project);
1818 sdb_plugin->files_count_system_done = 0;
1819 sdb_plugin->files_count_system = 0;
1821 sdb_plugin->files_count_project_done = 0;
1822 sdb_plugin->files_count_project = 0;
1825 g_free (sdb_plugin->project_root_uri);
1826 g_free (sdb_plugin->project_root_dir);
1827 g_free (sdb_plugin->project_opened);
1828 sdb_plugin->project_root_uri = NULL;
1829 sdb_plugin->project_root_dir = NULL;
1830 sdb_plugin->project_opened = NULL;
1833 static void
1834 on_scan_end_manager (SymbolDBEngine *dbe, gint process_id,
1835 gpointer data)
1837 SymbolDBPlugin *sdb_plugin;
1838 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);
1839 gint task_registered;
1841 task_registered = GPOINTER_TO_INT (g_tree_lookup (sdb_plugin->proc_id_tree,
1842 GINT_TO_POINTER (process_id)));
1843 /* hey, we haven't find anything */
1844 if (task_registered <= 0)
1846 DEBUG_PRINT ("No task found, proc id was %d", process_id);
1847 return;
1850 switch (task_registered)
1852 case TASK_IMPORT_PROJECT:
1853 case TASK_IMPORT_PROJECT_AFTER_ABORT:
1855 DEBUG_PRINT ("received TASK_IMPORT_PROJECT (AFTER_ABORT)");
1857 /* re-enable signals receiving on local-view */
1858 sdb_plugin->is_project_importing = FALSE;
1860 /* disconnect this coz it's not important after the process of importing */
1861 g_signal_handlers_disconnect_by_func (dbe, on_project_single_file_scan_end,
1862 sdb_plugin);
1864 /* get preferences about the parallel scan */
1865 gboolean parallel_scan = g_settings_get_boolean (sdb_plugin->settings,
1866 PARALLEL_SCAN);
1869 /* check the system population has a parallel fashion or not. */
1870 if (parallel_scan == FALSE)
1871 do_import_system_sources (sdb_plugin);
1873 break;
1875 case TASK_BUFFER_UPDATE:
1876 DEBUG_PRINT ("received TASK_BUFFER_UPDATE");
1877 on_editor_buffer_symbol_update_scan_end (dbe, process_id, sdb_plugin);
1878 break;
1880 case TASK_ELEMENT_ADDED:
1881 DEBUG_PRINT ("received TASK_ELEMENT_ADDED");
1882 sdb_plugin->is_adding_element = FALSE;
1883 break;
1885 case TASK_OFFLINE_CHANGES:
1886 DEBUG_PRINT ("received TASK_OFFLINE_CHANGES");
1888 /* disconnect this coz it's not important after the process of importing */
1889 g_signal_handlers_disconnect_by_func (dbe, on_check_offline_single_file_scan_end,
1890 sdb_plugin);
1892 sdb_plugin->is_offline_scanning = FALSE;
1893 break;
1895 case TASK_PROJECT_UPDATE:
1896 DEBUG_PRINT ("received TASK_PROJECT_UPDATE");
1897 sdb_plugin->is_project_updating = FALSE;
1898 break;
1900 case TASK_FILE_UPDATE:
1901 DEBUG_PRINT ("received TASK_FILE_UPDATE");
1902 break;
1904 default:
1905 DEBUG_PRINT ("Don't know what to to with task_registered %d",
1906 task_registered);
1909 /* ok, we're done. Remove the proc_id from the GTree coz we won't use it anymore */
1910 if (g_tree_remove (sdb_plugin->proc_id_tree, GINT_TO_POINTER (process_id)) == FALSE)
1911 g_warning ("Cannot remove proc_id from GTree");
1913 DEBUG_PRINT ("is_offline_scanning %d, is_project_importing %d, is_project_updating %d, "
1914 "is_adding_element %d", sdb_plugin->is_offline_scanning,
1915 sdb_plugin->is_project_importing, sdb_plugin->is_project_updating,
1916 sdb_plugin->is_adding_element);
1918 /* is the project still opened? */
1919 if (sdb_plugin->project_opened == NULL)
1921 /* just return, the project may have been closed while we were waiting for the
1922 * scanning to finish
1924 return;
1928 * perform some checks on some booleans. If they're all successfully passed
1929 * then activate the display of local view
1931 if (sdb_plugin->is_offline_scanning == FALSE &&
1932 sdb_plugin->is_project_importing == FALSE &&
1933 sdb_plugin->is_project_updating == FALSE &&
1934 sdb_plugin->is_adding_element == FALSE)
1936 sdb_plugin->files_count_project_done = 0;
1937 sdb_plugin->files_count_project = 0;
1938 clear_project_progress_bar (dbe, sdb_plugin);
1942 static void
1943 on_isymbol_manager_prj_scan_end (SymbolDBEngine *dbe,
1944 gint process_id,
1945 IAnjutaSymbolManager *sm)
1947 g_signal_emit_by_name (sm, "prj-scan-end", process_id);
1950 static void
1951 on_isymbol_manager_sys_scan_begin (SymbolDBEngine *dbe, gint process_id,
1952 SymbolDBPlugin *sdb_plugin)
1954 sdb_plugin->current_pkg_scanned = g_async_queue_pop (sdb_plugin->global_scan_aqueue);
1956 if (sdb_plugin->current_pkg_scanned == NULL)
1957 return;
1959 DEBUG_PRINT ("==%d==>\n"
1960 "begin %s", process_id, sdb_plugin->current_pkg_scanned->package_name);
1961 gtk_widget_show (sdb_plugin->progress_bar_system);
1964 static void
1965 on_isymbol_manager_sys_single_scan_end (SymbolDBEngine *dbe, SymbolDBPlugin *sdb_plugin)
1967 PackageScanData *pkg_scan;
1969 /* ignore signals when scan-end has already been received */
1970 if (sdb_plugin->current_pkg_scanned == NULL)
1972 return;
1975 pkg_scan = sdb_plugin->current_pkg_scanned;
1976 pkg_scan->files_done++;
1978 gtk_widget_show (sdb_plugin->progress_bar_system);
1979 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_system),
1980 (gdouble)pkg_scan->files_done /
1981 (gdouble)pkg_scan->files_length);
1984 static void
1985 on_isymbol_manager_sys_scan_end (SymbolDBEngine *dbe,
1986 gint process_id,
1987 SymbolDBPlugin *sdb_plugin)
1989 IAnjutaSymbolManager *sm;
1990 PackageScanData *pkg_scan;
1992 g_return_if_fail (sdb_plugin->current_pkg_scanned != NULL);
1994 DEBUG_PRINT ("<==%d==\nscan end %s. Queue now is %d",
1995 process_id,
1996 sdb_plugin->current_pkg_scanned->package_name,
1997 g_async_queue_length (sdb_plugin->global_scan_aqueue));
1999 sm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
2000 IAnjutaSymbolManager, NULL);
2002 g_signal_emit_by_name (sm, "sys-scan-end", process_id);
2004 pkg_scan = sdb_plugin->current_pkg_scanned;
2005 g_free (pkg_scan->package_name);
2006 g_free (pkg_scan->package_version);
2007 g_free (pkg_scan);
2009 sdb_plugin->current_pkg_scanned = NULL;
2011 gtk_widget_hide (sdb_plugin->progress_bar_system);
2014 static gboolean
2015 symbol_db_activate (AnjutaPlugin *plugin)
2017 IAnjutaProjectManager *pm;
2018 SymbolDBPlugin *sdb_plugin;
2019 gchar *anjuta_cache_path;
2020 gchar *ctags_path;
2021 GtkWidget *view, *label;
2022 GError *error = NULL;
2024 DEBUG_PRINT ("SymbolDBPlugin: Activating SymbolDBPlugin plugin …");
2026 /* Initialize gda library. */
2027 gda_init ();
2029 register_stock_icons (plugin);
2031 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
2032 sdb_plugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
2033 sdb_plugin->project_opened = NULL;
2035 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
2036 IAnjutaProjectManager, NULL);
2038 ctags_path = NULL;
2040 /* leaving here this code. Maybe in future ctags-devs will include our patches
2041 * upstream and this can be useful again.
2043 if (ctags_path == NULL)
2045 DEBUG_PRINT ("ctags is not in preferences. Trying a default one %s",
2046 CTAGS_PATH);
2047 ctags_path = g_strdup (CTAGS_PATH);
2050 sdb_plugin->buf_update_timeout_id = 0;
2051 sdb_plugin->need_symbols_update = FALSE;
2052 /* creates and start a new timer. */
2053 sdb_plugin->update_timer = g_timer_new ();
2055 /* these two arrays will maintain the same number of objects,
2056 * so that if you search, say on the first, an occurrence of a file,
2057 * you'll be able to get in O(1) the _index in the second array, where the
2058 * scan process ids are stored. This is true in the other way too.
2060 sdb_plugin->buffer_update_files = g_ptr_array_new_with_free_func (g_free);
2061 sdb_plugin->buffer_update_ids = g_ptr_array_new ();
2062 sdb_plugin->buffer_update_semaphore = FALSE;
2064 sdb_plugin->is_offline_scanning = FALSE;
2065 sdb_plugin->is_project_importing = FALSE;
2066 sdb_plugin->is_project_updating = FALSE;
2067 sdb_plugin->is_adding_element = FALSE;
2069 DEBUG_PRINT ("SymbolDBPlugin: Initializing engines with %s", ctags_path);
2070 /* create SymbolDBEngine(s) */
2071 sdb_plugin->sdbe_project = symbol_db_engine_new (ctags_path);
2072 if (sdb_plugin->sdbe_project == NULL)
2074 g_critical ("sdbe_project == NULL");
2075 return FALSE;
2078 /* the globals one too */
2079 sdb_plugin->sdbe_globals = symbol_db_engine_new (ctags_path);
2080 if (sdb_plugin->sdbe_globals == NULL)
2082 g_critical ("sdbe_globals == NULL");
2083 return FALSE;
2086 g_free (ctags_path);
2088 /* open it */
2089 anjuta_cache_path = anjuta_util_get_user_cache_file_path (".", NULL);
2090 if (symbol_db_engine_open_db (sdb_plugin->sdbe_globals,
2091 anjuta_cache_path,
2092 PROJECT_GLOBALS,
2093 &error) == DB_OPEN_STATUS_FATAL)
2095 g_error ("Opening global project under %s: %s", anjuta_cache_path, error->message);
2098 g_free (anjuta_cache_path);
2100 sdb_plugin->global_scan_aqueue = g_async_queue_new ();
2101 /* create the object that'll manage the globals population */
2102 sdb_plugin->sdbs = symbol_db_system_new (sdb_plugin, sdb_plugin->sdbe_globals);
2103 #if 0
2104 g_signal_connect (G_OBJECT (sdb_plugin->sdbs), "scan-package-start",
2105 G_CALLBACK (on_system_scan_package_start), plugin);
2107 g_signal_connect (G_OBJECT (sdb_plugin->sdbs), "scan-package-end",
2108 G_CALLBACK (on_system_scan_package_end), plugin);
2110 g_signal_connect (G_OBJECT (sdb_plugin->sdbs), "single-file-scan-end",
2111 G_CALLBACK (on_system_single_file_scan_end), plugin);
2112 #endif
2113 /* beign necessary to listen to many scan-end signals, we'll build up a method
2114 * to manage them with just one signal connection
2116 sdb_plugin->proc_id_tree = g_tree_new_full ((GCompareDataFunc)&symbol_db_gtree_compare_func,
2117 NULL,
2118 NULL,
2119 NULL);
2121 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "scan-end",
2122 G_CALLBACK (on_scan_end_manager), sdb_plugin);
2124 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "scan-end",
2125 G_CALLBACK (on_isymbol_manager_prj_scan_end), sdb_plugin);
2127 /* connect signals for interface to receive them */
2128 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_globals), "single-file-scan-end",
2129 G_CALLBACK (on_isymbol_manager_sys_single_scan_end), sdb_plugin);
2131 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_globals), "scan-end",
2132 G_CALLBACK (on_isymbol_manager_sys_scan_end), sdb_plugin);
2134 g_signal_connect (G_OBJECT (sdb_plugin->sdbe_globals), "scan-begin",
2135 G_CALLBACK (on_isymbol_manager_sys_scan_begin), sdb_plugin);
2139 /* connect signals for project loading and element adding */
2140 g_signal_connect (G_OBJECT (pm), "element-added",
2141 G_CALLBACK (on_project_element_added), sdb_plugin);
2142 g_signal_connect (G_OBJECT (pm), "element-removed",
2143 G_CALLBACK (on_project_element_removed), sdb_plugin);
2144 g_signal_connect (G_OBJECT (pm), "project-loaded",
2145 G_CALLBACK (on_project_loaded), sdb_plugin);
2147 /* Create widgets */
2148 sdb_plugin->dbv_main = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
2149 sdb_plugin->dbv_notebook = gtk_notebook_new();
2150 gtk_notebook_set_show_border (GTK_NOTEBOOK (sdb_plugin->dbv_notebook), FALSE);
2151 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sdb_plugin->dbv_notebook), FALSE);
2152 sdb_plugin->dbv_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
2154 label = gtk_label_new (_("Symbols"));
2155 gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
2156 gtk_box_pack_start (GTK_BOX(sdb_plugin->dbv_hbox),
2157 gtk_image_new_from_stock ("symbol-db-plugin-icon",
2158 GTK_ICON_SIZE_MENU),
2159 FALSE, FALSE, 0);
2160 gtk_box_pack_start (GTK_BOX(sdb_plugin->dbv_hbox), label,
2161 FALSE, FALSE, 0);
2163 sdb_plugin->tabber = anjuta_tabber_new (GTK_NOTEBOOK (sdb_plugin->dbv_notebook));
2164 label = gtk_label_new (_("File"));
2165 gtk_label_set_ellipsize (GTK_LABEL (label),
2166 PANGO_ELLIPSIZE_END);
2167 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin->tabber),
2168 label);
2169 label = gtk_label_new (_("Project"));
2170 gtk_label_set_ellipsize (GTK_LABEL (label),
2171 PANGO_ELLIPSIZE_END);
2172 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin->tabber),
2173 label);
2174 label = gtk_label_new (_("Search"));
2175 gtk_label_set_ellipsize (GTK_LABEL (label),
2176 PANGO_ELLIPSIZE_END);
2177 anjuta_tabber_add_tab (ANJUTA_TABBER (sdb_plugin->tabber),
2178 label);
2179 gtk_box_pack_end (GTK_BOX(sdb_plugin->dbv_hbox), sdb_plugin->tabber,
2180 TRUE, TRUE, 5);
2182 gtk_widget_show_all (sdb_plugin->dbv_hbox);
2184 sdb_plugin->progress_bar_project = gtk_progress_bar_new();
2185 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(sdb_plugin->progress_bar_project),
2186 PANGO_ELLIPSIZE_MIDDLE);
2187 g_object_ref (sdb_plugin->progress_bar_project);
2189 sdb_plugin->progress_bar_system = gtk_progress_bar_new();
2190 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(sdb_plugin->progress_bar_system),
2191 PANGO_ELLIPSIZE_MIDDLE);
2192 g_object_ref (sdb_plugin->progress_bar_system);
2194 gtk_box_pack_start (GTK_BOX (sdb_plugin->dbv_main), sdb_plugin->dbv_notebook,
2195 TRUE, TRUE, 0);
2196 gtk_box_pack_start (GTK_BOX (sdb_plugin->dbv_main), sdb_plugin->progress_bar_project,
2197 FALSE, FALSE, 0);
2198 gtk_box_pack_start (GTK_BOX (sdb_plugin->dbv_main), sdb_plugin->progress_bar_system,
2199 FALSE, FALSE, 0);
2200 gtk_widget_show_all (sdb_plugin->dbv_main);
2202 /* Local symbols */
2203 view = symbol_db_view_new (SYMBOL_DB_VIEW_FILE, sdb_plugin->sdbe_project,
2204 sdb_plugin);
2205 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin->dbv_notebook),
2206 view, gtk_label_new (_("Local")));
2207 sdb_plugin->file_model =
2208 gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN(view))));
2210 g_object_add_weak_pointer (G_OBJECT (sdb_plugin->file_model),
2211 (gpointer)&sdb_plugin->file_model);
2213 /* Global symbols */
2214 view = symbol_db_view_new (SYMBOL_DB_VIEW_PROJECT,
2215 sdb_plugin->sdbe_project,
2216 sdb_plugin);
2217 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin->dbv_notebook),
2218 view, gtk_label_new (_("Global" )));
2220 /* Search symbols */
2221 view = symbol_db_view_new (SYMBOL_DB_VIEW_SEARCH,
2222 sdb_plugin->sdbe_project,
2223 sdb_plugin);
2224 sdb_plugin->search_entry = symbol_db_view_get_search_entry (view);
2225 gtk_notebook_append_page (GTK_NOTEBOOK (sdb_plugin->dbv_notebook),
2226 view, gtk_label_new (_("Search" )));
2228 gtk_widget_show_all (sdb_plugin->dbv_notebook);
2230 /* setting focus to the tree_view*/
2231 gtk_notebook_set_current_page (GTK_NOTEBOOK (sdb_plugin->dbv_notebook), 0);
2233 sdb_plugin->editor_watch_id =
2234 anjuta_plugin_add_watch (plugin, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
2235 value_added_current_editor,
2236 value_removed_current_editor, NULL);
2237 /* Added widgets */
2238 anjuta_shell_add_widget_custom (plugin->shell, sdb_plugin->dbv_main,
2239 "AnjutaSymbolDB", _("Symbols"),
2240 "symbol-db-plugin-icon",
2241 sdb_plugin->dbv_hbox,
2242 ANJUTA_SHELL_PLACEMENT_LEFT, NULL);
2244 /* Add action group */
2245 sdb_plugin->popup_action_group =
2246 anjuta_ui_add_action_group_entries (sdb_plugin->ui,
2247 "ActionGroupPopupSymbolDB",
2248 _("SymbolDb popup actions"),
2249 actions,
2250 G_N_ELEMENTS (actions),
2251 GETTEXT_PACKAGE, FALSE, plugin);
2253 sdb_plugin->menu_action_group =
2254 anjuta_ui_add_action_group_entries (sdb_plugin->ui,
2255 "ActionGroupEditSearchSymbolDB",
2256 _("SymbolDb menu actions"),
2257 actions_search,
2258 G_N_ELEMENTS (actions_search),
2259 GETTEXT_PACKAGE, FALSE, plugin);
2261 /* Add UI */
2262 sdb_plugin->merge_id =
2263 anjuta_ui_merge (sdb_plugin->ui, UI_FILE);
2265 /* set up project directory watch */
2266 sdb_plugin->root_watch_id = anjuta_plugin_add_watch (plugin,
2267 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
2268 on_project_root_added,
2269 on_project_root_removed, NULL);
2271 /* Determine session state */
2272 g_signal_connect (plugin->shell, "load-session",
2273 G_CALLBACK (on_session_load), plugin);
2275 g_signal_connect (plugin->shell, "save-session",
2276 G_CALLBACK (on_session_save), plugin);
2278 /* be sure to hide the progress bars in case no project has been opened. */
2279 gtk_widget_hide (sdb_plugin->progress_bar_project);
2280 gtk_widget_hide (sdb_plugin->progress_bar_system);
2282 static IAnjutaSymbolField search_fields[] =
2284 IANJUTA_SYMBOL_FIELD_KIND,
2285 IANJUTA_SYMBOL_FIELD_FILE_PATH,
2286 IANJUTA_SYMBOL_FIELD_FILE_POS
2288 sdb_plugin->search_query =
2289 ianjuta_symbol_manager_create_query (IANJUTA_SYMBOL_MANAGER (sdb_plugin),
2290 IANJUTA_SYMBOL_QUERY_SEARCH,
2291 IANJUTA_SYMBOL_QUERY_DB_PROJECT,
2292 NULL);
2293 ianjuta_symbol_query_set_fields (sdb_plugin->search_query,
2294 G_N_ELEMENTS (search_fields),
2295 search_fields, NULL);
2296 return TRUE;
2299 static gboolean
2300 symbol_db_deactivate (AnjutaPlugin *plugin)
2302 SymbolDBPlugin *sdb_plugin;
2303 IAnjutaProjectManager *pm;
2305 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
2307 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
2308 IAnjutaProjectManager, NULL);
2312 DEBUG_PRINT ("%s", "SymbolDBPlugin: Dectivating SymbolDBPlugin plugin …");
2314 /* Unmerge UI */
2315 gtk_ui_manager_remove_ui (GTK_UI_MANAGER (sdb_plugin->ui),
2316 sdb_plugin->merge_id);
2317 gtk_ui_manager_remove_action_group (GTK_UI_MANAGER (sdb_plugin->ui),
2318 sdb_plugin->popup_action_group);
2319 gtk_ui_manager_remove_action_group (GTK_UI_MANAGER (sdb_plugin->ui),
2320 sdb_plugin->menu_action_group);
2321 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
2322 on_session_load,
2323 plugin);
2325 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
2326 on_session_save,
2327 plugin);
2329 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbs),
2330 on_system_scan_package_start,
2331 plugin);
2333 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbs),
2334 on_system_scan_package_end,
2335 plugin);
2337 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbs),
2338 on_system_single_file_scan_end,
2339 plugin);
2341 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbs),
2342 on_scan_end_manager,
2343 plugin);
2345 /* disconnect the interface ones */
2346 /* connect signals for interface to receive them */
2347 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbe_globals),
2348 G_CALLBACK (on_isymbol_manager_sys_scan_end), plugin);
2350 g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->sdbe_project),
2351 G_CALLBACK (on_isymbol_manager_prj_scan_end), plugin);
2353 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
2354 G_CALLBACK (on_project_element_added), plugin);
2356 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
2357 G_CALLBACK (on_project_element_removed), plugin);
2359 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
2360 G_CALLBACK (on_project_loaded), plugin);
2362 if (sdb_plugin->buf_update_timeout_id)
2364 g_source_remove (sdb_plugin->buf_update_timeout_id);
2365 sdb_plugin->buf_update_timeout_id = 0;
2367 if (sdb_plugin->update_timer)
2369 g_timer_destroy (sdb_plugin->update_timer);
2370 sdb_plugin->update_timer = NULL;
2373 /* destroy search query */
2374 if (sdb_plugin->search_query)
2376 g_object_unref (sdb_plugin->search_query);
2378 sdb_plugin->search_query = NULL;
2380 /* destroy objects */
2381 if (sdb_plugin->sdbe_project)
2383 DEBUG_PRINT ("Destroying project engine object. ");
2384 g_object_unref (sdb_plugin->sdbe_project);
2386 sdb_plugin->sdbe_project = NULL;
2388 PackageScanData *pkg_scan_data;
2389 while ((pkg_scan_data = g_async_queue_try_pop (sdb_plugin->global_scan_aqueue)) != NULL)
2391 g_free (pkg_scan_data->package_name);
2392 g_free (pkg_scan_data->package_version);
2393 g_free (pkg_scan_data);
2396 g_async_queue_unref (sdb_plugin->global_scan_aqueue);
2397 sdb_plugin->global_scan_aqueue = NULL;
2399 /* this must be done *before* destroying sdbe_globals */
2400 g_object_unref (sdb_plugin->sdbs);
2401 sdb_plugin->sdbs = NULL;
2403 g_free (sdb_plugin->current_scanned_package);
2404 sdb_plugin->current_scanned_package = NULL;
2406 DEBUG_PRINT ("Destroying global engine object. ");
2407 g_object_unref (sdb_plugin->sdbe_globals);
2408 sdb_plugin->sdbe_globals = NULL;
2410 g_free (sdb_plugin->project_opened);
2411 sdb_plugin->project_opened = NULL;
2413 if (sdb_plugin->buffer_update_files)
2415 g_ptr_array_unref (sdb_plugin->buffer_update_files);
2416 sdb_plugin->buffer_update_files = NULL;
2419 if (sdb_plugin->buffer_update_ids)
2421 g_ptr_array_unref (sdb_plugin->buffer_update_ids);
2422 sdb_plugin->buffer_update_ids = NULL;
2425 /* Ensure all editor cached info are released */
2426 if (sdb_plugin->editor_connected)
2428 g_hash_table_foreach (sdb_plugin->editor_connected,
2429 on_editor_foreach_disconnect, plugin);
2430 g_hash_table_destroy (sdb_plugin->editor_connected);
2431 sdb_plugin->editor_connected = NULL;
2432 g_hash_table_destroy (sdb_plugin->editors);
2433 sdb_plugin->editors = NULL;
2436 // FIXME
2437 g_tree_destroy (sdb_plugin->proc_id_tree);
2439 /* Remove watches */
2440 anjuta_plugin_remove_watch (plugin, sdb_plugin->root_watch_id, FALSE);
2441 anjuta_plugin_remove_watch (plugin, sdb_plugin->editor_watch_id, TRUE);
2443 /* Remove UI */
2444 anjuta_ui_unmerge (sdb_plugin->ui, sdb_plugin->merge_id);
2446 /* Remove widgets: Widgets will be destroyed when dbv_main is removed */
2447 anjuta_shell_remove_widget (plugin->shell, sdb_plugin->dbv_main, NULL);
2449 sdb_plugin->root_watch_id = 0;
2450 sdb_plugin->editor_watch_id = 0;
2451 sdb_plugin->merge_id = 0;
2452 sdb_plugin->dbv_notebook = NULL;
2453 sdb_plugin->progress_bar_project = NULL;
2454 sdb_plugin->progress_bar_system = NULL;
2455 return TRUE;
2458 static void
2459 symbol_db_finalize (GObject *obj)
2461 DEBUG_PRINT ("Symbol-DB finalize");
2462 /* Finalization codes here */
2463 G_OBJECT_CLASS (parent_class)->finalize (obj);
2466 static void
2467 symbol_db_dispose (GObject *obj)
2469 SymbolDBPlugin *plugin = (SymbolDBPlugin*)obj;
2470 DEBUG_PRINT ("Symbol-DB dispose");
2471 /* Disposition codes */
2472 if (plugin->settings != NULL)
2474 g_object_unref (plugin->settings);
2475 plugin->settings = NULL;
2478 if (plugin->file_model != NULL)
2480 g_object_remove_weak_pointer (G_OBJECT (plugin->file_model),
2481 (gpointer)&plugin->file_model);
2482 plugin->file_model = NULL;
2485 G_OBJECT_CLASS (parent_class)->dispose (obj);
2488 static void
2489 symbol_db_instance_init (GObject *obj)
2491 SymbolDBPlugin *plugin = (SymbolDBPlugin*)obj;
2493 plugin->files_count_project_done = 0;
2494 plugin->files_count_project = 0;
2496 plugin->files_count_system_done = 0;
2497 plugin->files_count_system = 0;
2498 plugin->current_scanned_package = NULL;
2499 plugin->settings = g_settings_new (PREF_SCHEMA);
2502 static void
2503 symbol_db_class_init (GObjectClass *klass)
2505 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
2507 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2508 parent_class = g_type_class_peek_parent (klass);
2510 plugin_class->activate = symbol_db_activate;
2511 plugin_class->deactivate = symbol_db_deactivate;
2512 klass->finalize = symbol_db_finalize;
2513 klass->dispose = symbol_db_dispose;
2515 signals[PROJECT_IMPORT_END]
2516 = g_signal_new ("project-import-end",
2517 G_OBJECT_CLASS_TYPE (object_class),
2518 G_SIGNAL_RUN_FIRST,
2519 G_STRUCT_OFFSET (SymbolDBPluginClass, project_import_end),
2520 NULL, NULL,
2521 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2523 signals[GLOBALS_IMPORT_END]
2524 = g_signal_new ("globals-import-end",
2525 G_OBJECT_CLASS_TYPE (object_class),
2526 G_SIGNAL_RUN_FIRST,
2527 G_STRUCT_OFFSET (SymbolDBPluginClass, globals_import_end),
2528 NULL, NULL,
2529 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2532 static void
2533 on_prefs_buffer_update_toggled (GtkToggleButton* button,
2534 gpointer user_data)
2536 SymbolDBPlugin *sdb_plugin;
2537 gboolean sensitive;
2539 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
2541 sensitive = gtk_toggle_button_get_active (button);
2543 DEBUG_PRINT ("on_prefs_buffer_update_toggled () %d", sensitive);
2545 if (sensitive == FALSE)
2547 if (sdb_plugin->buf_update_timeout_id)
2548 g_source_remove (sdb_plugin->buf_update_timeout_id);
2549 sdb_plugin->buf_update_timeout_id = 0;
2551 else
2553 if (sdb_plugin->buf_update_timeout_id == 0)
2554 sdb_plugin->buf_update_timeout_id =
2555 g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
2556 on_editor_buffer_symbols_update_timeout,
2557 sdb_plugin);
2561 static void
2562 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2564 DEBUG_PRINT ("%s", "SymbolDB: ipreferences_merge");
2565 SymbolDBPlugin *sdb_plugin;
2566 GtkWidget *buf_up_widget;
2567 GError* error = NULL;
2569 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (ipref);
2571 if (sdb_plugin->prefs_bxml == NULL)
2573 /* Create the preferences page */
2574 sdb_plugin->prefs_bxml = gtk_builder_new ();
2575 if (!gtk_builder_add_from_file (sdb_plugin->prefs_bxml, BUILDER_FILE, &error))
2577 g_warning ("Couldn't load builder file: %s", error->message);
2578 g_error_free(error);
2582 anjuta_preferences_add_from_builder (prefs,
2583 sdb_plugin->prefs_bxml,
2584 sdb_plugin->settings,
2585 BUILDER_ROOT,
2586 _("Symbol Database"),
2587 ICON_FILE);
2589 buf_up_widget = GTK_WIDGET (gtk_builder_get_object (sdb_plugin->prefs_bxml,
2590 PREFS_BUFFER_UPDATE));
2592 g_signal_connect (buf_up_widget, "toggled",
2593 G_CALLBACK (on_prefs_buffer_update_toggled),
2594 sdb_plugin);
2597 static void
2598 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
2600 SymbolDBPlugin *sdb_plugin;
2602 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (ipref);
2604 anjuta_preferences_remove_page(prefs, _("Symbol Database"));
2605 g_object_unref (sdb_plugin->prefs_bxml);
2606 sdb_plugin->prefs_bxml = NULL;
2609 static void
2610 ipreferences_iface_init(IAnjutaPreferencesIface* iface)
2612 DEBUG_PRINT ("%s", "SymbolDB: ipreferences_iface_init");
2613 iface->merge = ipreferences_merge;
2614 iface->unmerge = ipreferences_unmerge;
2617 /* IAnjutaSymbolManager implementation */
2618 static IAnjutaSymbolQuery*
2619 isymbol_manager_create_query (IAnjutaSymbolManager *isymbol_manager,
2620 IAnjutaSymbolQueryName query_name,
2621 IAnjutaSymbolQueryDb db,
2622 GError **err)
2624 SymbolDBPlugin *sdb_plugin;
2625 SymbolDBQuery *query;
2627 g_return_val_if_fail (isymbol_manager != NULL, NULL);
2629 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager);
2631 query = symbol_db_query_new (sdb_plugin->sdbe_globals,
2632 sdb_plugin->sdbe_project,
2633 query_name,
2635 db == IANJUTA_SYMBOL_QUERY_DB_PROJECT ?
2636 NULL : /* FIXME */ NULL);
2637 return IANJUTA_SYMBOL_QUERY (query);
2640 static gboolean
2641 isymbol_manager_add_package (IAnjutaSymbolManager *isymbol_manager,
2642 const gchar* pkg_name,
2643 const gchar* pkg_version,
2644 GList* files,
2645 GError **err)
2647 SymbolDBPlugin *sdb_plugin;
2648 IAnjutaLanguage *lang_manager;
2649 GPtrArray *files_array;
2650 PackageScanData *pkg_scan_data;
2653 g_return_val_if_fail (isymbol_manager != NULL, FALSE);
2655 /* DEBUG */
2656 GList *node;
2657 node = files;
2658 while (node != NULL)
2660 node = node->next;
2663 /* FIXME: pkg_version comes with \n at the end. This should be avoided */
2664 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager);
2665 lang_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell, IAnjutaLanguage,
2666 NULL);
2668 if (symbol_db_engine_add_new_project (sdb_plugin->sdbe_globals, NULL, pkg_name,
2669 pkg_version) == FALSE)
2671 return FALSE;
2674 files_array = anjuta_util_convert_string_list_to_array (files);
2676 pkg_scan_data = g_new0 (PackageScanData, 1);
2678 g_async_queue_push (sdb_plugin->global_scan_aqueue, pkg_scan_data);
2679 pkg_scan_data->files_length = g_list_length (files);
2680 pkg_scan_data->package_name = g_strdup (pkg_name);
2681 pkg_scan_data->package_version = g_strdup (pkg_version);
2683 pkg_scan_data->proc_id = symbol_db_engine_add_new_files_async (sdb_plugin->sdbe_globals, lang_manager,
2684 pkg_name, pkg_version, files_array);
2686 g_ptr_array_unref (files_array);
2688 return TRUE;
2691 /* FIXME: do this thread safe */
2692 static gboolean
2693 isymbol_manager_activate_package (IAnjutaSymbolManager *isymbol_manager,
2694 const gchar *pkg_name,
2695 const gchar *pkg_version,
2696 GError **err)
2698 SymbolDBPlugin *sdb_plugin;
2700 g_return_val_if_fail (isymbol_manager != NULL, FALSE);
2702 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager);
2704 if (symbol_db_engine_project_exists (sdb_plugin->sdbe_globals, pkg_name,
2705 pkg_version) == TRUE)
2707 /* FIXME: Activate package in database */
2708 DEBUG_PRINT ("STUB");
2709 return TRUE;
2712 /* user should add a package before activating it. */
2713 return FALSE;
2716 static void
2717 isymbol_manager_deactivate_package (IAnjutaSymbolManager *isymbol_manager,
2718 const gchar *pkg_name,
2719 const gchar *pkg_version,
2720 GError **err)
2722 SymbolDBPlugin *sdb_plugin;
2724 g_return_if_fail (isymbol_manager != NULL);
2726 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager);
2728 if (symbol_db_engine_project_exists (sdb_plugin->sdbe_globals, pkg_name,
2729 pkg_version) == TRUE)
2731 DEBUG_PRINT ("STUB");
2732 /* FIXME: deactivate package in database */
2736 static void
2737 isymbol_manager_deactivate_all (IAnjutaSymbolManager *isymbol_manager,
2738 GError **err)
2740 #if 0
2741 SymbolDBPlugin *sdb_plugin;
2743 g_return_if_fail (isymbol_manager != NULL);
2745 sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (isymbol_manager);
2746 #endif
2747 /* FIXME: deactivate all packages in database */
2748 DEBUG_PRINT ("STUB");
2751 static void
2752 isymbol_manager_iface_init (IAnjutaSymbolManagerIface *iface)
2754 iface->create_query = isymbol_manager_create_query;
2755 iface->activate_package = isymbol_manager_activate_package;
2756 iface->deactivate_package = isymbol_manager_deactivate_package;
2757 iface->deactivate_all = isymbol_manager_deactivate_all;
2758 iface->add_package = isymbol_manager_add_package;
2761 ANJUTA_PLUGIN_BEGIN (SymbolDBPlugin, symbol_db);
2762 ANJUTA_PLUGIN_ADD_INTERFACE (isymbol_manager, IANJUTA_TYPE_SYMBOL_MANAGER);
2763 ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences, IANJUTA_TYPE_PREFERENCES);
2764 ANJUTA_PLUGIN_END;
2766 ANJUTA_SIMPLE_PLUGIN (SymbolDBPlugin, symbol_db);