Updated Spanish translation
[anjuta-git-plugin.git] / plugins / symbol-browser / plugin.c
blob75f85b2bd37a0352e78f9b7cd528ee16ad3cdcd3
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) Naba Kumar <naba@gnome.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <config.h>
22 #include <libgnomevfs/gnome-vfs-utils.h>
23 #include <libanjuta/anjuta-shell.h>
24 #include <libanjuta/anjuta-debug.h>
25 #include <libanjuta/interfaces/ianjuta-help.h>
26 #include <libanjuta/interfaces/ianjuta-document-manager.h>
27 #include <libanjuta/interfaces/ianjuta-project-manager.h>
28 #include <libanjuta/interfaces/ianjuta-file-manager.h>
29 #include <libanjuta/interfaces/ianjuta-file.h>
30 #include <libanjuta/interfaces/ianjuta-file-loader.h>
31 #include <libanjuta/interfaces/ianjuta-editor.h>
32 #include <libanjuta/interfaces/ianjuta-markable.h>
33 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
34 #include <libanjuta/interfaces/ianjuta-preferences.h>
35 #include <libegg/menu/egg-combo-action.h>
37 #include <tm_tagmanager.h>
38 #include "an_symbol_view.h"
39 #include "an_symbol_search.h"
40 #include "anjuta-symbol-locals.h"
41 #include "an_symbol_info.h"
42 #include "an_symbol_prefs.h"
43 #include "an_symbol_iter.h"
44 #include "plugin.h"
46 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-symbol-browser-plugin.ui"
47 #define PREFS_GLADE PACKAGE_DATA_DIR"/glade/anjuta-symbol-browser-plugin.glade"
48 #define ICON_FILE "anjuta-symbol-browser-plugin.png"
50 #define TIMEOUT_INTERVAL_SYMBOLS_UPDATE 10000
52 static gpointer parent_class = NULL;
53 static gboolean need_symbols_update;
54 static gint timeout_id;
55 static gchar prev_char_added = ' ';
57 /* these will block signals on treeview and treesearch callbacks functions */
58 static void trees_signals_block (SymbolBrowserPlugin *sv_plugin);
59 static void trees_signals_unblock (SymbolBrowserPlugin *sv_plugin);
61 static void on_treesearch_symbol_selected_event (AnjutaSymbolSearch *search,
62 AnjutaSymbolInfo *sym,
63 SymbolBrowserPlugin *sv_plugin);
64 static void update_editor_symbol_model (SymbolBrowserPlugin *sv_plugin);
66 static void on_editor_update_ui (IAnjutaEditor *editor,
67 SymbolBrowserPlugin *sv_plugin);
68 static void on_char_added (IAnjutaEditor *editor, gint position, gchar ch,
69 SymbolBrowserPlugin *sv_plugin);
71 #define REGISTER_ICON(icon, stock_id) \
72 pixbuf = gdk_pixbuf_new_from_file (icon, NULL); \
73 icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); \
74 gtk_icon_factory_add (icon_factory, stock_id, icon_set); \
75 g_object_unref (pixbuf);
77 static void
78 register_stock_icons (AnjutaPlugin *plugin)
80 AnjutaUI *ui;
81 GtkIconFactory *icon_factory;
82 GtkIconSet *icon_set;
83 GdkPixbuf *pixbuf;
84 static gboolean registered = FALSE;
86 if (registered)
87 return;
88 registered = TRUE;
90 /* Register stock icons */
91 ui = anjuta_shell_get_ui (plugin->shell, NULL);
92 icon_factory = anjuta_ui_get_icon_factory (ui);
93 REGISTER_ICON (PACKAGE_PIXMAPS_DIR"/"ICON_FILE, "symbol-browser-plugin-icon");
96 static void
97 goto_file_line (AnjutaPlugin *plugin, const gchar *filename, gint lineno)
99 gchar *uri;
100 IAnjutaFileLoader *loader;
102 g_return_if_fail (filename != NULL);
104 /* Go to file and line number */
105 loader = anjuta_shell_get_interface (plugin->shell, IAnjutaFileLoader,
106 NULL);
108 uri = g_strdup_printf ("file:///%s#%d", filename, lineno);
109 ianjuta_file_loader_load (loader, uri, FALSE, NULL);
110 g_free (uri);
113 static void
114 goto_file_tag (SymbolBrowserPlugin *sv_plugin, const char *symbol,
115 gboolean prefer_definition)
117 const gchar *file;
118 gint line;
119 gboolean ret;
121 ret = anjuta_symbol_view_get_file_symbol (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
122 symbol, prefer_definition,
123 &file, &line);
124 if (ret)
126 goto_file_line (ANJUTA_PLUGIN (sv_plugin), file, line);
130 static void
131 on_goto_def_activate (GtkAction *action, SymbolBrowserPlugin *sv_plugin)
133 gchar *file;
134 gint line;
135 gboolean ret;
137 ret = anjuta_symbol_view_get_current_symbol_def (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
138 &file, &line);
139 if (ret)
141 goto_file_line (ANJUTA_PLUGIN (sv_plugin), file, line);
142 g_free (file);
146 static void
147 on_goto_decl_activate (GtkAction *action, SymbolBrowserPlugin *sv_plugin)
149 gchar *file;
150 gint line;
151 gboolean ret;
153 ret = anjuta_symbol_view_get_current_symbol_decl (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
154 &file, &line);
155 if (ret)
157 goto_file_line (ANJUTA_PLUGIN (sv_plugin), file, line);
158 g_free (file);
162 static void
163 on_goto_file_tag_decl_activate (GtkAction * action,
164 SymbolBrowserPlugin *sv_plugin)
166 IAnjutaEditor *ed;
167 gchar *word;
169 if (sv_plugin->current_editor)
171 ed = IANJUTA_EDITOR (sv_plugin->current_editor);
172 word = ianjuta_editor_get_current_word (ed, NULL);
173 if (word)
175 goto_file_tag (sv_plugin, word, FALSE);
176 g_free (word);
181 static void
182 on_goto_file_tag_def_activate (GtkAction * action,
183 SymbolBrowserPlugin *sv_plugin)
185 IAnjutaEditor *ed;
186 gchar *word;
188 if (sv_plugin->current_editor)
190 ed = IANJUTA_EDITOR (sv_plugin->current_editor);
191 word = ianjuta_editor_get_current_word (ed, NULL);
192 if (word)
194 goto_file_tag (sv_plugin, word, TRUE);
195 g_free (word);
200 static void
201 on_find_activate (GtkAction *action, SymbolBrowserPlugin *sv_plugin)
203 gchar *symbol;
204 symbol = anjuta_symbol_view_get_current_symbol (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree));
205 if (symbol)
207 g_warning ("TODO: Unimplemented");
208 g_free (symbol);
212 static gboolean
213 on_refresh_idle (gpointer user_data)
215 IAnjutaProjectManager *pm;
216 GList *source_uris;
217 GList *source_files;
218 AnjutaStatus *status;
219 SymbolBrowserPlugin *sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
221 /* FIXME: There should be a way to ensure that this project manager
222 * is indeed the one that has opened the project_uri
224 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sv_plugin)->shell,
225 IAnjutaProjectManager, NULL);
226 g_return_val_if_fail (pm != NULL, FALSE);
228 status = anjuta_shell_get_status (ANJUTA_PLUGIN (sv_plugin)->shell, NULL);
229 anjuta_status_push (status, "Refreshing symbol tree...");
230 anjuta_status_busy_push (status);
232 source_uris = source_files = NULL;
233 source_uris = ianjuta_project_manager_get_elements (pm,
234 IANJUTA_PROJECT_MANAGER_SOURCE,
235 NULL);
236 if (source_uris)
238 const gchar *uri;
239 GList *node;
240 node = source_uris;
242 while (node)
244 gchar *file_path;
246 uri = (const gchar *)node->data;
247 file_path = gnome_vfs_get_local_path_from_uri (uri);
248 if (file_path)
249 source_files = g_list_prepend (source_files, file_path);
250 node = g_list_next (node);
252 source_files = g_list_reverse (source_files);
254 anjuta_symbol_view_update (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
255 source_files);
256 g_list_foreach (source_files, (GFunc)g_free, NULL);
257 g_list_foreach (source_uris, (GFunc)g_free, NULL);
258 g_list_free (source_files);
259 g_list_free (source_uris);
261 /* Current editor symbol model may have changed */
262 update_editor_symbol_model (sv_plugin);
264 anjuta_status_busy_pop (status);
265 anjuta_status_pop (status);
266 return FALSE;
269 static void
270 on_refresh_activate (GtkAction *action, SymbolBrowserPlugin *sv_plugin)
272 if (!sv_plugin->project_root_uri)
273 return;
274 g_idle_add (on_refresh_idle, sv_plugin);
277 static GtkActionEntry actions[] =
279 { "ActionMenuGoto", NULL, N_("_Goto"), NULL, NULL, NULL},
281 "ActionSymbolBrowserGotoDef",
282 NULL,
283 N_("Tag _Definition"),
284 "<control>d",
285 N_("Goto symbol definition"),
286 G_CALLBACK (on_goto_file_tag_def_activate)
289 "ActionSymbolBrowserGotoDecl",
290 NULL,
291 N_("Tag De_claration"),
292 "<shift><control>d",
293 N_("Goto symbol declaration"),
294 G_CALLBACK (on_goto_file_tag_decl_activate)
298 static GtkActionEntry popup_actions[] =
301 "ActionPopupSymbolBrowserGotoDef",
302 NULL,
303 N_("Goto _Definition"),
304 NULL,
305 N_("Goto symbol definition"),
306 G_CALLBACK (on_goto_def_activate)
309 "ActionPopupSymbolBrowserGotoDecl",
310 NULL,
311 N_("Goto De_claration"),
312 NULL,
313 N_("Goto symbol declaration"),
314 G_CALLBACK (on_goto_decl_activate)
317 "ActionPopupSymbolBrowserFind",
318 GTK_STOCK_FIND,
319 N_("_Find Usage"),
320 NULL,
321 N_("Find usage of symbol in project"),
322 G_CALLBACK (on_find_activate)
325 "ActionPopupSymbolBrowserRefresh",
326 GTK_STOCK_REFRESH,
327 N_("_Refresh"),
328 NULL,
329 N_("Refresh symbol browser tree"),
330 G_CALLBACK (on_refresh_activate)
334 static void
335 on_project_element_added (IAnjutaProjectManager *pm, const gchar *uri,
336 SymbolBrowserPlugin *sv_plugin)
338 gchar *filename;
340 if (!sv_plugin->project_root_uri)
341 return;
343 filename = gnome_vfs_get_local_path_from_uri (uri);
344 if (filename)
346 anjuta_symbol_view_add_source (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
347 filename);
348 g_free (filename);
352 static void
353 on_project_element_removed (IAnjutaProjectManager *pm, const gchar *uri,
354 SymbolBrowserPlugin *sv_plugin)
356 gchar *filename;
358 if (!sv_plugin->project_root_uri)
359 return;
361 filename = gnome_vfs_get_local_path_from_uri (uri);
362 if (filename)
364 anjuta_symbol_view_remove_source (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
365 filename);
366 g_free (filename);
370 // add a new project
371 static void
372 project_root_added (AnjutaPlugin *plugin, const gchar *name,
373 const GValue *value, gpointer user_data)
375 AnjutaStatus *status;
376 IAnjutaProjectManager *pm;
377 SymbolBrowserPlugin *sv_plugin;
378 const gchar *root_uri;
380 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
382 g_free (sv_plugin->project_root_uri);
383 sv_plugin->project_root_uri = NULL;
384 root_uri = g_value_get_string (value);
385 if (root_uri)
387 gchar *root_dir = gnome_vfs_get_local_path_from_uri (root_uri);
388 if (root_dir)
390 status = anjuta_shell_get_status (plugin->shell, NULL);
391 anjuta_status_progress_add_ticks (status, 1);
392 trees_signals_block (sv_plugin);
393 anjuta_symbol_view_open (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
394 root_dir);
396 /* Current editor symbol model may have changed */
397 update_editor_symbol_model (sv_plugin);
398 anjuta_status_progress_tick (status, NULL, _("Created symbols..."));
399 trees_signals_unblock (sv_plugin);
400 g_free (root_dir);
402 sv_plugin->project_root_uri = g_strdup (root_uri);
404 /* FIXME: There should be a way to ensure that this project manager
405 * is indeed the one that has opened the project_uri
407 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sv_plugin)->shell,
408 IAnjutaProjectManager, NULL);
409 g_signal_connect (G_OBJECT (pm), "element_added",
410 G_CALLBACK (on_project_element_added), sv_plugin);
411 g_signal_connect (G_OBJECT (pm), "element_removed",
412 G_CALLBACK (on_project_element_removed), sv_plugin);
415 static void
416 project_root_removed (AnjutaPlugin *plugin, const gchar *name,
417 gpointer user_data)
419 IAnjutaProjectManager *pm;
420 SymbolBrowserPlugin *sv_plugin;
422 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
424 /* Disconnect events from project manager */
426 /* FIXME: There should be a way to ensure that this project manager
427 * is indeed the one that has opened the project_uri
429 pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sv_plugin)->shell,
430 IAnjutaProjectManager, NULL);
431 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
432 on_project_element_added,
433 sv_plugin);
434 g_signal_handlers_disconnect_by_func (G_OBJECT (pm),
435 on_project_element_removed,
436 sv_plugin);
438 /* clear anjuta_symbol_search side */
439 anjuta_symbol_search_clear(ANJUTA_SYMBOL_SEARCH(sv_plugin->ss));
441 /* clear glist's sfiles */
442 anjuta_symbol_view_clear (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree));
444 g_free (sv_plugin->project_root_uri);
445 sv_plugin->project_root_uri = NULL;
448 static gboolean
449 on_treeview_event (GtkWidget *widget,
450 GdkEvent *event,
451 SymbolBrowserPlugin *sv_plugin)
453 GtkTreeView *view;
454 GtkTreeModel *model;
455 GtkTreeSelection *selection;
457 g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
459 view = GTK_TREE_VIEW (widget);
460 model = gtk_tree_view_get_model (view);
461 selection = gtk_tree_view_get_selection (view);
463 if (!event)
464 return FALSE;
466 if (event->type == GDK_BUTTON_PRESS) {
467 GdkEventButton *e = (GdkEventButton *) event;
469 if (e->button == 3) {
470 GtkWidget *menu;
472 /* Popup project menu */
473 menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (sv_plugin->ui),
474 "/PopupSymbolBrowser");
475 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
476 NULL, NULL, e->button, e->time);
477 return TRUE;
479 } else if (event->type == GDK_KEY_PRESS) {
480 GdkEventKey *e = (GdkEventKey *) event;
482 switch (e->keyval) {
483 case GDK_Return:
484 anjuta_ui_activate_action_by_group (sv_plugin->ui,
485 sv_plugin->popup_action_group,
486 "ActionPopupSymbolBrowserGotoDef");
487 return TRUE;
488 default:
489 return FALSE;
492 return FALSE;
495 static void
496 on_treeview_row_activated (GtkTreeView *view, GtkTreePath *arg1,
497 GtkTreeViewColumn *arg2,
498 SymbolBrowserPlugin *sv_plugin)
500 GtkTreeModel *model;
501 GtkTreeSelection *selection;
502 GtkTreeIter iter;
504 selection = gtk_tree_view_get_selection (view);
505 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
506 return;
507 anjuta_ui_activate_action_by_group (sv_plugin->ui,
508 sv_plugin->popup_action_group,
509 "ActionPopupSymbolBrowserGotoDef");
512 static void
513 trees_signals_block (SymbolBrowserPlugin *sv_plugin)
515 g_signal_handlers_block_by_func (G_OBJECT (sv_plugin->sv_tree),
516 G_CALLBACK (on_treeview_event), NULL);
518 g_signal_handlers_block_by_func (G_OBJECT (sv_plugin->ss),
519 G_CALLBACK (on_treesearch_symbol_selected_event),
520 NULL);
524 static void
525 trees_signals_unblock (SymbolBrowserPlugin *sv_plugin)
527 g_signal_handlers_unblock_by_func (G_OBJECT (sv_plugin->sv_tree),
528 G_CALLBACK (on_treeview_event), NULL);
530 g_signal_handlers_unblock_by_func (G_OBJECT (sv_plugin->ss),
531 G_CALLBACK (on_treesearch_symbol_selected_event),
532 NULL);
535 static void
536 goto_tree_iter (SymbolBrowserPlugin *sv_plugin, GtkTreeIter *iter)
538 gint line;
540 /* FIXME: */
541 line = anjuta_symbol_view_workspace_get_line (ANJUTA_SYMBOL_VIEW
542 (sv_plugin->sv_tree),
543 iter);
545 if (line > 0 && sv_plugin->current_editor)
547 /* Goto line number */
548 ianjuta_editor_goto_line (IANJUTA_EDITOR (sv_plugin->current_editor),
549 line, NULL);
550 if (IANJUTA_IS_MARKABLE (sv_plugin->current_editor))
552 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (sv_plugin->current_editor),
553 IANJUTA_MARKABLE_LINEMARKER,
554 NULL);
556 ianjuta_markable_mark (IANJUTA_MARKABLE (sv_plugin->current_editor),
557 line, IANJUTA_MARKABLE_LINEMARKER, NULL);
562 static void
563 on_symbol_selected (GtkAction *action, SymbolBrowserPlugin *sv_plugin)
565 GtkTreeIter iter;
567 if (egg_combo_action_get_active_iter (EGG_COMBO_ACTION (action), &iter))
569 goto_tree_iter (sv_plugin, &iter);
573 static void
574 on_local_treeview_row_activated (GtkTreeView *view, GtkTreePath *arg1,
575 GtkTreeViewColumn *arg2,
576 SymbolBrowserPlugin *sv_plugin)
578 GtkTreeModel *model;
579 GtkTreeSelection *selection;
580 GtkTreeIter iter;
582 selection = gtk_tree_view_get_selection (view);
583 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
584 return;
585 goto_tree_iter (sv_plugin, &iter);
588 /* -----------------------------------------------------------------------------
589 * will manage the click of mouse and other events on search->hitlist treeview
591 static void
592 on_treesearch_symbol_selected_event (AnjutaSymbolSearch *search,
593 AnjutaSymbolInfo *sym,
594 SymbolBrowserPlugin *sv_plugin) {
595 gboolean ret;
596 gint line;
597 const gchar *file;
599 ret = anjuta_symbol_view_get_file_symbol (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
600 sym->sym_name, TRUE,
601 &file, &line);
602 if (ret)
604 goto_file_line (ANJUTA_PLUGIN (sv_plugin), file, line);
608 static void
609 on_editor_destroy (SymbolBrowserPlugin *sv_plugin, IAnjutaEditor *editor)
611 const gchar *uri;
613 if (!sv_plugin->editor_connected || !sv_plugin->sv_tree)
614 return;
615 uri = g_hash_table_lookup (sv_plugin->editor_connected, G_OBJECT (editor));
616 if (uri && strlen (uri) > 0)
618 DEBUG_PRINT ("Removing file tags of %s", uri);
619 anjuta_symbol_view_workspace_remove_file (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
620 uri);
622 g_hash_table_remove (sv_plugin->editor_connected, G_OBJECT (editor));
625 static void
626 on_editor_saved (IAnjutaEditor *editor, const gchar *saved_uri,
627 SymbolBrowserPlugin *sv_plugin)
629 const gchar *old_uri;
630 gboolean tags_update;
631 GtkTreeModel *file_symbol_model;
632 GtkAction *action;
633 AnjutaUI *ui;
635 /* FIXME: Do this only if automatic tags update is enabled */
636 /* tags_update =
637 anjuta_preferences_get_int (te->preferences, AUTOMATIC_TAGS_UPDATE);
639 tags_update = TRUE;
640 if (tags_update)
642 gchar *local_filename;
644 /* Verify that it's local file */
645 local_filename = gnome_vfs_get_local_path_from_uri (saved_uri);
646 g_return_if_fail (local_filename != NULL);
647 g_free (local_filename);
649 if (!sv_plugin->editor_connected)
650 return;
652 old_uri = g_hash_table_lookup (sv_plugin->editor_connected, editor);
654 if (old_uri && strlen (old_uri) <= 0)
655 old_uri = NULL;
656 anjuta_symbol_view_workspace_update_file (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
657 old_uri, saved_uri);
658 g_hash_table_insert (sv_plugin->editor_connected, editor,
659 g_strdup (saved_uri));
661 /* Update File symbol view */
662 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (sv_plugin)->shell, NULL);
663 action = anjuta_ui_get_action (ui, "ActionGroupSymbolNavigation",
664 "ActionGotoSymbol");
667 file_symbol_model =
668 anjuta_symbol_view_get_file_symbol_model (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree));
669 g_object_set_data (G_OBJECT (editor), "tm_file",
670 g_object_get_data (G_OBJECT (file_symbol_model),
671 "tm_file"));
672 /* Set toolbar version */
673 egg_combo_action_set_model (EGG_COMBO_ACTION (action), file_symbol_model);
674 /* Set local view version */
675 gtk_tree_view_set_model (GTK_TREE_VIEW (sv_plugin->sl_tree),
676 file_symbol_model);
677 sv_plugin->locals_line_number = 0;
678 on_editor_update_ui (editor, sv_plugin);
680 if (gtk_tree_model_iter_n_children (file_symbol_model, NULL) > 0)
681 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
682 else
683 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
685 #if 0
686 /* FIXME: Re-hilite all editors on tags update */
687 if(update)
689 for (tmp = app->text_editor_list; tmp; tmp = g_list_next(tmp))
691 te1 = TEXT_EDITOR (tmp->data);
692 text_editor_set_hilite_type(te1);
695 #endif
699 static void
700 on_editor_foreach_disconnect (gpointer key, gpointer value, gpointer user_data)
702 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
703 G_CALLBACK (on_editor_saved),
704 user_data);
705 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
706 G_CALLBACK (on_editor_update_ui),
707 user_data);
708 g_signal_handlers_disconnect_by_func (G_OBJECT(key),
709 G_CALLBACK (on_char_added),
710 user_data);
711 g_object_weak_unref (G_OBJECT(key),
712 (GWeakNotify) (on_editor_destroy),
713 user_data);
716 static void
717 on_editor_foreach_clear (gpointer key, gpointer value, gpointer user_data)
719 const gchar *uri;
720 SymbolBrowserPlugin *sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
722 uri = (const gchar *)value;
723 if (uri && strlen (uri) > 0)
725 DEBUG_PRINT ("Removing file tags of %s", uri);
726 anjuta_symbol_view_workspace_remove_file (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
727 uri);
731 static void
732 update_editor_symbol_model (SymbolBrowserPlugin *sv_plugin)
734 AnjutaUI *ui;
735 gchar *uri;
736 GObject *editor = sv_plugin->current_editor;
738 if (!editor)
739 return;
741 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (sv_plugin)->shell, NULL);
742 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
743 if (uri)
745 gchar *local_filename;
746 GtkTreeModel *file_symbol_model;
747 GtkAction *action;
749 /* Verify that it's local file */
750 local_filename = gnome_vfs_get_local_path_from_uri (uri);
751 g_return_if_fail (local_filename != NULL);
752 g_free (local_filename);
754 anjuta_symbol_view_workspace_add_file (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree), uri);
755 action = anjuta_ui_get_action (ui, "ActionGroupSymbolNavigation",
756 "ActionGotoSymbol");
758 file_symbol_model =
759 anjuta_symbol_view_get_file_symbol_model (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree));
760 if (file_symbol_model)
762 g_object_set_data (G_OBJECT (editor), "tm_file",
763 g_object_get_data (G_OBJECT (file_symbol_model),
764 "tm_file"));
765 /* Set toolbar version */
766 egg_combo_action_set_model (EGG_COMBO_ACTION (action), file_symbol_model);
768 /* Set local view version */
769 gtk_tree_view_set_model (GTK_TREE_VIEW (sv_plugin->sl_tree),
770 file_symbol_model);
771 sv_plugin->locals_line_number = 0;
772 on_editor_update_ui (IANJUTA_EDITOR (editor), sv_plugin);
774 if (gtk_tree_model_iter_n_children (file_symbol_model, NULL) > 0)
775 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
776 else
777 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
780 if (uri)
781 g_free (uri);
784 static gboolean
785 on_editor_buffer_symbols_update_timeout (gpointer user_data)
787 SymbolBrowserPlugin *sv_plugin;
788 IAnjutaEditor *ed;
789 gchar *current_buffer = NULL;
790 gint buffer_size = 0;
791 gchar *uri = NULL;
793 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
795 if (sv_plugin->current_editor == NULL)
796 return FALSE;
798 /* we won't proceed with the updating of the symbols if we didn't type in
799 anything */
800 if (!need_symbols_update)
801 return TRUE;
803 if (sv_plugin->current_editor) {
804 ed = IANJUTA_EDITOR (sv_plugin->current_editor);
806 buffer_size = ianjuta_editor_get_length (ed, NULL);
807 current_buffer = ianjuta_editor_get_text (ed, 0, -1, NULL);
809 uri = ianjuta_file_get_uri (IANJUTA_FILE (ed), NULL);
812 else
813 return FALSE;
815 if (uri) {
816 /* FIXME: Only uncomment after investigating bug 395362 */
818 anjuta_symbol_view_update_source_from_buffer (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
819 uri, current_buffer, buffer_size);
821 g_free (uri);
824 if (current_buffer)
825 g_free (current_buffer);
827 need_symbols_update = FALSE;
829 return TRUE;
832 static gboolean
833 iter_matches (SymbolBrowserPlugin *sv_plugin, GtkTreeIter* iter,
834 GtkTreeModel* model, gint lineno)
836 gint line;
837 gtk_tree_model_get (model, iter, COL_LINE, &line, -1);
838 if (line == lineno)
840 GtkTreePath* path = gtk_tree_model_get_path (model, iter);
841 GtkAction* action = anjuta_ui_get_action (sv_plugin->ui,
842 "ActionGroupSymbolNavigation",
843 "ActionGotoSymbol");
845 egg_combo_action_set_active_iter (EGG_COMBO_ACTION (action), iter);
846 gtk_tree_view_set_cursor (GTK_TREE_VIEW (sv_plugin->sl_tree), path, NULL,
847 FALSE);
848 gtk_tree_path_free (path);
849 return TRUE;
851 return FALSE;
854 static void
855 on_editor_update_ui (IAnjutaEditor *editor, SymbolBrowserPlugin *sv_plugin)
857 gint lineno = ianjuta_editor_get_lineno (editor, NULL);
859 GtkTreeModel* model = anjuta_symbol_view_get_file_symbol_model
860 (ANJUTA_SYMBOL_VIEW(sv_plugin->sv_tree));
861 GtkTreeIter iter;
862 gboolean found = FALSE;
864 if (sv_plugin->locals_line_number == lineno)
865 return;
866 sv_plugin->locals_line_number = lineno;
868 if (!gtk_tree_model_get_iter_first (model, &iter))
869 return;
870 while (!found && lineno >= 0)
872 gtk_tree_model_get_iter_first (model, &iter);
875 found = iter_matches (sv_plugin, &iter, model, lineno);
876 if (found)
877 break;
879 while (gtk_tree_model_iter_next (model, &iter));
880 lineno--;
884 static void
885 on_char_added (IAnjutaEditor *editor, gint position, gchar ch,
886 SymbolBrowserPlugin *sv_plugin)
888 DEBUG_PRINT ("char added @ %d : %c [int %d]", position, ch, ch);
890 /* try to force the update if a "." or a "->" is pressed */
891 if ((ch == '.') || (prev_char_added == '-' && ch == '>'))
892 on_editor_buffer_symbols_update_timeout (sv_plugin);
894 need_symbols_update = TRUE;
896 prev_char_added = ch;
899 static void
900 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
901 const GValue *value, gpointer data)
903 gchar *uri;
904 GObject *editor;
905 SymbolBrowserPlugin *sv_plugin;
907 editor = g_value_get_object (value);
909 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
911 if (!sv_plugin->editor_connected)
913 sv_plugin->editor_connected = g_hash_table_new_full (g_direct_hash,
914 g_direct_equal,
915 NULL, g_free);
917 sv_plugin->current_editor = editor;
919 update_editor_symbol_model (sv_plugin);
921 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
922 if (g_hash_table_lookup (sv_plugin->editor_connected, editor) == NULL)
924 g_object_weak_ref (G_OBJECT (editor),
925 (GWeakNotify) (on_editor_destroy),
926 sv_plugin);
927 if (uri)
929 g_hash_table_insert (sv_plugin->editor_connected, editor,
930 g_strdup (uri));
932 else
934 g_hash_table_insert (sv_plugin->editor_connected, editor,
935 g_strdup (""));
937 g_signal_connect (G_OBJECT (editor), "saved",
938 G_CALLBACK (on_editor_saved),
939 sv_plugin);
941 g_signal_connect (G_OBJECT (editor), "char-added",
942 G_CALLBACK (on_char_added),
943 sv_plugin);
944 g_signal_connect (G_OBJECT(editor), "update_ui",
945 G_CALLBACK (on_editor_update_ui),
946 sv_plugin);
948 g_free (uri);
950 /* add a default timeout to the updating of buffer symbols */
951 timeout_id = g_timeout_add (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
952 on_editor_buffer_symbols_update_timeout,
953 plugin);
954 need_symbols_update = FALSE;
958 static void
959 value_removed_current_editor (AnjutaPlugin *plugin,
960 const char *name, gpointer data)
962 AnjutaUI *ui;
963 SymbolBrowserPlugin *sv_plugin;
964 GtkAction *action;
966 /* let's remove the timeout for symbols refresh */
967 g_source_remove (timeout_id);
968 need_symbols_update = FALSE;
970 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
971 ui = anjuta_shell_get_ui (plugin->shell, NULL);
972 action = anjuta_ui_get_action (ui, "ActionGroupSymbolNavigation",
973 "ActionGotoSymbol");
974 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
975 sv_plugin->current_editor = NULL;
978 static gboolean
979 activate_plugin (AnjutaPlugin *plugin)
981 GtkActionGroup *group;
982 GtkAction *action;
983 SymbolBrowserPlugin *sv_plugin;
985 DEBUG_PRINT ("SymbolBrowserPlugin: Activating Symbol Manager plugin...");
987 register_stock_icons (plugin);
989 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
990 sv_plugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
991 sv_plugin->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
993 /* Create widgets */
994 sv_plugin->sw = gtk_notebook_new();
996 /* Local symbols */
997 sv_plugin->sl = gtk_scrolled_window_new (NULL, NULL);
998 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sv_plugin->sl),
999 GTK_SHADOW_IN);
1000 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sv_plugin->sl),
1001 GTK_POLICY_AUTOMATIC,
1002 GTK_POLICY_AUTOMATIC);
1004 sv_plugin->sl_tab_label = gtk_label_new (_("Local" ));
1005 sv_plugin->sl_tree = anjuta_symbol_locals_new ();
1006 g_object_add_weak_pointer (G_OBJECT (sv_plugin->sl_tree),
1007 (gpointer)&sv_plugin->sl_tree);
1008 g_signal_connect (G_OBJECT (sv_plugin->sl_tree), "row_activated",
1009 G_CALLBACK (on_local_treeview_row_activated), plugin);
1010 gtk_container_add (GTK_CONTAINER(sv_plugin->sl), sv_plugin->sl_tree);
1012 /* add the scrolled window to the notebook */
1013 gtk_notebook_append_page (GTK_NOTEBOOK(sv_plugin->sw),
1014 sv_plugin->sl, sv_plugin->sl_tab_label );
1016 /* Global symbols */
1017 sv_plugin->sv = gtk_scrolled_window_new (NULL, NULL);
1018 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sv_plugin->sv),
1019 GTK_SHADOW_IN);
1020 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sv_plugin->sv),
1021 GTK_POLICY_AUTOMATIC,
1022 GTK_POLICY_AUTOMATIC);
1024 sv_plugin->sv_tab_label = gtk_label_new (_("Global" ));
1025 sv_plugin->sv_tree = anjuta_symbol_view_new ();
1026 g_object_add_weak_pointer (G_OBJECT (sv_plugin->sv_tree),
1027 (gpointer)&sv_plugin->sv_tree);
1029 g_signal_connect (G_OBJECT (sv_plugin->sv_tree), "event-after",
1030 G_CALLBACK (on_treeview_event), plugin);
1031 g_signal_connect (G_OBJECT (sv_plugin->sv_tree), "row_activated",
1032 G_CALLBACK (on_treeview_row_activated), plugin);
1034 gtk_container_add (GTK_CONTAINER(sv_plugin->sv), sv_plugin->sv_tree);
1036 /* add the scrolled window to the notebook */
1037 gtk_notebook_append_page (GTK_NOTEBOOK(sv_plugin->sw),
1038 sv_plugin->sv, sv_plugin->sv_tab_label );
1040 /* anjuta symbol search */
1041 sv_plugin->ss =
1042 anjuta_symbol_search_new (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree));
1043 sv_plugin->ss_tab_label = gtk_label_new (_("Search" ));
1045 g_object_add_weak_pointer (G_OBJECT (sv_plugin->ss),
1046 (gpointer)&sv_plugin->ss);
1048 gtk_notebook_append_page (GTK_NOTEBOOK(sv_plugin->sw), sv_plugin->ss,
1049 sv_plugin->ss_tab_label );
1051 gtk_widget_show_all (sv_plugin->sw);
1053 /* connect some signals */
1054 g_signal_connect (G_OBJECT (sv_plugin->ss), "symbol_selected",
1055 G_CALLBACK (on_treesearch_symbol_selected_event),
1056 plugin);
1059 /* setting focus to the tree_view*/
1060 gtk_notebook_set_current_page (GTK_NOTEBOOK (sv_plugin->sw), 0);
1062 /* Add action group */
1063 sv_plugin->action_group =
1064 anjuta_ui_add_action_group_entries (sv_plugin->ui,
1065 "ActionGroupSymbolBrowser",
1066 _("Symbol browser actions"),
1067 actions,
1068 G_N_ELEMENTS (actions),
1069 GETTEXT_PACKAGE, TRUE, plugin);
1070 sv_plugin->popup_action_group =
1071 anjuta_ui_add_action_group_entries (sv_plugin->ui,
1072 "ActionGroupPopupSymbolBrowser",
1073 _("Symbol browser popup actions"),
1074 popup_actions,
1075 G_N_ELEMENTS (popup_actions),
1076 GETTEXT_PACKAGE, FALSE, plugin);
1077 group = gtk_action_group_new ("ActionGroupSymbolNavigation");
1079 /* create a new combobox in style of libegg... */
1080 action = g_object_new (EGG_TYPE_COMBO_ACTION,
1081 "name", "ActionGotoSymbol",
1082 "label", _("Goto symbol"),
1083 "tooltip", _("Select the symbol to go"),
1084 "stock_id", GTK_STOCK_JUMP_TO,
1085 NULL);
1087 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1088 g_signal_connect (action, "activate",
1089 G_CALLBACK (on_symbol_selected), sv_plugin);
1090 gtk_action_group_add_action (group, action);
1091 anjuta_ui_add_action_group (sv_plugin->ui, "ActionGroupSymbolNavigation",
1092 N_("Symbol navigations"), group, FALSE);
1093 sv_plugin->action_group_nav = group;
1095 /* Add UI */
1096 sv_plugin->merge_id =
1097 anjuta_ui_merge (sv_plugin->ui, UI_FILE);
1099 /* Added widgets */
1100 anjuta_shell_add_widget (plugin->shell, sv_plugin->sw,
1101 "AnjutaSymbolBrowser", _("Symbols"),
1102 "symbol-browser-plugin-icon",
1103 ANJUTA_SHELL_PLACEMENT_LEFT, NULL);
1105 /* set up project directory watch */
1106 sv_plugin->root_watch_id = anjuta_plugin_add_watch (plugin,
1107 "project_root_uri",
1108 project_root_added,
1109 project_root_removed, NULL);
1110 sv_plugin->editor_watch_id =
1111 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
1112 value_added_current_editor,
1113 value_removed_current_editor, NULL);
1115 return TRUE;
1118 static gboolean
1119 deactivate_plugin (AnjutaPlugin *plugin)
1121 SymbolBrowserPlugin *sv_plugin;
1122 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (plugin);
1124 /* Ensure all editor cached info are released */
1125 if (sv_plugin->editor_connected)
1127 g_hash_table_foreach (sv_plugin->editor_connected,
1128 on_editor_foreach_disconnect, plugin);
1129 g_hash_table_foreach (sv_plugin->editor_connected,
1130 on_editor_foreach_clear, plugin);
1131 g_hash_table_destroy (sv_plugin->editor_connected);
1132 sv_plugin->editor_connected = NULL;
1134 /* Remove watches */
1135 anjuta_plugin_remove_watch (plugin, sv_plugin->root_watch_id, FALSE);
1136 anjuta_plugin_remove_watch (plugin, sv_plugin->editor_watch_id, TRUE);
1138 /* Remove widgets: Widgets will be destroyed when sw is removed */
1139 anjuta_shell_remove_widget (plugin->shell, sv_plugin->sw, NULL);
1141 /* Remove UI */
1142 anjuta_ui_unmerge (sv_plugin->ui, sv_plugin->merge_id);
1144 /* Remove action group */
1145 anjuta_ui_remove_action_group (sv_plugin->ui, sv_plugin->action_group);
1146 anjuta_ui_remove_action_group (sv_plugin->ui, sv_plugin->popup_action_group);
1147 anjuta_ui_remove_action_group (sv_plugin->ui, sv_plugin->action_group_nav);
1149 sv_plugin->root_watch_id = 0;
1150 sv_plugin->editor_watch_id = 0;
1151 sv_plugin->merge_id = 0;
1152 sv_plugin->sw = NULL;
1153 sv_plugin->sl = NULL;
1154 sv_plugin->sl_tree = NULL;
1155 sv_plugin->sv = NULL;
1156 sv_plugin->sv_tree = NULL;
1157 sv_plugin->ss = NULL;
1158 return TRUE;
1161 static void
1162 dispose (GObject *obj)
1164 SymbolBrowserPlugin *sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (obj);
1165 /* Ensure all editors are disconnected */
1166 if (sv_plugin->editor_connected)
1168 g_hash_table_foreach (sv_plugin->editor_connected,
1169 on_editor_foreach_disconnect,
1170 sv_plugin);
1171 g_hash_table_destroy (sv_plugin->editor_connected);
1172 sv_plugin->editor_connected = NULL;
1175 if (plugin->sw)
1177 g_object_unref (G_OBJECT (plugin->sw));
1178 plugin->sw = NULL;
1182 g_object_remove_weak_pointer (G_OBJECT (sv_plugin->ss),
1183 (gpointer)&sv_plugin->ss);
1186 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (obj));
1189 static void
1190 finalize (GObject *obj)
1192 /* SymbolBrowserPlugin *plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (obj); */
1193 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (obj));
1196 static void
1197 symbol_browser_plugin_instance_init (GObject *obj)
1199 SymbolBrowserPlugin *plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (obj);
1200 plugin->current_editor = NULL;
1201 plugin->editor_connected = NULL;
1202 plugin->sw = NULL;
1203 plugin->sv = NULL;
1204 plugin->gconf_notify_ids = NULL;
1205 plugin->locals_line_number = 0;
1206 plugin->launcher = NULL;
1209 static void
1210 symbol_browser_plugin_class_init (SymbolBrowserPluginClass *klass)
1212 GObjectClass *object_class;
1213 AnjutaPluginClass *plugin_class;
1215 parent_class = g_type_class_peek_parent (klass);
1216 object_class = G_OBJECT_CLASS (klass);
1217 plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1219 plugin_class->activate = activate_plugin;
1220 plugin_class->deactivate = deactivate_plugin;
1222 object_class->dispose = dispose;
1223 object_class->finalize = finalize;
1226 static IAnjutaIterable*
1227 isymbol_manager_search (IAnjutaSymbolManager *sm,
1228 IAnjutaSymbolType match_types,
1229 const gchar *match_name,
1230 gboolean partial_name_match,
1231 gboolean global_search,
1232 GError **err)
1234 const GPtrArray *tags_array;
1235 AnjutaSymbolIter *iter = NULL;
1236 const gchar *name;
1238 if (match_name && strlen (match_name) > 0)
1239 name = match_name;
1240 else
1241 name = NULL;
1243 tags_array = tm_workspace_find (name, match_types, NULL,
1244 partial_name_match, global_search);
1245 if (tags_array)
1247 iter = anjuta_symbol_iter_new (tags_array);
1248 return IANJUTA_ITERABLE (iter);
1250 return NULL;
1253 static IAnjutaIterable*
1254 isymbol_manager_get_members (IAnjutaSymbolManager *sm,
1255 const gchar *symbol_name,
1256 gboolean global_search,
1257 GError **err)
1259 const GPtrArray *tags_array;
1260 AnjutaSymbolIter *iter = NULL;
1262 tags_array = tm_workspace_find_scope_members (NULL, symbol_name,
1263 global_search, TRUE);
1266 if (tags_array)
1268 iter = anjuta_symbol_iter_new (tags_array);
1269 return IANJUTA_ITERABLE (iter);
1271 return NULL;
1274 static IAnjutaIterable*
1275 isymbol_manager_get_parents (IAnjutaSymbolManager *sm,
1276 const gchar *symbol_name,
1277 GError **err)
1279 const GPtrArray *tags_array;
1280 AnjutaSymbolIter *iter = NULL;
1282 tags_array = tm_workspace_get_parents (symbol_name);
1283 if (tags_array)
1285 iter = anjuta_symbol_iter_new (tags_array);
1286 return IANJUTA_ITERABLE (iter);
1288 return NULL;
1291 static IAnjutaIterable*
1292 isymbol_manager_get_completions_at_position (IAnjutaSymbolManager *sm,
1293 const gchar *file_uri,
1294 const gchar *text_buffer,
1295 gint text_length,
1296 gint text_pos,
1297 GError **err)
1299 SymbolBrowserPlugin *sv_plugin;
1300 const TMTag *func_scope_tag;
1301 TMSourceFile *tm_file;
1302 IAnjutaEditor *ed;
1303 AnjutaSymbolView *symbol_view;
1304 gulong line;
1305 gulong scope_position;
1306 gchar *needed_text = NULL;
1307 gint access_method;
1308 GPtrArray * completable_tags_array;
1309 AnjutaSymbolIter *iter = NULL;
1311 sv_plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (sm);
1312 ed = IANJUTA_EDITOR (sv_plugin->current_editor);
1313 symbol_view = ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree);
1315 line = ianjuta_editor_get_line_from_position (ed, text_pos, NULL);
1317 /* get the function scope */
1318 tm_file = anjuta_symbol_view_get_tm_file (symbol_view, file_uri);
1320 /* check whether the current file_uri is listed in the tm_workspace or not... */
1321 if (tm_file == NULL)
1322 return NULL;
1325 // FIXME: remove DEBUG_PRINT
1327 DEBUG_PRINT ("tags in file &s\n");
1328 if (tm_file->work_object.tags_array != NULL) {
1329 int i;
1330 for (i=0; i < tm_file->work_object.tags_array->len; i++) {
1331 TMTag *cur_tag;
1333 cur_tag = (TMTag*)g_ptr_array_index (tm_file->work_object.tags_array, i);
1334 tm_tag_print (cur_tag, stdout);
1339 func_scope_tag = tm_get_current_function (tm_file->work_object.tags_array, line);
1341 if (func_scope_tag == NULL) {
1342 DEBUG_PRINT ("func_scope_tag is NULL, seems like it's a completion on a global scope");
1343 return NULL;
1346 DEBUG_PRINT ("current expression scope: %s", func_scope_tag->name);
1349 scope_position = ianjuta_editor_get_line_begin_position (ed, func_scope_tag->atts.entry.line, NULL);
1350 needed_text = ianjuta_editor_get_text (ed, scope_position,
1351 text_pos - scope_position, NULL);
1353 if (needed_text == NULL)
1354 DEBUG_PRINT ("needed_text is null");
1355 DEBUG_PRINT ("text needed is %s", needed_text );
1358 /* we'll pass only the text of the current scope: i.e. only the current function
1359 * in which we request the completion. */
1360 TMTag * found_type = anjuta_symbol_view_get_type_of_expression (symbol_view,
1361 needed_text, text_pos - scope_position, func_scope_tag, &access_method);
1364 if (found_type == NULL) {
1365 DEBUG_PRINT ("type not found.");
1366 return NULL;
1369 /* get the completable memebers. If the access is COMPLETION_ACCESS_STATIC we don't
1370 * want to know the parents members of the class.
1372 if (access_method == COMPLETION_ACCESS_STATIC)
1373 completable_tags_array = anjuta_symbol_view_get_completable_members (found_type, FALSE);
1374 else
1375 completable_tags_array = anjuta_symbol_view_get_completable_members (found_type, TRUE);
1377 if (completable_tags_array)
1379 iter = anjuta_symbol_iter_new (completable_tags_array);
1380 return IANJUTA_ITERABLE (iter);
1382 return NULL;
1386 static void
1387 isymbol_manager_iface_init (IAnjutaSymbolManagerIface *iface)
1389 iface->search = isymbol_manager_search;
1390 iface->get_members = isymbol_manager_get_members;
1391 iface->get_parents = isymbol_manager_get_parents;
1392 iface->get_completions_at_position = isymbol_manager_get_completions_at_position;
1395 static void
1396 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
1398 symbol_browser_prefs_init(ANJUTA_PLUGIN_SYMBOL_BROWSER (ipref));
1401 static void
1402 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
1404 symbol_browser_prefs_finalize (ANJUTA_PLUGIN_SYMBOL_BROWSER (ipref));
1407 static void
1408 ipreferences_iface_init(IAnjutaPreferencesIface* iface)
1410 iface->merge = ipreferences_merge;
1411 iface->unmerge = ipreferences_unmerge;
1414 ANJUTA_PLUGIN_BEGIN (SymbolBrowserPlugin, symbol_browser_plugin);
1415 ANJUTA_PLUGIN_ADD_INTERFACE (isymbol_manager, IANJUTA_TYPE_SYMBOL_MANAGER);
1416 ANJUTA_PLUGIN_ADD_INTERFACE (ipreferences, IANJUTA_TYPE_PREFERENCES);
1417 ANJUTA_PLUGIN_END;
1419 ANJUTA_SIMPLE_PLUGIN (SymbolBrowserPlugin, symbol_browser_plugin);