Updated Spanish translation
[anjuta-git-plugin.git] / plugins / symbol-browser / an_symbol_prefs.c
blob5e5c7fd02d34257d2d0dbee47582dbd3cbf36952
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 an_symbol_prefs.c
4 Copyright (C) 2004 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <dirent.h>
25 #include <string.h>
26 #include <gtk/gtktreeview.h>
27 #include <gtk/gtkliststore.h>
28 #include <libgnomevfs/gnome-vfs.h>
29 #include <libanjuta/anjuta-debug.h>
30 #include <libanjuta/anjuta-launcher.h>
32 #include "an_symbol_prefs.h"
33 #include "tm_tagmanager.h"
35 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-symbol-browser-plugin.glade"
36 #define ICON_FILE "anjuta-symbol-browser-plugin.png"
37 #define LOCAL_TAGS_DIR ".anjuta/tags"
38 #define SYSTEM_TAGS_CACHE ".anjuta/system-tags.cache"
39 #define SYMBOL_BROWSER_TAGS "symbol.browser.tags"
40 #define CREATE_GLOBAL_TAGS PACKAGE_DATA_DIR"/scripts/create_global_tags.sh"
42 enum
44 COLUMN_LOAD,
45 COLUMN_NAME,
46 COLUMN_PATH,
47 N_COLUMNS
50 static void
51 update_system_tags (GList *tags_files)
53 gchar *output_file;
55 output_file = g_build_filename (g_get_home_dir (), SYSTEM_TAGS_CACHE, NULL);
57 DEBUG_PRINT ("Recreating system tags cache: %s", output_file);
59 if (!tm_workspace_merge_global_tags (output_file, tags_files))
61 g_warning ("Error while re-creating system tags cache");
64 /* Reload tags */
65 tm_workspace_reload_global_tags(output_file);
67 g_free (output_file);
70 static void
71 update_system_tags_only_add (const gchar *tag_file)
73 GList *tags_files;
74 gchar *output_file;
76 output_file = g_build_filename (g_get_home_dir (), SYSTEM_TAGS_CACHE, NULL);
78 DEBUG_PRINT ("Recreating system tags cache: %s", output_file);
80 tags_files = g_list_append (NULL, output_file);
81 tags_files = g_list_append (tags_files, (gpointer) tag_file);
82 if (!tm_workspace_merge_global_tags (output_file, tags_files))
84 g_warning ("Error while re-creating system tags cache");
86 /* Reload tags */
87 tm_workspace_reload_global_tags(output_file);
89 g_free (output_file);
92 static gboolean
93 str_has_suffix (const char *haystack, const char *needle)
95 const char *h, *n;
97 if (needle == NULL) {
98 return TRUE;
100 if (haystack == NULL) {
101 return needle[0] == '\0';
104 /* Eat one character at a time. */
105 h = haystack + strlen(haystack);
106 n = needle + strlen(needle);
107 do {
108 if (n == needle) {
109 return TRUE;
111 if (h == haystack) {
112 return FALSE;
114 } while (*--h == *--n);
115 return FALSE;
118 static void
119 select_loaded_tags (GtkListStore * store, AnjutaPreferences *prefs)
121 GtkTreeIter iter;
122 gchar *all_tags_path;
123 gchar **tags_paths, **tags_path;
124 GHashTable *path_hash;
126 all_tags_path = anjuta_preferences_get (prefs, SYMBOL_BROWSER_TAGS);
127 if (all_tags_path == NULL)
128 return;
130 tags_paths = g_strsplit (all_tags_path, ":", -1);
131 path_hash = g_hash_table_new (g_str_hash, g_str_equal);
132 tags_path = tags_paths;
133 while (*tags_path)
135 g_hash_table_insert (path_hash, *tags_path, *tags_path);
136 tags_path++;
139 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
143 gchar *tag_path;
145 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
146 COLUMN_PATH, &tag_path,
147 -1);
148 if (g_hash_table_lookup (path_hash, tag_path))
149 gtk_list_store_set (store, &iter, COLUMN_LOAD, TRUE, -1);
150 else
151 gtk_list_store_set (store, &iter, COLUMN_LOAD, FALSE, -1);
152 g_free (tag_path);
154 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
156 g_hash_table_destroy (path_hash);
157 g_strfreev (tags_paths);
158 g_free (all_tags_path);
161 static GtkListStore *
162 create_store (AnjutaPreferences *prefs)
164 GList *node;
165 gchar *local_tags_dir;
166 GList *tags_dirs = NULL;
167 GtkListStore *store;
169 /* Create store */
170 store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING,
171 G_TYPE_STRING);
173 local_tags_dir = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, NULL);
174 tags_dirs = g_list_prepend (tags_dirs, local_tags_dir);
176 /* Load the tags files */
177 node = tags_dirs;
178 while (node)
180 DIR *dir;
181 struct dirent *entry;
182 const gchar *dirname;
184 dirname = (const gchar*)node->data;
185 node = g_list_next (node);
187 dir = opendir (dirname);
188 if (!dir)
189 continue;
191 for (entry = readdir (dir); entry != NULL; entry = readdir (dir))
193 if (str_has_suffix (entry->d_name, ".anjutatags.gz"))
195 gchar *pathname;
196 gchar *tag_name;
197 GtkTreeIter iter;
199 tag_name = g_strndup (entry->d_name,
200 strlen (entry->d_name) -
201 strlen (".anjutatags.gz"));
202 pathname = g_build_filename (dirname, entry->d_name, NULL);
204 gtk_list_store_append (store, &iter);
205 gtk_list_store_set (store, &iter, COLUMN_LOAD, FALSE,
206 COLUMN_NAME, tag_name,
207 COLUMN_PATH, pathname, -1);
208 g_free (tag_name);
209 g_free (pathname);
212 closedir (dir);
214 g_list_foreach (tags_dirs, (GFunc)g_free, NULL);
215 g_list_free (tags_dirs);
217 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
218 COLUMN_NAME, GTK_SORT_ASCENDING);
219 select_loaded_tags (store, prefs);
220 return store;
223 static void
224 on_tag_load_toggled (GtkCellRendererToggle *cell, char *path_str,
225 SymbolBrowserPlugin *plugin)
227 GtkTreeIter iter;
228 GtkTreePath *path;
229 gboolean enabled;
230 AnjutaPreferences *prefs;
231 gchar *tag_path;
232 GList *enabled_paths;
233 GtkListStore *store;
234 AnjutaStatus *status;
236 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
237 store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (plugin->pref_tree_view)));
238 prefs = plugin->prefs;
240 anjuta_status_busy_push (status);
242 path = gtk_tree_path_new_from_string (path_str);
243 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
244 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
245 COLUMN_LOAD, &enabled,
246 -1);
247 enabled = !enabled;
248 gtk_list_store_set (store, &iter, COLUMN_LOAD, enabled, -1);
249 gtk_tree_path_free (path);
251 enabled_paths = NULL;
252 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
256 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
257 COLUMN_LOAD, &enabled,
258 COLUMN_PATH, &tag_path,
259 -1);
260 if (enabled)
261 enabled_paths = g_list_prepend (enabled_paths, tag_path);
264 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
267 if (enabled_paths)
269 GList *node;
270 GString *str;
271 gboolean first;
272 gchar *final_str;
274 enabled_paths = g_list_sort (enabled_paths, (GCompareFunc)strcmp);
275 node = enabled_paths;
276 str = g_string_new ("");
277 first = TRUE;
278 while (node)
280 if (first)
282 first = FALSE;
283 str = g_string_append (str, (const gchar*) node->data);
285 else
287 str = g_string_append (str, ":");
288 str = g_string_append (str, (const gchar*) node->data);
290 node = g_list_next (node);
293 /* Update preferences */
294 final_str = g_string_free (str, FALSE);
295 anjuta_preferences_set (prefs, SYMBOL_BROWSER_TAGS, final_str);
297 /* Update system tags cache */
298 if (enabled)
300 update_system_tags_only_add (tag_path);
302 else
304 update_system_tags (enabled_paths);
305 g_free (final_str);
308 else
310 /* Unset key and clear all tags */
311 anjuta_preferences_set (prefs, SYMBOL_BROWSER_TAGS, "");
313 g_list_foreach (enabled_paths, (GFunc)g_free, NULL);
314 g_list_free (enabled_paths);
315 anjuta_status_busy_pop (status);
318 static void
319 on_add_directory_clicked (GtkWidget *button, GtkListStore *store)
321 GtkTreeIter iter;
322 GtkWidget *fileselection;
323 GtkWidget *parent;
325 parent = gtk_widget_get_toplevel (button);
326 fileselection = gtk_file_chooser_dialog_new (_("Select directory"),
327 GTK_WINDOW (parent),
328 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
329 GTK_STOCK_CANCEL,
330 GTK_RESPONSE_CANCEL,
331 GTK_STOCK_OK,
332 GTK_RESPONSE_OK,
333 NULL);
334 if (gtk_dialog_run (GTK_DIALOG (fileselection)) == GTK_RESPONSE_OK)
336 GSList *dirs, *node;
338 /* Only local files since we can only create tags for local files */
339 dirs = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (fileselection));
341 node = dirs;
342 while (node)
344 gchar *dir = node->data;
345 gtk_list_store_append (store, &iter);
346 gtk_list_store_set (store, &iter, 0, dir, -1);
347 g_free (dir);
348 node = g_slist_next (node);
350 g_slist_free (dirs);
352 gtk_widget_destroy (fileselection);
355 static void
356 refresh_tags_list (SymbolBrowserPlugin *plugin)
358 GtkListStore *new_tags_store;
359 if (plugin->pref_tree_view)
361 new_tags_store = create_store (plugin->prefs);
362 gtk_tree_view_set_model (GTK_TREE_VIEW (plugin->pref_tree_view),
363 GTK_TREE_MODEL (new_tags_store));
364 g_object_unref (new_tags_store);
368 static void
369 on_create_tags_clicked (GtkButton *widget, SymbolBrowserPlugin *plugin)
371 GtkWidget *treeview, *button, *dlg, *name_entry;
372 GtkCellRenderer *renderer;
373 GtkTreeViewColumn *column;
374 GtkListStore *store;
375 AnjutaPreferences *pref;
376 GladeXML *gxml;
378 pref = plugin->prefs;
379 gxml = glade_xml_new (GLADE_FILE, "create.symbol.tags.dialog", NULL);
381 dlg = glade_xml_get_widget (gxml, "create.symbol.tags.dialog");
382 treeview = glade_xml_get_widget (gxml, "directory_list_treeview");
383 name_entry = glade_xml_get_widget (gxml, "symbol_tags_name_entry");
385 store = gtk_list_store_new (1, G_TYPE_STRING);
386 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
387 GTK_TREE_MODEL (store));
389 /* Add the column for stock treeview */
390 renderer = gtk_cell_renderer_text_new ();
391 column = gtk_tree_view_column_new_with_attributes (_("Directories to scan"),
392 renderer, "text",
394 NULL);
395 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
396 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
397 gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
398 COLUMN_NAME);
400 button = glade_xml_get_widget (gxml, "add_directory_button");
401 g_signal_connect (G_OBJECT (button), "clicked",
402 G_CALLBACK (on_add_directory_clicked), store);
404 button = glade_xml_get_widget (gxml, "clear_list_button");
405 g_signal_connect_swapped (G_OBJECT (button), "clicked",
406 G_CALLBACK (gtk_list_store_clear), store);
408 gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (plugin->prefs));
409 while (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK)
411 GtkTreeIter iter;
412 gchar **argv, *tmp;
413 const gchar *name;
414 gint argc;
415 pid_t pid;
417 name = gtk_entry_get_text (GTK_ENTRY (name_entry));
419 argc = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store),
420 NULL) * 3 + 3;
422 if (name == NULL || strlen (name) <= 0 || argc <= 3)
424 /* Validation failed */
425 GtkWidget *edlg;
427 edlg = gtk_message_dialog_new (GTK_WINDOW (dlg),
428 GTK_DIALOG_DESTROY_WITH_PARENT,
429 GTK_MESSAGE_ERROR,
430 GTK_BUTTONS_CLOSE,
431 _("Please enter a name and at least one directory."));
432 gtk_dialog_run (GTK_DIALOG (edlg));
433 gtk_widget_destroy (edlg);
434 continue;
437 argv = g_new0 (gchar*, argc);
439 argv[0] = g_strdup ("anjuta-tags");
440 tmp = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, name, NULL);
441 argv[1] = g_strconcat (tmp, ".anjutatags", NULL);
442 g_free (tmp);
444 argc = 2;
445 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
449 gchar *dir;
450 gchar *files;
452 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
453 0, &dir, -1);
455 files = g_build_filename (dir, "*.h", NULL);
456 DEBUG_PRINT ("%d: Adding scan files '%s'", argc, files);
457 argv[argc++] = g_strconcat ("\"", files, "\"", NULL);
458 g_free (files);
460 files = g_build_filename (dir, "*", "*.h", NULL);
461 DEBUG_PRINT ("%d: Adding scan files '%s'", argc, files);
462 argv[argc++] = g_strconcat ("\"", files, "\"", NULL);
463 g_free (files);
465 files = g_build_filename (dir, "*", "*", "*.h", NULL);
466 DEBUG_PRINT ("%d: Adding scan files '%s'", argc, files);
467 argv[argc++] = g_strconcat ("\"", files, "\"", NULL);
468 g_free (files);
470 g_free (dir);
472 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
475 /* Create local tags directory */
476 tmp = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, NULL);
477 if ((pid = fork()) == 0)
479 execlp ("mkdir", "mkdir", "-p", tmp, NULL);
480 perror ("Could not execute mkdir");
482 waitpid (pid, NULL, 0);
483 g_free (tmp);
485 /* Execute anjuta-tags to create tags for the given files */
486 if ((pid = fork()) == 0)
488 execvp (g_build_filename (PACKAGE_DATA_DIR, "scripts",
489 "anjuta-tags", NULL), argv);
490 perror ("Could not execute anjuta-tags");
492 waitpid (pid, NULL, 0);
494 /* Compress the tags file */
495 if ((pid = fork()) == 0)
497 execlp ("gzip", "gzip", "-f", argv[1], NULL);
498 perror ("Could not execute gzip");
500 waitpid (pid, NULL, 0);
502 g_strfreev (argv);
504 /* Refresh the tags list */
505 refresh_tags_list (plugin);
506 break;
508 g_object_unref (store);
509 g_object_unref (gxml);
510 gtk_widget_destroy (dlg);
513 static void
514 on_add_tags_clicked (GtkWidget *button, SymbolBrowserPlugin *plugin)
516 GtkWidget *fileselection;
517 GtkWidget *parent;
518 GtkFileFilter *filter;
520 parent = gtk_widget_get_toplevel (button);
522 fileselection = gtk_file_chooser_dialog_new (_("Select directory"),
523 GTK_WINDOW (parent),
524 GTK_FILE_CHOOSER_ACTION_OPEN,
525 GTK_STOCK_CANCEL,
526 GTK_RESPONSE_CANCEL,
527 GTK_STOCK_OK,
528 GTK_RESPONSE_OK,
529 NULL);
530 filter = gtk_file_filter_new ();
531 gtk_file_filter_set_name (filter, _("Anjuta tags files"));
532 gtk_file_filter_add_pattern (filter, "*.anjutatags.gz");
533 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileselection), filter);
535 if (gtk_dialog_run (GTK_DIALOG (fileselection)) == GTK_RESPONSE_OK)
537 GSList *uris, *node;
538 gchar *tmp;
539 pid_t pid;
541 /* Create local tags directory */
542 tmp = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, NULL);
543 if ((pid = fork()) == 0)
545 execlp ("mkdir", "mkdir", "-p", tmp, NULL);
546 perror ("Could not execute mkdir");
548 waitpid (pid, NULL, 0);
549 g_free (tmp);
551 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (fileselection));
553 node = uris;
554 while (node)
556 gchar *dest, *src, *basename;
558 src = node->data;
559 basename = g_path_get_basename (src);
560 dest = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, basename, NULL);
561 g_free (basename);
563 /* Copy the tags file in local tags directory */
564 GnomeVFSURI* source_uri = gnome_vfs_uri_new(src);
565 GnomeVFSURI* dest_uri = gnome_vfs_uri_new(dest);
567 GnomeVFSResult error = gnome_vfs_xfer_uri (source_uri,
568 dest_uri,
569 GNOME_VFS_XFER_DEFAULT,
570 GNOME_VFS_XFER_ERROR_MODE_ABORT,
571 GNOME_VFS_XFER_OVERWRITE_MODE_ABORT,
572 NULL,
573 NULL);
574 if (error != GNOME_VFS_OK)
576 const gchar *err;
578 err = gnome_vfs_result_to_string (error);
579 anjuta_util_dialog_error (GTK_WINDOW (fileselection),
580 "Adding tags file '%s' failed: %s",
581 src, err);
583 gnome_vfs_uri_unref (source_uri);
584 gnome_vfs_uri_unref (dest_uri);
585 g_free (dest);
586 g_free (src);
587 node = g_slist_next (node);
589 if (uris)
591 refresh_tags_list (plugin);
593 g_slist_free (uris);
595 gtk_widget_destroy (fileselection);
598 static void
599 on_remove_tags_clicked (GtkWidget *button, SymbolBrowserPlugin *plugin)
601 GtkWidget *parent;
602 GtkTreeSelection *sel;
603 GtkTreeIter iter;
604 GtkTreeModel *model;
606 parent = gtk_widget_get_toplevel (button);
607 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (plugin->pref_tree_view));
608 if (gtk_tree_selection_get_selected (sel, &model, &iter))
610 gchar *tags_filename;
611 gtk_tree_model_get (model, &iter, 1, &tags_filename, -1);
612 if (tags_filename)
614 gchar *file_path, *path;
615 path = g_build_filename (g_get_home_dir(), LOCAL_TAGS_DIR,
616 tags_filename, NULL);
617 file_path = g_strconcat (path, ".anjutatags.gz", NULL);
619 if (!g_file_test (file_path, G_FILE_TEST_EXISTS))
621 anjuta_util_dialog_error (GTK_WINDOW (parent),
622 "Can not remove tags file '%s': "
623 "You can only remove tags you created or added",
624 tags_filename);
626 else if (anjuta_util_dialog_boolean_question (GTK_WINDOW (parent),
627 "Are you sure you want to remove the tags file '%s'?",
628 tags_filename))
630 unlink (file_path);
631 refresh_tags_list (plugin);
633 g_free (file_path);
634 g_free (path);
635 g_free (tags_filename);
640 static void
641 on_message (AnjutaLauncher *launcher,
642 AnjutaLauncherOutputType output_type,
643 const gchar * mesg, gpointer user_data)
645 AnjutaStatus *status;
646 gchar **lines, **line;
647 SymbolBrowserPlugin* plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
649 lines = g_strsplit (mesg, "\n", -1);
650 if (!lines)
651 return;
653 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
655 line = lines;
656 while (*line)
658 gint packages_count;
659 gchar *pos;
661 if (sscanf (*line, "Scanning %d packages", &packages_count) == 1)
662 anjuta_status_progress_add_ticks (status, packages_count + 1);
663 else if ((pos = strstr (*line, ".anjutatags.gz")))
665 const gchar *package_name;
667 /* Get the name of the package */
668 *pos = '\0';
669 package_name = g_strrstr (*line, "/");
670 if (package_name)
672 gchar *status_mesg;
673 package_name++;
674 status_mesg = g_strdup_printf (_("Scanning package: %s"),
675 package_name);
676 anjuta_status_progress_tick (status, NULL, status_mesg);
677 g_free (status_mesg);
679 else
680 anjuta_status_progress_tick (status, NULL, *line);
682 line++;
684 g_strfreev (lines);
687 static void
688 on_system_tags_update_finished (AnjutaLauncher *launcher, gint child_pid,
689 gint status, gulong time_taken,
690 SymbolBrowserPlugin *plugin)
692 AnjutaStatus *statusbar;
693 GList *enabled_paths = NULL;
694 gchar *all_tags_path;
695 gchar **tags_paths, **tags_path;
697 all_tags_path = anjuta_preferences_get (plugin->prefs,
698 SYMBOL_BROWSER_TAGS);
699 if (all_tags_path)
701 tags_paths = g_strsplit (all_tags_path, ":", -1);
702 tags_path = tags_paths;
703 while (*tags_path)
705 enabled_paths = g_list_prepend (enabled_paths,
706 g_strdup (*tags_path));
707 tags_path++;
709 g_free (all_tags_path);
710 g_strfreev (tags_paths);
711 enabled_paths = g_list_reverse (enabled_paths);
714 /* Refresh the list */
715 refresh_tags_list(plugin);
717 /* Regenerate system-tags.cache */
718 if (enabled_paths)
720 update_system_tags (enabled_paths);
721 g_list_foreach (enabled_paths, (GFunc)g_free, NULL);
722 g_list_free (enabled_paths);
725 g_object_unref (plugin->launcher);
726 plugin->launcher = NULL;
727 statusbar = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
728 anjuta_status_progress_tick (statusbar, NULL,
729 _("Completed system tags generation"));
732 static void
733 on_update_global_clicked (GtkWidget *button, SymbolBrowserPlugin *plugin)
735 gchar* tmp;
736 gint pid;
738 if (plugin->launcher)
739 return; /* Already running */
741 /* Create local tags directory */
742 tmp = g_build_filename (g_get_home_dir (), LOCAL_TAGS_DIR, NULL);
743 if ((pid = fork()) == 0)
745 execlp ("mkdir", "mkdir", "-p", tmp, NULL);
746 perror ("Could not execute mkdir");
748 waitpid (pid, NULL, 0);
749 g_free (tmp);
751 plugin->launcher = anjuta_launcher_new ();
752 g_signal_connect (G_OBJECT (plugin->launcher), "child-exited",
753 G_CALLBACK (on_system_tags_update_finished), plugin);
754 anjuta_launcher_set_buffered_output (plugin->launcher, TRUE);
755 anjuta_launcher_execute (plugin->launcher, CREATE_GLOBAL_TAGS,
756 on_message, plugin);
759 static GtkWidget *
760 prefs_page_init (SymbolBrowserPlugin *plugin)
762 GtkWidget *treeview, *button;
763 GtkCellRenderer *renderer;
764 GtkTreeViewColumn *column;
765 GtkListStore *store;
766 AnjutaPreferences *pref = plugin->prefs;
767 GladeXML *gxml = glade_xml_new (GLADE_FILE, NULL, NULL);
769 anjuta_preferences_add_page (pref, gxml, "Symbol Browser",
770 _("Symbol Browser"), ICON_FILE);
771 treeview = glade_xml_get_widget (gxml, "tags_treeview");
773 store = create_store (pref);
774 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
775 GTK_TREE_MODEL (store));
777 /* Add the column for stock treeview */
778 renderer = gtk_cell_renderer_toggle_new ();
779 g_signal_connect (G_OBJECT (renderer), "toggled",
780 G_CALLBACK (on_tag_load_toggled), plugin);
781 column = gtk_tree_view_column_new_with_attributes (_("Load"),
782 renderer,
783 "active",
784 COLUMN_LOAD,
785 NULL);
786 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
788 renderer = gtk_cell_renderer_text_new ();
789 column = gtk_tree_view_column_new_with_attributes (_("API Tags"),
790 renderer, "text",
791 COLUMN_NAME,
792 NULL);
793 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
794 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
795 gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
796 COLUMN_NAME);
798 button = glade_xml_get_widget (gxml, "create_tags_button");
799 g_signal_connect (G_OBJECT (button), "clicked",
800 G_CALLBACK (on_create_tags_clicked), plugin);
802 button = glade_xml_get_widget (gxml, "add_tags_button");
803 g_signal_connect (G_OBJECT (button), "clicked",
804 G_CALLBACK (on_add_tags_clicked), plugin);
806 button = glade_xml_get_widget (gxml, "remove_tags_button");
807 g_signal_connect (G_OBJECT (button), "clicked",
808 G_CALLBACK (on_remove_tags_clicked), plugin);
810 button = glade_xml_get_widget (gxml, "update_tags_button");
811 g_signal_connect (G_OBJECT (button), "clicked",
812 G_CALLBACK (on_update_global_clicked), plugin);
815 g_object_unref (store);
816 g_object_unref (gxml);
817 return treeview;
820 static void
821 on_gconf_notify_tags_list_changed (GConfClient *gclient, guint cnxn_id,
822 GConfEntry *entry, gpointer user_data)
824 GtkListStore *store;
825 SymbolBrowserPlugin *plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
827 if (plugin->pref_tree_view)
829 store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (plugin->pref_tree_view)));
830 select_loaded_tags (store, plugin->prefs);
834 void
835 symbol_browser_prefs_init (SymbolBrowserPlugin *plugin)
837 guint notify_id;
838 plugin->pref_tree_view = prefs_page_init (plugin);
839 g_object_add_weak_pointer (G_OBJECT (plugin->pref_tree_view),
840 (gpointer)&plugin->pref_tree_view);
841 plugin->gconf_notify_ids = NULL;
842 notify_id = anjuta_preferences_notify_add (plugin->prefs,
843 SYMBOL_BROWSER_TAGS,
844 on_gconf_notify_tags_list_changed,
845 plugin, NULL);
846 plugin->gconf_notify_ids = g_list_prepend (plugin->gconf_notify_ids,
847 GUINT_TO_POINTER (notify_id));
850 void
851 symbol_browser_prefs_finalize (SymbolBrowserPlugin *plugin)
853 GList *node;
854 node = plugin->gconf_notify_ids;
855 while (node)
857 anjuta_preferences_notify_remove (plugin->prefs,
858 GPOINTER_TO_UINT (node->data));
859 node = g_list_next (node);
861 g_list_free (plugin->gconf_notify_ids);
862 plugin->gconf_notify_ids = NULL;
864 anjuta_preferences_remove_page(plugin->prefs, _("Symbol Browser"));
867 static gboolean
868 symbol_browser_prefs_create_global_tags (gpointer user_data)
870 SymbolBrowserPlugin *plugin = ANJUTA_PLUGIN_SYMBOL_BROWSER (user_data);
871 on_update_global_clicked (NULL, plugin);
872 return FALSE; /* Stop g_idle */
875 void
876 symbol_browser_load_global_tags (gpointer plugin)
878 gchar *system_tags_path;
879 /* Load gloabal tags on gtk idle */
880 system_tags_path = g_build_filename (g_get_home_dir(), ".anjuta",
881 "system-tags.cache", NULL);
882 if (!tm_workspace_load_global_tags (system_tags_path))
884 g_message ("Added idle loop to create global tags");
885 g_idle_add((GSourceFunc) symbol_browser_prefs_create_global_tags,
886 plugin);
888 g_free (system_tags_path);