anjuta r4082 - in trunk: . plugins/symbol-db



Author: jhs
Date: Wed Jul 16 16:11:05 2008
New Revision: 4082
URL: http://svn.gnome.org/viewvc/anjuta?rev=4082&view=rev

Log:
2008-07-14  Massimo Cora\'  <maxcvs email it>

	* plugins/symbol-db/plugin.c (on_editor_destroy),
	(on_session_save), (on_session_load), (on_project_element_removed),
	(do_import_system_src_after_abort),
	(do_import_project_src_after_abort), (do_import_sources),
	(on_project_root_added), (symbol_db_activate),
	(symbol_db_deactivate), (isymbol_manager_search), (g_list_compare),
	(on_prefs_package_add), (on_prefs_package_remove),
	(ipreferences_merge), (ipreferences_unmerge):
	* plugins/symbol-db/plugin.h:
	* plugins/symbol-db/symbol-db-engine.c
	(sdb_engine_get_dyn_query_node_by_id),
	(sdb_engine_insert_dyn_query_node_by_id),
	(sdb_engined_ctags_launcher_create), (sdb_engine_scan_files_1),
	(sdb_engine_init), (sdb_engine_finalize),
	(symbol_db_engine_set_ctags_path), (symbol_db_engine_new),
	(symbol_db_engine_project_exists),
	(symbol_db_engine_add_new_files),
	(symbol_db_engine_get_files_with_zero_symbols),
	(sdb_engine_prepare_symbol_info_sql):
	* plugins/symbol-db/symbol-db-engine.h:
	* plugins/symbol-db/symbol-db-prefs.c
	(on_prefs_executable_changed), (on_listall_output),
	(on_listall_exit), (on_tag_load_toggled_parseable_cb),
	(on_tag_load_toggled), (sdb_prefs_init1), (sdb_prefs_init),
	(sdb_prefs_finalize), (sdb_prefs_class_init),
	(symbol_db_prefs_new):
	* plugins/symbol-db/symbol-db-prefs.h:
	Rewritten symbol-db-prefs.[c|h]. SymbolDBPrefs is now an object. 
	It\'s more usable/maintainable.
	Session packages are now saved and reloaded at session-start time.
	Code cleaning.

	* plugins/symbol-db/symbol-db-system.c (destroy_engine_scan_data),
	(sdb_system_do_engine_scan), (on_engine_package_scan_end),
	(sdb_system_do_scan_package_1), (on_pkg_config_exit),
	(symbol_db_system_scan_package), (symbol_db_parse_aborted_package):
	* plugins/symbol-db/symbol-db-system.h:
	* plugins/symbol-db/symbol-db-view.c
	(sdb_view_namespace_row_expanded), (sdb_view_global_row_expanded):
	Added \'continue global tags scan after abort\' feature.
	Code cleaning.

Modified:
   trunk/ChangeLog
   trunk/plugins/symbol-db/Makefile.am
   trunk/plugins/symbol-db/anjuta-symbol-db.glade
   trunk/plugins/symbol-db/plugin.c
   trunk/plugins/symbol-db/plugin.h
   trunk/plugins/symbol-db/symbol-db-engine.c
   trunk/plugins/symbol-db/symbol-db-engine.h
   trunk/plugins/symbol-db/symbol-db-prefs.c
   trunk/plugins/symbol-db/symbol-db-prefs.h
   trunk/plugins/symbol-db/symbol-db-system.c
   trunk/plugins/symbol-db/symbol-db-system.h
   trunk/plugins/symbol-db/symbol-db-view.c

Modified: trunk/plugins/symbol-db/Makefile.am
==============================================================================
--- trunk/plugins/symbol-db/Makefile.am	(original)
+++ trunk/plugins/symbol-db/Makefile.am	Wed Jul 16 16:11:05 2008
@@ -56,9 +56,9 @@
 	symbol-db-view-search.c \
     	symbol-db-engine-iterator-node.h \
 	symbol-db-engine-iterator-node.c \
-	symbol-db-prefs.c \
-	symbol-db-prefs.h  symbol-db-system.h \
-	symbol-db-system.c
+	symbol-db-system.h \
+	symbol-db-system.c  symbol-db-prefs.h \
+	symbol-db-prefs.c
 
 libanjuta_symbol_db_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 

Modified: trunk/plugins/symbol-db/anjuta-symbol-db.glade
==============================================================================
--- trunk/plugins/symbol-db/anjuta-symbol-db.glade	(original)
+++ trunk/plugins/symbol-db/anjuta-symbol-db.glade	Wed Jul 16 16:11:05 2008
@@ -1,6 +1,7 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.4 on Wed Jul  9 23:45:46 2008 -->
 <glade-interface>
-  <requires-version lib="gtk+" version="2.12"/>
   <widget class="GtkWindow" id="symbol_db_pref_window">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <child>
@@ -39,8 +40,8 @@
                       <widget class="GtkFileChooserButton" id="preferences_file:text:/usr/bin/ctags:0:symboldb.ctags">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="use_preview_label">False</property>
                         <property name="preview_widget_active">False</property>
+                        <property name="use_preview_label">False</property>
                         <property name="title" translatable="yes">Choose ctags executable</property>
                       </widget>
                       <packing>

Modified: trunk/plugins/symbol-db/plugin.c
==============================================================================
--- trunk/plugins/symbol-db/plugin.c	(original)
+++ trunk/plugins/symbol-db/plugin.c	Wed Jul 16 16:11:05 2008
@@ -54,9 +54,10 @@
 #define TIMEOUT_SECONDS_AFTER_LAST_TIP		5
 
 #define CHOOSER_WIDGET		"preferences_folder:text:/:0:symboldb.root"
-
 #define PROJECT_GLOBALS		"/"
-
+#define CTAGS_PREFS_KEY		"symboldb.ctags"
+#define SESSION_SECTION		"SymbolDB"
+#define SESSION_KEY			"SystemPackages"
 
 static gpointer parent_class;
 static gboolean need_symbols_update = FALSE;
@@ -174,15 +175,6 @@
 		return;
 	
 	uri = g_hash_table_lookup (sdb_plugin->editor_connected, G_OBJECT (editor));
-	if (uri && strlen (uri) > 0)
-	{
-/*				
-		DEBUG_PRINT ("Removing file tags of %s", uri);
-
-		anjuta_symbol_view_workspace_remove_file (ANJUTA_SYMBOL_VIEW (sv_plugin->sv_tree),
-											   uri);
-*/		
-	}
 	g_hash_table_remove (sdb_plugin->editor_connected, G_OBJECT (editor));
 }
 
@@ -358,20 +350,78 @@
 }
 
 static void
+on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
+				 AnjutaSession *session,
+				 SymbolDBPlugin *sdb_plugin)
+{
+	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
+		return;
+
+	DEBUG_PRINT ("SymbolDB: session_save");
+
+	anjuta_session_set_string_list (session, 
+									SESSION_SECTION, 
+									SESSION_KEY,
+									sdb_plugin->session_packages);	
+}
+
+static void
 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
 				 AnjutaSession *session,
 				 SymbolDBPlugin *sdb_plugin)
 {
+	IAnjutaProjectManager *pm;
+	pm = anjuta_shell_get_interface (ANJUTA_PLUGIN (sdb_plugin)->shell,
+									 IAnjutaProjectManager, NULL);	
+	
 	if (phase == ANJUTA_SESSION_PHASE_START)
 	{
+		DEBUG_PRINT ("SymbolDB: session_loading started. Getting info from %s",
+					 anjuta_session_get_session_directory (session));
 		sdb_plugin->session_loading = TRUE;
-		DEBUG_PRINT ("session_loading started");
+
+		GList *session_packages = anjuta_session_get_string_list (session, 
+														SESSION_SECTION, 
+														SESSION_KEY);
+		
+		GList *to_scan_packages = NULL;
+		
+		if (session_packages == NULL)
+		{
+			GList *project_default_packages = 
+				ianjuta_project_manager_get_packages (pm, NULL);
+			
+			/* take the project's defaults */
+			to_scan_packages = project_default_packages;
+		}
+		else
+		{
+			to_scan_packages = session_packages;
+		}
+
+		/* system's packages management */				
+		GList *item = to_scan_packages; 
+		while (item != NULL)
+		{
+			/* the function will take care of checking if the package is already 
+		 	 * scanned and present on db 
+		 	 */
+			DEBUG_PRINT ("ianjuta_project_manager_get_packages: package required: %s", 
+					 (gchar*)item->data);
+			symbol_db_system_scan_package (sdb_plugin->sdbs, item->data);
+				
+			item = item->next;
+		}
+		
+		sdb_plugin->session_packages = to_scan_packages;
+		
+		/* no need to free the GList(s) */
 	}
 	else if (phase == ANJUTA_SESSION_PHASE_END)
 	{
 		IAnjutaDocumentManager* docman;
 		sdb_plugin->session_loading = FALSE;
-		DEBUG_PRINT ("session_loading finished");
+		DEBUG_PRINT ("SymbolDB: session_loading finished");
 		
 		/* Show the symbols for the current editor */
 		docman = anjuta_shell_get_interface (shell, IAnjutaDocumentManager, NULL);
@@ -655,8 +705,6 @@
 	if (filename)
 	{
 		DEBUG_PRINT ("on_project_element_removed");
-		DEBUG_PRINT ("gonna removing %s", 
-					 filename + strlen(sdb_plugin->project_root_dir));
 		DEBUG_PRINT ("project_root_dir %s", sdb_plugin->project_root_dir );
 		symbol_db_engine_remove_file (sdb_plugin->sdbe_project, 
 			sdb_plugin->project_root_dir, filename);
@@ -811,9 +859,73 @@
 	sdb_plugin->files_count_project = 0;	
 }
 
+static void
+do_import_system_src_after_abort (AnjutaPlugin *plugin, 
+								  const GPtrArray *sources_array)
+{
+	SymbolDBPlugin *sdb_plugin;
+	GPtrArray* languages_array = NULL;
+	GPtrArray *to_scan_array = NULL;
+	IAnjutaLanguage* lang_manager;
+	gint i;
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);			
+
+	lang_manager =	anjuta_shell_get_interface (plugin->shell, IAnjutaLanguage, 
+										NULL);
+
+	DEBUG_PRINT ("do_import_system_src_after_abort %d", sources_array->len);
+	/* create array of languages */
+	languages_array = g_ptr_array_new ();
+	to_scan_array = g_ptr_array_new ();
+	
+	if (!lang_manager)
+	{
+		g_critical ("LanguageManager not found");
+		return;
+	}
+
+	for (i=0; i < sources_array->len; i++) 
+	{
+		const gchar *file_mime;
+		const gchar *lang;
+		const gchar *local_filename;
+		IAnjutaLanguageId lang_id;
+		
+		local_filename = g_ptr_array_index (sources_array, i);
+		
+		if (local_filename == NULL)
+			continue;
+		file_mime = gnome_vfs_get_mime_type_for_name (local_filename);
+					
+		lang_id = ianjuta_language_get_from_mime_type (lang_manager, 
+													 file_mime, NULL);
+					
+		if (!lang_id)		
+			continue;
+						
+		lang = ianjuta_language_get_name (lang_manager, lang_id, NULL);
+
+		/* test its existence */
+		if (g_file_test (local_filename, G_FILE_TEST_EXISTS) == FALSE) 		
+			continue;		
+					
+		g_ptr_array_add (languages_array, g_strdup (lang));					
+		g_ptr_array_add (to_scan_array, g_strdup (local_filename));
+	}
+
+	symbol_db_parse_aborted_package (sdb_plugin->sdbs, 
+									 to_scan_array,
+									 languages_array);
+	
+	/* no need to free the GPtrArray, Huston. They'll be auto-destroyed in that
+	 * function 
+	 */
+}
+
 /* we assume that sources_array has already unique elements */
 static void
-do_import_sources_after_abort (AnjutaPlugin *plugin, const gchar *root_dir, 
+do_import_project_src_after_abort (AnjutaPlugin *plugin, 
 							   const GPtrArray *sources_array)
 {
 	SymbolDBPlugin *sdb_plugin;
@@ -824,19 +936,6 @@
 	
 	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (plugin);	
 		
-	/* if we're importing first shut off the signal receiving.
-	 * We'll re-enable that on scan-end 
-	 */
-	symbol_db_view_locals_recv_signals_from_engine (																
-				SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals), 
-								 sdb_plugin->sdbe_project, FALSE);
-
-	symbol_db_view_recv_signals_from_engine (																
-				SYMBOL_DB_VIEW (sdb_plugin->dbv_view_tree), 
-								 sdb_plugin->sdbe_project, FALSE);
-				
-	g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "scan-end",
-		  G_CALLBACK (on_importing_project_end), plugin);				
 
 	lang_manager =	anjuta_shell_get_interface (plugin->shell, IAnjutaLanguage, 
 										NULL);
@@ -1021,7 +1120,8 @@
 	g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), "single-file-scan-end",
 		  G_CALLBACK (on_project_single_file_scan_end), plugin);
 	
-	symbol_db_engine_add_new_files (sdb_plugin->sdbe_project, sdb_plugin->project_opened,
+	symbol_db_engine_add_new_files (sdb_plugin->sdbe_project, 
+									sdb_plugin->project_opened,
 					sources_array, languages_array, TRUE);
 				
 	g_hash_table_unref (check_unique_file);
@@ -1054,7 +1154,8 @@
 	if (root_uri)
 	{
 		gchar *root_dir = gnome_vfs_get_local_path_from_uri (root_uri);
-		DEBUG_PRINT ("Symbol-DB: added project root_dir %s, name %s", root_dir, name);
+		DEBUG_PRINT ("Symbol-DB: added project root_dir %s, name %s", root_dir, 
+					 name);
 		
 		/* FIXME: where's the project name itself? */
 		DEBUG_PRINT ("FIXME: where's the project name itself? ");
@@ -1073,7 +1174,8 @@
 			/* is it a fresh-new project? is it an imported project with 
 			 * no 'new' symbol-db database but the 'old' one symbol-browser? 
 			 */
-			if (symbol_db_engine_db_exists (sdb_plugin->sdbe_project, root_dir) == FALSE)
+			if (symbol_db_engine_db_exists (sdb_plugin->sdbe_project, 
+											root_dir) == FALSE)
 			{
 				DEBUG_PRINT ("Symbol-DB: project did not exist");
 				needs_sources_scan = TRUE;
@@ -1086,7 +1188,8 @@
 
 			/* we'll use the same values for db_directory and project_directory */
 			DEBUG_PRINT ("opening db %s and project_dir %s", root_dir, root_dir);
-			if (symbol_db_engine_open_db (sdb_plugin->sdbe_project, root_dir, root_dir) == FALSE)
+			if (symbol_db_engine_open_db (sdb_plugin->sdbe_project, root_dir, 
+										  root_dir) == FALSE)
 				g_error ("Symbol-DB: error in opening db");
 
 			/* if project did not exist add a new project */
@@ -1109,21 +1212,36 @@
 				/* we may have aborted the scan of sources ..*/
 				GPtrArray *sources_array = NULL;
 				
-				sources_array = symbol_db_engine_get_files_with_zero_symbols (sdb_plugin->sdbe_project);
+				sources_array = 
+					symbol_db_engine_get_files_with_zero_symbols (sdb_plugin->sdbe_project);
 
 				if (sources_array != NULL && sources_array->len > 0) 
-				{
-					DEBUG_PRINT ("do_import_sources_after_abort ");
-					do_import_sources_after_abort (plugin, root_dir, sources_array);
+				{					
+					/* if we're importing first shut off the signal receiving.
+	 				 * We'll re-enable that on scan-end 
+	 				 */
+					symbol_db_view_locals_recv_signals_from_engine (																
+						SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals), 
+								 sdb_plugin->sdbe_project, FALSE);
+
+					symbol_db_view_recv_signals_from_engine (																
+						SYMBOL_DB_VIEW (sdb_plugin->dbv_view_tree), 
+								 sdb_plugin->sdbe_project, FALSE);
+				
+					g_signal_connect (G_OBJECT (sdb_plugin->sdbe_project), 
+						"scan-end", G_CALLBACK (on_importing_project_end), plugin);				
+					
+					do_import_project_src_after_abort (plugin, sources_array);
 					
 					g_ptr_array_foreach (sources_array, (GFunc)g_free, NULL);
 					g_ptr_array_free (sources_array, TRUE);
 				}
 
 				/* Update the symbols */
-				symbol_db_engine_update_project_symbols (sdb_plugin->sdbe_project, root_dir);				
+				symbol_db_engine_update_project_symbols (sdb_plugin->sdbe_project, 
+														 root_dir);				
 			}
-			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project), 
+			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sdb_plugin->progress_bar_project),
 									   _("Populating symbols' db..."));
 			id = g_idle_add ((GSourceFunc) gtk_progress_bar_pulse, 
 							 sdb_plugin->progress_bar_project);
@@ -1148,21 +1266,22 @@
 	g_signal_connect (G_OBJECT (pm), "element_removed",
 					  G_CALLBACK (on_project_element_removed), sdb_plugin);
 	
+	
+	/* hide it. Default */
+	/* system tags thing */
 	gtk_widget_hide (sdb_plugin->progress_bar_system);
 
-	/* system's packages management */
-	GList* packages = ianjuta_project_manager_get_packages (pm, NULL);
-	GList *item = packages; 
-	while (item != NULL)
+	GPtrArray *sys_src_array = NULL;
+
+	sys_src_array = 
+		symbol_db_engine_get_files_with_zero_symbols (sdb_plugin->sdbe_globals);
+
+	if (sys_src_array != NULL && sys_src_array->len > 0) 
 	{
-		/* the function will take care of checking if the package is already 
-		 * scanned and present on db 
-		 */
-		DEBUG_PRINT ("ianjuta_project_manager_get_packages: package required: %s", 
-					 (gchar*)item->data);
-		symbol_db_system_scan_package (sdb_plugin->sdbs, item->data);
-				
-		item = item->next;
+		do_import_system_src_after_abort (plugin, sys_src_array);
+					
+		g_ptr_array_foreach (sys_src_array, (GFunc)g_free, NULL);
+		g_ptr_array_free (sys_src_array, TRUE);
 	}
 }
 
@@ -1212,6 +1331,7 @@
 {
 	SymbolDBPlugin *symbol_db;
 	gchar *anjuta_cache_path;
+	gchar *ctags_path;
 	
 	DEBUG_PRINT ("SymbolDBPlugin: Activating SymbolDBPlugin plugin ...");
 	
@@ -1223,23 +1343,36 @@
 	symbol_db = ANJUTA_PLUGIN_SYMBOL_DB (plugin);
 	symbol_db->ui = anjuta_shell_get_ui (plugin->shell, NULL);
 	symbol_db->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
-	symbol_db->prefs_list_store = NULL;
-	symbol_db->pkg_config_launcher = NULL;
 	symbol_db->project_opened = NULL;
 
-	/* create mutex. Without this libgda'll crash on multithread environment */
-/*	symbol_db->engine_mutex = g_mutex_new ();*/
+	ctags_path = anjuta_preferences_get (symbol_db->prefs, CTAGS_PREFS_KEY); 
+
+	if (ctags_path == NULL) 
+	{
+		g_warning ("ctags is not in preferences. Trying a default one %s", 
+				   CTAGS_PATH);
+		ctags_path = g_strdup (CTAGS_PATH);
+	}
+	
+	/* initialize the session packages to NULL. We'll store there the user 
+	 * preferences for the session about global-system packages 
+	 */
+	symbol_db->session_packages = NULL;
 	
 	/* create SymbolDBEngine(s) */
-	symbol_db->sdbe_project = symbol_db_engine_new (plugin);
+	symbol_db->sdbe_project = symbol_db_engine_new (ctags_path);
 	
 	/* the globals one too */
-	symbol_db->sdbe_globals = symbol_db_engine_new (plugin);
+	symbol_db->sdbe_globals = symbol_db_engine_new (ctags_path);
+	
+	g_free (ctags_path);
+	
 	/* open it */
-	anjuta_cache_path = anjuta_util_get_user_cache_file_path (".");
+	anjuta_cache_path = anjuta_util_get_user_cache_file_path (".", NULL);
 	symbol_db_engine_open_db (symbol_db->sdbe_globals, 
 							  anjuta_cache_path, 
 							  PROJECT_GLOBALS);
+
 	g_free (anjuta_cache_path);
 	
 	/* create the object that'll manage the globals population */
@@ -1254,6 +1387,9 @@
 	g_signal_connect (G_OBJECT (symbol_db->sdbs), "single-file-scan-end",
 					  G_CALLBACK (on_system_single_file_scan_end), plugin);	
 	
+	/* sets preferences to NULL, it'll be instantiated when required.\ */
+	symbol_db->sdbp = NULL;
+	
 	/* Create widgets */
 	symbol_db->dbv_main = gtk_vbox_new(FALSE, 5);
 	symbol_db->dbv_notebook = gtk_notebook_new();
@@ -1366,7 +1502,7 @@
 								 value_removed_current_editor, NULL);
 	/* Added widgets */
 	anjuta_shell_add_widget (plugin->shell, symbol_db->dbv_main,
-							 "AnjutaSymbolBrowser", _("Symbols"),
+							 "AnjutaSymbolDB", _("Symbols"),
 							 "symbol-db-plugin-icon",
 							 ANJUTA_SHELL_PLACEMENT_LEFT, NULL);	
 
@@ -1375,11 +1511,13 @@
 									IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
 									on_project_root_added,
 									on_project_root_removed, NULL);
-
 	
 	/* Determine session state */
-	g_signal_connect (plugin->shell, "load_session", 
+	g_signal_connect (plugin->shell, "load-session", 
 					  G_CALLBACK (on_session_load), plugin);
+	
+	g_signal_connect (plugin->shell, "save-session", 
+					  G_CALLBACK (on_session_save), plugin);
 		
 	return TRUE;
 }
@@ -1407,6 +1545,13 @@
 	g_free (sdb_plugin->project_opened);
 	sdb_plugin->project_opened = NULL;
 
+	if (sdb_plugin->session_packages)
+	{
+		g_list_foreach (sdb_plugin->session_packages, (GFunc)g_free, NULL);
+		g_list_free (sdb_plugin->session_packages);
+		sdb_plugin->session_packages = NULL;
+	}
+	
 	/* disconnect some signals */
 	g_signal_handlers_disconnect_by_func (G_OBJECT (sdb_plugin->dbv_view_tree_locals),
 									  on_local_treeview_row_activated,
@@ -1425,18 +1570,6 @@
 		sdb_plugin->editor_connected = NULL;
 	}
 	
-	if (sdb_plugin->pkg_config_launcher) 
-	{
-		g_object_unref (sdb_plugin->pkg_config_launcher);
-		sdb_plugin->pkg_config_launcher = NULL;
-	}	
-	
-	if (sdb_plugin->prefs_list_store)
-	{
-		g_object_unref (sdb_plugin->prefs_list_store);
-		sdb_plugin->prefs_list_store = NULL;
-	}
-	
 	/* Remove watches */
 	anjuta_plugin_remove_watch (plugin, sdb_plugin->root_watch_id, FALSE);
 	anjuta_plugin_remove_watch (plugin, sdb_plugin->editor_watch_id, TRUE);
@@ -1446,9 +1579,6 @@
 	g_object_unref (sdb_plugin->progress_bar_system);
 	anjuta_shell_remove_widget (plugin->shell, sdb_plugin->dbv_main, NULL);
 
-	/* delete mutexes */
-/*	g_mutex_free (sdb_plugin->engine_mutex);*/
-	
 	sdb_plugin->root_watch_id = 0;
 	sdb_plugin->editor_watch_id = 0;
 	sdb_plugin->dbv_notebook = NULL;
@@ -1540,16 +1670,6 @@
 		filter_array = symbol_db_engine_fill_type_array (match_types);
 	}
 
-	/* DEBUG REMOVE ME *
-	gint i;
-	if (filter_array != NULL)
-		for (i=0; i < filter_array->len; i++) 
-		{
-			DEBUG_PRINT ("isymbol_manager_search (): search for type %s", 
-						 g_ptr_array_index (filter_array, i));
-		}
-	//*/
-	
 	if (exact_match == FALSE)
 		pattern = g_strdup_printf ("%s%%", match_name);
 	else
@@ -1640,18 +1760,90 @@
 	iface->get_class_parents = isymbol_manager_get_class_parents;
 }
 
+static gint 
+g_list_compare (gconstpointer a, gconstpointer b)
+{
+	return strcmp ((const gchar*)a, (const gchar*)b);
+}
+
+static void
+on_prefs_package_add (SymbolDBPrefs *sdbp, const gchar *package, 
+							  gpointer user_data)
+{
+	SymbolDBPlugin *sdb_plugin;
+	
+	g_return_if_fail (package != NULL);
+	
+	DEBUG_PRINT ("on_prefs_package_add");
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
+	
+	sdb_plugin->session_packages = g_list_prepend (sdb_plugin->session_packages,
+												   g_strdup (package));	
+}
+
+static void
+on_prefs_package_remove (SymbolDBPrefs *sdbp, const gchar *package, 
+							  gpointer user_data)
+{
+	SymbolDBPlugin *sdb_plugin;
+	
+	g_return_if_fail (package != NULL);
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
+	
+	GList *item;
+	DEBUG_PRINT ("on_prefs_package_remove");	
+	if ((item = g_list_find_custom (sdb_plugin->session_packages, package, 
+							g_list_compare)) != NULL)
+	{
+		sdb_plugin->session_packages = g_list_remove_link (sdb_plugin->session_packages,
+														   item);
+		
+		/* ok, now think to the item left alone by its friends... */
+		g_list_foreach (item, (GFunc)g_free, NULL);
+		g_list_free (item);
+	}
+}
 
 static void
 ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
 {
 	DEBUG_PRINT ("SymbolDB: ipreferences_merge");	
-	symbol_db_prefs_init (ANJUTA_PLUGIN_SYMBOL_DB (ipref), prefs);
+	SymbolDBPlugin *sdb_plugin;
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (ipref);
+	
+	if (sdb_plugin->sdbp == NULL)
+	{
+		sdb_plugin->sdbp = symbol_db_prefs_new (sdb_plugin->sdbs, 
+												sdb_plugin->sdbe_project,
+												sdb_plugin->sdbe_globals,
+												prefs,
+												sdb_plugin->session_packages);
+		
+		/* connect the signals to retrieve package modifications */
+		g_signal_connect (G_OBJECT (sdb_plugin->sdbp), "package-add",
+						  G_CALLBACK (on_prefs_package_add),
+						  sdb_plugin);
+		g_signal_connect (G_OBJECT (sdb_plugin->sdbp), "package-remove",
+						  G_CALLBACK (on_prefs_package_remove),
+						  sdb_plugin);		
+	}
 }
 
 static void
 ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e)
 {
-	symbol_db_prefs_finalize (ANJUTA_PLUGIN_SYMBOL_DB (ipref), prefs);
+	SymbolDBPlugin *sdb_plugin;
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (ipref);
+	
+	if (sdb_plugin->sdbp != NULL)
+	{
+		g_object_unref (sdb_plugin->sdbp);
+		sdb_plugin->sdbp = NULL;
+	}
 }
 
 static void

Modified: trunk/plugins/symbol-db/plugin.h
==============================================================================
--- trunk/plugins/symbol-db/plugin.h	(original)
+++ trunk/plugins/symbol-db/plugin.h	Wed Jul 16 16:11:05 2008
@@ -47,15 +47,15 @@
 
 
 #include "symbol-db-system.h"
+#include "symbol-db-prefs.h"
+
+/* a sort of 'default' value for ctags executable. User must have it installed */
+#define CTAGS_PATH			"/usr/bin/ctags"
 
 struct _SymbolDBPlugin{
 	AnjutaPlugin parent;
 	AnjutaUI *ui;
 	AnjutaPreferences *prefs;
-	GtkListStore *prefs_list_store;
-	AnjutaLauncher *pkg_config_launcher;
-	
-	gint prefs_notify_id;
 	
 	/* project monitor */
 	guint root_watch_id;
@@ -71,27 +71,32 @@
 	
 	/* global's one */
 	SymbolDBEngine *sdbe_globals;
+	
+	/* system's population object */
 	SymbolDBSystem *sdbs;
 	
-	GtkWidget *dbv_main;				/* symbol main window [gtk_box] */
-	GtkWidget *dbv_notebook;          	/* main notebook */	
-	GtkWidget *scrolled_global; 		/* symbol view scrolledwindow for global
-										   symbols */
+	/* preferences object */
+	SymbolDBPrefs *sdbp;
+	
+	GtkWidget *dbv_main;					/* symbol main window [gtk_box] */
+	GtkWidget *dbv_notebook;          		/* main notebook */	
+	GtkWidget *scrolled_global; 			/* symbol view scrolledwindow for global
+										   	symbols */
 	GtkWidget *scrolled_locals;
 	GtkWidget *scrolled_search;
-	GtkWidget *progress_bar_project;			/* symbol db progress bar - project */
-	GtkWidget *progress_bar_system;				/* symbol db progress bar - system (globals) */
+	GtkWidget *progress_bar_project;		/* symbol db progress bar - project */
+	GtkWidget *progress_bar_system;			/* symbol db progress bar - system (globals) */
 	
-	GtkWidget *dbv_view_tree;        	/* symbol_db_view */
+	GtkWidget *dbv_view_tree;        		/* symbol_db_view */
 	GtkWidget *dbv_view_tab_label;
 	
-	GtkWidget *dbv_view_tree_locals;	/* local symbols */
+	GtkWidget *dbv_view_tree_locals;		/* local symbols */
 	GtkWidget *dbv_view_locals_tab_label;
 	
-	GtkWidget *dbv_view_tree_search;	/* search symbols */
+	GtkWidget *dbv_view_tree_search;		/* search symbols */
 	GtkWidget *dbv_view_search_tab_label;	
 	
-	GtkWidget *pref_tree_view; 			/* Preferences treeview */
+	GtkWidget *pref_tree_view; 				/* Preferences treeview */
 	
 	/* current editor */
 	GObject *current_editor;
@@ -106,8 +111,7 @@
 	gint files_count_system;
 	gint files_count_system_done;
 	gchar *current_scanned_package;
-	
-/*	GMutex* engine_mutex;*/
+	GList *session_packages;
 };
 
 struct _SymbolDBPluginClass{

Modified: trunk/plugins/symbol-db/symbol-db-engine.c
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-engine.c	(original)
+++ trunk/plugins/symbol-db/symbol-db-engine.c	Wed Jul 16 16:11:05 2008
@@ -136,8 +136,6 @@
 #define	TRIGGER_MAX_CLOSURE_RETRIES		50
 #define	THREAD_MAX_CLOSURE_RETRIES		20
 
-#define CTAGS_PREFS_KEY		"symboldb.ctags"
-
 enum {
 	DO_UPDATE_SYMS = 1,
 	DO_UPDATE_SYMS_AND_EXIT,
@@ -246,12 +244,12 @@
 	
 } DynChildQueryNode;
 
-#define DYN_QUERY_POPULATE_INIT_NODE(query_list_ptr, query_type, gtree_child) { \
-	dyn_query_node *q = g_new0 (dyn_query_node, 1); \
-	q->dyn_query_id = query_type; \
-	q->sym_extra_info_gtree = NULL; \
-	q->has_gtree_child = gtree_child; \
-	query_list_ptr [query_type] = q; \
+#define DYN_QUERY_POPULATE_INIT_NODE(dquery_list_ptr, dquery_type, gtree_child) { \
+	dyn_query_node *dq = g_new0 (dyn_query_node, 1); \
+	dq->dyn_query_id = dquery_type; \
+	dq->sym_extra_info_gtree = NULL; \
+	dq->has_gtree_child = gtree_child; \
+	dquery_list_ptr [dquery_type] = dq; \
 }
 
 
@@ -273,7 +271,7 @@
 
 struct _SymbolDBEnginePriv
 {
-	AnjutaPlugin* plugin;
+	gchar *ctags_path;
 	
 	GdaConnection *db_connection;
 	GdaSqlParser *sql_parser;
@@ -550,7 +548,7 @@
 
 	node = priv->dyn_query_list[query_id];
 
-	if (node->sym_extra_info_gtree == NULL) 
+	if (node == NULL || node->sym_extra_info_gtree == NULL) 
 	{
 		/* we didn't find any extra info symbol, nor it has been added before */
 		return NULL;
@@ -612,6 +610,8 @@
 
 	node = priv->dyn_query_list[query_id];
 	
+	g_return_val_if_fail (node != NULL, NULL);
+	
 	if (node->sym_extra_info_gtree == NULL) 
 	{
 		/* lazy initialization */
@@ -1473,6 +1473,35 @@
 	DEBUG_PRINT ("ctags ended");
 }
 
+
+static inline void
+sdb_engine_ctags_launcher_create (SymbolDBEngine * dbe)
+{
+	SymbolDBEnginePriv *priv;
+	gchar *exe_string;
+		
+	priv = dbe->priv;
+	
+	DEBUG_PRINT ("creating anjuta_launcher");
+
+	priv->ctags_launcher = anjuta_launcher_new ();
+
+	anjuta_launcher_set_check_passwd_prompt (priv->ctags_launcher, FALSE);
+	anjuta_launcher_set_encoding (priv->ctags_launcher, NULL);
+		
+	g_signal_connect (G_OBJECT (priv->ctags_launcher), "child-exited",
+						  G_CALLBACK (on_scan_files_end_1), NULL);
+
+	exe_string = g_strdup_printf ("%s --fields=afmiKlnsStz --c++-kinds=+p "
+								  "--filter=yes --filter-terminator='"CTAGS_MARKER"'",
+								  priv->ctags_path);
+		
+	anjuta_launcher_execute (priv->ctags_launcher,
+								 exe_string, sdb_engine_ctags_output_callback_1, 
+								 dbe);
+	g_free (exe_string);
+}
+
 /* Scans with ctags and produce an output 'tags' file [shared memory file]
  * containing language symbols. This function will call ctags 
  * executale and then sdb_engine_populate_db_by_tags () when it'll detect some
@@ -1495,66 +1524,27 @@
 {
 	SymbolDBEnginePriv *priv;
 	gint i;
-	gchar* ctags_path;
-	AnjutaPreferences* prefs;
-	
+
 	g_return_val_if_fail (dbe != NULL, FALSE);
 	g_return_val_if_fail (files_list != NULL, FALSE);
 	
 	if (files_list->len == 0)
-		return FALSE;
-	
-	/* Check if ctags is really installed */
-	prefs = anjuta_shell_get_preferences (dbe->priv->plugin->shell,
-										  NULL);
-	ctags_path = anjuta_preferences_get (prefs, CTAGS_PREFS_KEY); 
-	if (!anjuta_util_prog_is_installed (ctags_path, TRUE))
-	{
-		g_free (ctags_path);
-		return FALSE;
-	}
+		return FALSE;	
 	
 	/* start process in server mode */
 	priv = dbe->priv;
 
 	if (real_files_list != NULL && (files_list->len != real_files_list->len)) 
 	{
-		g_warning ("no matched size between real_files_list and files_list");
-		g_free (ctags_path);
+		g_warning ("no matched size between real_files_list and files_list");		
 		return FALSE;
 	}
 	
 	/* if ctags_launcher isn't initialized, then do it now. */
+	/* lazy initialization */
 	if (priv->ctags_launcher == NULL) 
 	{
-		gchar *exe_string;
-		
-		DEBUG_PRINT ("creating anjuta_launcher");
-		priv->ctags_launcher = anjuta_launcher_new ();
-
-		anjuta_launcher_set_check_passwd_prompt (priv->ctags_launcher, FALSE);
-		anjuta_launcher_set_encoding (priv->ctags_launcher, NULL);
-		
-		g_signal_connect (G_OBJECT (priv->ctags_launcher), "child-exited",
-						  G_CALLBACK (on_scan_files_end_1), NULL);
-
-		exe_string = g_strdup_printf ("%s --fields=afmiKlnsStz --c++-kinds=+p "
-								  "--filter=yes --filter-terminator='"CTAGS_MARKER"'",
-								  ctags_path);
-		
-		anjuta_launcher_execute (priv->ctags_launcher,
-								 exe_string, sdb_engine_ctags_output_callback_1, 
-								 dbe);
-		g_free (exe_string);
-	}
-	g_free (ctags_path);
-	
-	/* what about the scan_queue? is it initialized? It will contain mainly 
-	 * ints that refers to the force_update status.
-	 */
-	if (priv->scan_queue == NULL)
-	{
-		priv->scan_queue = g_async_queue_new ();		
+		sdb_engine_ctags_launcher_create (dbe);
 	}
 	
 	/* create the shared memory file */
@@ -1742,9 +1732,17 @@
 	sdbe->priv->garbage_shared_mem_files = g_hash_table_new_full (g_str_hash, g_str_equal, 
 													  g_free, NULL);	
 	
-	/* create Anjuta Launcher instance. It will be used for tags parsing. */
 	sdbe->priv->ctags_launcher = NULL;
 
+	/* set the ctags executable path to NULL */
+	sdbe->priv->ctags_path = NULL;
+
+	/* the scan_queue? It will contain mainly 
+	 * ints that refer to the force_update status.
+	 */
+	sdbe->priv->scan_queue = g_async_queue_new ();		
+
+	
 	/*
 	 * STATIC QUERY STRUCTURE INITIALIZE
 	 */
@@ -1977,7 +1975,7 @@
 	STATIC_QUERY_POPULATE_INIT_NODE(sdbe->priv->static_query_list, 
 	 								PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME,
 	 	"SELECT symbol_id FROM symbol JOIN sym_type ON symbol.type_id = "
-	 	"sym_type.type_id AND symbol.scope_id = 0 WHERE AND sym_type.type_type='class' AND "
+	 	"sym_type.type_id AND symbol.scope_id = 0 WHERE sym_type.type_type='class' AND "
 	 	"name = ## /* name:'klassname' type:gchararray */ LIMIT 1");
 	
 	STATIC_QUERY_POPULATE_INIT_NODE(sdbe->priv->static_query_list, 
@@ -2076,6 +2074,11 @@
 	DYN_QUERY_POPULATE_INIT_NODE(sdbe->priv->dyn_query_list,
 								 	DYN_PREP_QUERY_GET_SCOPE_MEMBERS_BY_SYMBOL_ID,
 									TRUE);
+
+	DYN_QUERY_POPULATE_INIT_NODE(sdbe->priv->dyn_query_list,
+								 	DYN_PREP_QUERY_GET_SCOPE_MEMBERS_BY_SYMBOL_ID_FILTERED,
+									TRUE);
+	
 	
 	/* init cache hashtables */
 	sdb_engine_init_caches (sdbe);
@@ -2147,9 +2150,10 @@
 	}
 	
 	if (priv->ctags_launcher)
-	{
+	{		
 		anjuta_launcher_signal (priv->ctags_launcher, SIGINT);
 		g_object_unref (priv->ctags_launcher);
+		priv->ctags_launcher = NULL;
 	}	
 	
 	if (priv->mutex)
@@ -2267,17 +2271,59 @@
 	return our_type;
 }
 
+void 
+symbol_db_engine_set_ctags_path (SymbolDBEngine * dbe, const gchar * ctags_path)
+{
+	SymbolDBEnginePriv *priv;
+
+	g_return_if_fail (dbe != NULL);
+	g_return_if_fail (ctags_path != NULL);
+	
+	priv = dbe->priv;
+	
+	/* Check if ctags is really installed */
+	if (!anjuta_util_prog_is_installed (ctags_path, TRUE))
+	{
+		g_warning ("symbol_db_engine_set_ctags_path (): Wrong path for ctags. Keeping "
+				   "the old value %s", priv->ctags_path);
+		return;
+	}	
+
+	/* free the old value */
+	g_free (priv->ctags_path);
+	
+	/* is anjutalauncher already created? */
+	if (priv->ctags_launcher != NULL)
+	{
+		anjuta_launcher_reset (priv->ctags_launcher);
+		anjuta_launcher_signal (priv->ctags_launcher, SIGINT);
+		g_object_unref (priv->ctags_launcher);
+		priv->ctags_launcher = NULL;
+
+		/* recreate it on the fly */
+		sdb_engine_ctags_launcher_create (dbe);
+	}	
+	
+	/* set the new one */
+	priv->ctags_path = g_strdup (ctags_path);	
+}
+
 SymbolDBEngine *
-symbol_db_engine_new (AnjutaPlugin* plugin)
+symbol_db_engine_new (const gchar * ctags_path)
 {
 	SymbolDBEngine *sdbe;
 	SymbolDBEnginePriv *priv;
+	
+	g_return_val_if_fail (ctags_path != NULL, NULL);
 
 	sdbe = g_object_new (SYMBOL_TYPE_DB_ENGINE, NULL);
 	
 	priv = sdbe->priv;
 	priv->mutex = g_mutex_new ();
-	priv->plugin = plugin;
+	
+	/* set the mandatory ctags_path */
+	symbol_db_engine_set_ctags_path (sdbe, ctags_path);
+		
 	return sdbe;
 }
 
@@ -2330,7 +2376,7 @@
 	if (!GDA_IS_CONNECTION (priv->db_connection))
 	{
 		g_warning ("Could not open connection to %s\n", cnc_string);
-		return FALSE;
+		return FALSE;		
 	}
 
 	priv->sql_parser = gda_connection_create_parser (priv->db_connection);
@@ -2598,8 +2644,8 @@
 				"prjname",
 				 value)) <= 0)
 	{
-		DEBUG_PRINT ("symbol_db_engine_project_exists (): no project named %s found",
-					 project_name);
+/*		DEBUG_PRINT ("symbol_db_engine_project_exists (): no project named %s found",
+					 project_name);*/
 		gda_value_free (value);
 		return FALSE;
 	}
@@ -2943,7 +2989,6 @@
 	priv = dbe->priv;
 
 	g_return_val_if_fail (priv->db_connection != NULL, FALSE);
-	g_return_val_if_fail (project_name != NULL, FALSE);
 	g_return_val_if_fail (files_path->len > 0, FALSE);
 	g_return_val_if_fail (languages->len > 0, FALSE);
 
@@ -2971,7 +3016,8 @@
 				continue;
 		}
 		
-		if (sdb_engine_add_new_file (dbe, project_name, node_file, 
+		if (project_name != NULL && 
+			sdb_engine_add_new_file (dbe, project_name, node_file, 
 									 node_lang) == FALSE)
 		{
 			g_warning ("Error processing file %s, db_directory %s, project_name %s, "
@@ -5618,7 +5664,7 @@
 														  NULL, NULL);
 	
 	if (!GDA_IS_DATA_MODEL (data_model) ||
-		gda_data_model_get_n_rows (GDA_DATA_MODEL (data_model)) <= 0)
+		(num_rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (data_model))) <= 0)
 	{
 		if (data_model != NULL)
 			g_object_unref (data_model);
@@ -5646,11 +5692,7 @@
 
 		/* build abs path. */
 		file_name = g_value_get_string (value);
-		if (priv->db_directory != NULL)
-		{
-			file_abs_path = g_strdup_printf ("%s%s", priv->project_directory,
-										file_name);
-		}
+		file_abs_path = symbol_db_engine_get_full_local_path (dbe, file_name);
 		g_ptr_array_add (files_to_scan, file_abs_path);
 	}
 
@@ -5743,15 +5785,6 @@
 				"LEFT JOIN file_include ON "
 				"ext_include.file_incl_id = file_include.file_include_id ");
 	}
-	
-/* TODO, or better.. TAKE A DECISION
-	if (sym_info & SYMINFO_WORKSPACE_NAME)
-	{
-		info_data = g_string_append (info_data, ",sym_access.access_name ");
-		join_data = g_string_append (info_data, "LEFT JOIN sym_kind ON "
-				"symbol.kind_id = sym_kind.sym_kind_id ");
-	}
-*/
 }
 
 
@@ -7554,7 +7587,7 @@
  * @param pattern Pattern you want to search for. If NULL it will use '%' and LIKE for query.
  *        Please provide a pattern with '%' if you also specify a exact_match = FALSE
  * @param exact_match Should the pattern be searched for an exact match?
- * @param filter_kinds Can be NULL. In that case these filters will be taken into consideration.
+ * @param filter_kinds Can be NULL. In that case these filters will not be taken into consideration.
  * @param include_kinds Should the filter_kinds (if not null) be applied as inluded or excluded?
  * @param global_symbols_search If TRUE only global public function will be searched. If false
  *		  even private or static (for C language) will be searched.

Modified: trunk/plugins/symbol-db/symbol-db-engine.h
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-engine.h	(original)
+++ trunk/plugins/symbol-db/symbol-db-engine.h	Wed Jul 16 16:11:05 2008
@@ -83,8 +83,19 @@
 GType sdb_engine_get_type (void) G_GNUC_CONST;
 
 
-SymbolDBEngine* symbol_db_engine_new (AnjutaPlugin* plugin);
+/**
+ * Create a new instance of an engine. 
+ * @param ctags_path is mandatory. No NULL value is accepted.
+ */
+SymbolDBEngine* 
+symbol_db_engine_new (const gchar * ctags_path);
 
+/**
+ * Set a new path for ctags executable.
+ */ 
+void 
+symbol_db_engine_set_ctags_path (SymbolDBEngine *dbe,
+								  const gchar * ctags_path);
 
 /**
  * Be sure to check lock status with this function before calling
@@ -154,7 +165,8 @@
  * symbol_db_engine_open_db ().
  * @note if some file fails to enter the db the function will return without
  * processing the remaining files.
- * @param project_name something like 'foo_project', or 'helloworld_project'
+ * @param project_name something like 'foo_project', or 'helloworld_project'. Can be NULL,
+ *        for example when you're populating after abort.
  * @param project_directory something like the base path '/home/user/projects/foo_project/'
  *        Be sure not to exchange the db_directory with project_directory! they're different!
  * @param files_path requires full path to files on disk. Ctags itself requires that.
@@ -268,7 +280,7 @@
  * @param pattern Pattern you want to search for. If NULL it will use '%' and LIKE for query.
  *        Please provide a pattern with '%' if you also specify a exact_match = FALSE
  * @param exact_match Should the pattern be searched for an exact match?
- * @param filter_kinds Can be NULL. In that case these filters will be taken into consideration.
+ * @param filter_kinds Can be NULL. In that case these filters will not be taken into consideration.
  * @param include_kinds Should the filter_kinds (if not null) be applied as inluded or excluded?
  * @param global_symbols_search If TRUE only global public function will be searched. If false
  *		  even private or static (for C language) will be searched.

Modified: trunk/plugins/symbol-db/symbol-db-prefs.c
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-prefs.c	(original)
+++ trunk/plugins/symbol-db/symbol-db-prefs.c	Wed Jul 16 16:11:05 2008
@@ -1,27 +1,23 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * symbol-db-prefs.c
- * Copyright (C) Massimo Cora' 2007-2008 <maxcvs email it>
+ * anjuta_trunk
+ * Copyright (C) Massimo Cora' 2008 <maxcvs email it>
  * 
- * plugin.c is free software.
+ * anjuta_trunk is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  * 
- * You may redistribute it and/or modify it under the terms of the
- * GNU General Public License, as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * plugin.c is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * anjuta_trunk is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License
- * along with plugin.c.  If not, write to:
- * 	The Free Software Foundation, Inc.,
- * 	51 Franklin Street, Fifth Floor
- * 	Boston, MA  02110-1301, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+
 #include <glib.h>
 #include <config.h>
 #include <ctype.h>
@@ -42,15 +38,7 @@
 #define ICON_FILE "anjuta-symbol-db-plugin-48.png"
 
 #define CTAGS_PREFS_KEY		"ctags.executable"
-#define CTAGS_PATH			"/usr/bin/ctags"
-#define CHOOSER_WIDGET		"preferences_folder:text:/:0:symboldb.root"
-
-static AnjutaLauncher* cflags_launcher = NULL;
-static GList *pkg_list = NULL;
-static gboolean initialized = FALSE;
-
-/* FIXME move away */
-static GladeXML *gxml;
+#define CHOOSER_WIDGET		"preferences_file:text:/usr/bin/ctags:0:symboldb.ctags"
 
 enum
 {
@@ -59,8 +47,34 @@
 	COLUMN_MAX
 };
 
+enum
+{
+	PACKAGE_ADD,
+	PACKAGE_REMOVE,
+	LAST_SIGNAL
+};
+
+static unsigned int signals[LAST_SIGNAL] = { 0 };
+
+struct _SymbolDBPrefsPriv {
+	GtkListStore *prefs_list_store;
+	GladeXML *prefs_gxml;
+	AnjutaLauncher *pkg_config_launcher;	
+	AnjutaPreferences *prefs;
+	
+	SymbolDBSystem *sdbs;
+	SymbolDBEngine *sdbe_project;
+	SymbolDBEngine *sdbe_globals;
+	
+	GList *pkg_list;
+	GHashTable *enabled_packages_hash;
+
+	gint prefs_notify_id;
+};
+
+
 typedef struct _ParseableData {
-	SymbolDBPlugin *sdb_plugin;
+	SymbolDBPrefs *sdbp;
 	gchar *path_str;
 	
 } ParseableData;
@@ -73,18 +87,37 @@
 	g_free (pdata);
 }
 
+
+G_DEFINE_TYPE (SymbolDBPrefs, sdb_prefs, G_TYPE_OBJECT);
+
 static void 
 on_prefs_executable_changed (GtkFileChooser *chooser,
                              gpointer user_data)
 {
 	gchar *new_file;
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
+	
+	sdbp = SYMBOL_DB_PREFS (user_data);
+	priv = sdbp->priv;
 	
 	new_file = gtk_file_chooser_get_filename (chooser);
-	DEBUG_PRINT ("on_prefs_executable_changed ()");
-	DEBUG_PRINT ("new file selected %s", new_file);
-	anjuta_preferences_set (ANJUTA_PREFERENCES (user_data), CTAGS_PREFS_KEY,
+	DEBUG_PRINT ("on_prefs_executable_changed (): new executable selected %s", 
+				 new_file);
+	if (new_file != NULL) 
+	{
+		GtkWidget *fchooser;
+		fchooser = 	glade_xml_get_widget (priv->prefs_gxml, CHOOSER_WIDGET);	
+		gtk_widget_set_sensitive (fchooser, TRUE);
+		
+		anjuta_preferences_set (priv->prefs, CTAGS_PREFS_KEY,
 							new_file);
 	
+		/* remember to set the new ctags path into various symbol engines */
+		symbol_db_engine_set_ctags_path (priv->sdbe_project, new_file);
+		symbol_db_engine_set_ctags_path (priv->sdbe_globals, new_file);
+	}
+	
 	g_free (new_file);
 }
 
@@ -101,7 +134,6 @@
 	return strcmp ((const gchar*)a, (const gchar*)b);
 }
 
-
 static void
 on_listall_output (AnjutaLauncher * launcher,
 					AnjutaLauncherOutputType output_type,
@@ -110,7 +142,8 @@
 	gchar **lines;
 	const gchar *curr_line;
 	gint i = 0;
-	SymbolDBPlugin *sdb_plugin;
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
 	GtkListStore *store;
 
 	if (output_type == ANJUTA_LAUNCHER_OUTPUT_STDERR)
@@ -119,10 +152,10 @@
 		return;
 	}
 	
-	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
-	
-	store = sdb_plugin->prefs_list_store;
+	sdbp = SYMBOL_DB_PREFS (user_data);
+	priv = sdbp->priv;
 	
+	store = priv->prefs_list_store;	
 	lines = g_strsplit (chars, "\n", -1);
 	
 	while ((curr_line = lines[i++]) != NULL)
@@ -139,7 +172,7 @@
 			g_strfreev (pkgs);
 			continue;
 		}
-		pkg_list = g_list_prepend (pkg_list, g_strdup (pkgs[0]));
+		priv->pkg_list = g_list_prepend (priv->pkg_list, g_strdup (pkgs[0]));
 		g_strfreev (pkgs);
 	}
 
@@ -151,12 +184,23 @@
 				   int exit_status, gulong time_taken_in_seconds,
 				   gpointer user_data)
 {	
-	SymbolDBPlugin *sdb_plugin;
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;	
 	GtkListStore *store;
 	GList *item;
+	GtkWidget *treeview;
 	
-	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (user_data);
-	store = sdb_plugin->prefs_list_store;
+	sdbp = SYMBOL_DB_PREFS (user_data);
+	priv = sdbp->priv;
+	store = priv->prefs_list_store;
+	
+	DEBUG_PRINT ("on_listall_exit ()");
+
+	g_signal_handlers_disconnect_by_func (launcher, on_listall_exit,
+										  user_data);	
+
+	treeview = glade_xml_get_widget (priv->prefs_gxml, "tags_treeview");
+	gtk_widget_set_sensitive (treeview, TRUE);
 	
 	/* we should have pkg_list filled with packages names 
 	 * It's not enough anyway: we have to sort alphabetically the list.
@@ -166,23 +210,29 @@
 	 * Let then the user click on the toggle checkbox. We'll notify her whether
 	 * there are no good cflags for that package.
 	 */		
-	if (pkg_list == NULL)
+	if (priv->pkg_list == NULL)
 	{
 		g_warning ("No packages found");
 		return;
 	}
 
-	pkg_list = g_list_sort (pkg_list, pkg_list_compare);
-
-	
-	item = pkg_list;
+	priv->pkg_list = g_list_sort (priv->pkg_list, pkg_list_compare);
+	item = priv->pkg_list;
 	
 	while (item != NULL)
 	{
 		GtkTreeIter iter;
+		gboolean enabled = FALSE;
 		/* that's good. We can add the package to the GtkListStore */
 		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
-		gtk_list_store_set (store, &iter, COLUMN_LOAD, FALSE,
+		
+		/* check if we should enable or not the checkbox */
+		if (g_hash_table_lookup (priv->enabled_packages_hash, item->data) == NULL) 		
+			enabled = FALSE;
+		else
+			enabled = TRUE;		
+		
+		gtk_list_store_set (store, &iter, COLUMN_LOAD, enabled,
 									COLUMN_NAME, g_strdup (item->data), -1);
 		
 		item = item->next;
@@ -197,17 +247,32 @@
 	GtkWidget *treeview, *prefs_progressbar;
 	GtkWindow *prefs_window;
 	ParseableData *pdata;
-	SymbolDBPlugin *sdb_plugin;
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
 	const gchar *path_str;
+	GtkTreeIter iter;
+	GtkTreePath *path;		
+	GtkListStore *store;
+	gboolean enabled;
+	gchar *curr_package_name;
 	
 	pdata = (ParseableData *)user_data;
 	path_str = pdata->path_str;
-	sdb_plugin = pdata->sdb_plugin;
+	sdbp = pdata->sdbp;
+	priv = sdbp->priv;
 	
 	DEBUG_PRINT ("on_tag_load_toggled_parseable_cb %d", is_parseable);
-	prefs_window = GTK_WINDOW (glade_xml_get_widget (gxml, "symbol_db_pref_window"));
-	treeview = glade_xml_get_widget (gxml, "tags_treeview");
-	prefs_progressbar = glade_xml_get_widget (gxml, "prefs_progressbar");
+	prefs_window = GTK_WINDOW (glade_xml_get_widget (priv->prefs_gxml, "symbol_db_pref_window"));
+	treeview = glade_xml_get_widget (priv->prefs_gxml, "tags_treeview");
+	prefs_progressbar = glade_xml_get_widget (priv->prefs_gxml, "prefs_progressbar");
+
+	store = priv->prefs_list_store;
+	path = gtk_tree_path_new_from_string (path_str);
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+						COLUMN_LOAD, &enabled,
+						COLUMN_NAME, &curr_package_name,
+						-1);
 	
 	if (is_parseable == FALSE)
 	{
@@ -216,45 +281,44 @@
 								GTK_BUTTONS_OK, _("Package is not parseable"));
 		gtk_dialog_run (GTK_DIALOG (wid));
  		gtk_widget_destroy (wid);
+		
+		/* we for sure don't want this package on list next time */
+		gtk_list_store_set (store, &iter, COLUMN_LOAD, FALSE, -1);
+		
+		/* emit the package-remove signal */
+		g_signal_emit (sdbp, signals[PACKAGE_REMOVE], 0, curr_package_name); 		
 	}
 	else
 	{
-		GtkTreeIter iter;
-		GtkTreePath *path;		
-		GtkListStore *store;
-		gboolean enabled;
-		gchar *curr_package_name;
-
-		/* we have a good parseable package. Let's mark the check enabled/disabled */		
-		
-		store = sdb_plugin->prefs_list_store;
-		path = gtk_tree_path_new_from_string (path_str);
-		gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
-		gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-						COLUMN_LOAD, &enabled,
-						COLUMN_NAME, &curr_package_name,
-						-1);
+		/* we have a good parseable package. Let's mark the check enabled/disabled */
 		enabled = !enabled;
 		gtk_list_store_set (store, &iter, COLUMN_LOAD, enabled, -1);
-		gtk_tree_path_free (path);
 		
 		/* good, should we scan the packages? */
 		if (enabled == TRUE)
+		{			
+			symbol_db_system_scan_package (priv->sdbs, curr_package_name);
+			
+			/* emit the package-add signal */
+			g_signal_emit (sdbp, signals[PACKAGE_ADD], 0, curr_package_name);
+		}
+		else 
 		{
-			symbol_db_system_scan_package (sdb_plugin->sdbs, curr_package_name);
+			/* emit the package-remove signal */
+			g_signal_emit (sdbp, signals[PACKAGE_REMOVE], 0, curr_package_name); 
 		}
 	}
 	
 	gtk_widget_set_sensitive (treeview, TRUE);
 	gtk_widget_hide (prefs_progressbar);	
+	gtk_tree_path_free (path);
 	
 	destroy_parseable_data (pdata);
 }
-
 				  
 static void
 on_tag_load_toggled (GtkCellRendererToggle *cell, char *path_str,
-					 SymbolDBPlugin *sdb_plugin)
+					 SymbolDBPrefs *sdbp)
 {
 	GtkTreeIter iter;
 	GtkTreePath *path;
@@ -263,10 +327,13 @@
 	GtkWidget *prefs_progressbar;
 	GtkWidget *	treeview;
 	ParseableData *pdata;
+	SymbolDBPrefsPriv *priv;	
+	
+	priv = sdbp->priv;
 	
 	DEBUG_PRINT ("on_tag_load_toggled ()");
 	
-	store = sdb_plugin->prefs_list_store;
+	store = priv->prefs_list_store;
 	path = gtk_tree_path_new_from_string (path_str);
 	gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
 	gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
@@ -274,85 +341,109 @@
 						-1);
 	gtk_tree_path_free (path);
 	
-	prefs_progressbar = glade_xml_get_widget (gxml, "prefs_progressbar");
+	prefs_progressbar = glade_xml_get_widget (priv->prefs_gxml, "prefs_progressbar");
 	gtk_widget_show_all (prefs_progressbar);	
 	
 	gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (prefs_progressbar), 1.0);
 	gtk_progress_bar_pulse (GTK_PROGRESS_BAR (prefs_progressbar));
 	
-	treeview = glade_xml_get_widget (gxml, "tags_treeview");
+	treeview = glade_xml_get_widget (priv->prefs_gxml, "tags_treeview");
 	gtk_widget_set_sensitive (treeview, FALSE);
 	
 	pdata = g_new0 (ParseableData, 1);
-	pdata->sdb_plugin = sdb_plugin;
+	pdata->sdbp = sdbp;
 	pdata->path_str = g_strdup (path_str);
 	
-	symbol_db_system_is_package_parseable (sdb_plugin->sdbs, curr_package_name, 
+	symbol_db_system_is_package_parseable (priv->sdbs, curr_package_name, 
 										   on_tag_load_toggled_parseable_cb,
 										   pdata);
 }
 
-void 
-symbol_db_prefs_init (SymbolDBPlugin *sdb_plugin, AnjutaPreferences *prefs)
+static void
+sdb_prefs_init1 (SymbolDBPrefs *sdbp)
 {
-
-	GtkWidget *fchooser, *treeview;
-	GtkCellRenderer *renderer;
-	GtkTreeViewColumn *column;
+	SymbolDBPrefsPriv *priv;
+	GtkWidget *fchooser;
 	gchar *ctags_value;
-	gchar* exe_string = NULL;
-	gboolean require_scan = FALSE;		/* scan for packages */
-	
-	g_return_if_fail (sdb_plugin != NULL);
-	DEBUG_PRINT ("symbol_db_prefs_init ()");
-	
-	if (initialized)
-		return;
-	
-	/* Create the preferences page */
-	gxml = glade_xml_new (GLADE_FILE, GLADE_ROOT, NULL);	
-		
-	fchooser = 	glade_xml_get_widget (gxml, CHOOSER_WIDGET);
+
+	priv = sdbp->priv;
+
+	fchooser = 	glade_xml_get_widget (priv->prefs_gxml, CHOOSER_WIDGET);
+	/* we will reactivate it after the listall has been finished */
+	gtk_widget_set_sensitive (fchooser, FALSE);
 			
-	anjuta_preferences_add_page (prefs, gxml, GLADE_ROOT, _("Symbol Database"),  
+	anjuta_preferences_add_page (priv->prefs, 
+								 priv->prefs_gxml, 
+								 GLADE_ROOT, 
+								 _("Symbol Database"),  
 								 ICON_FILE);
-	ctags_value = anjuta_preferences_get (prefs, CTAGS_PREFS_KEY);
+	
+	ctags_value = anjuta_preferences_get (priv->prefs, CTAGS_PREFS_KEY);
 	
 	if (ctags_value == NULL || strlen (ctags_value) <= 0) 
 	{
 		ctags_value = g_strdup (CTAGS_PATH);
 	}
 	
-	DEBUG_PRINT ("trying to select ->%s<-", ctags_value);
-	if (gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (fchooser), ctags_value) 
-						== FALSE )
-	{
-		DEBUG_PRINT ("error: could not select file uri with gtk_file_chooser_select_filename ()");
-		return;
-	}
+	DEBUG_PRINT ("select ->%s<-", ctags_value);	
+	/* FIXME: wtf?! */
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fchooser), ctags_value);
+	gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (fchooser), ctags_value);
 	
 	g_signal_connect (G_OBJECT (fchooser), "selection-changed",
-					  G_CALLBACK (on_prefs_executable_changed), prefs);
+					  G_CALLBACK (on_prefs_executable_changed), sdbp);
 
-	sdb_plugin->prefs_notify_id = anjuta_preferences_notify_add (prefs, CTAGS_PREFS_KEY, 
-											   on_gconf_notify_prefs, prefs, NULL);	
+	priv->prefs_notify_id = anjuta_preferences_notify_add (priv->prefs, 
+												CTAGS_PREFS_KEY, 
+											   on_gconf_notify_prefs, 
+											   priv->prefs, NULL);		
 	
+	g_free (ctags_value);
+}
+
+static void
+sdb_prefs_init (SymbolDBPrefs *object)
+{
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
+	GtkWidget *treeview;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	gchar* exe_string = NULL;
+	gboolean require_scan = FALSE;		/* scan for packages */
+
+	sdbp = SYMBOL_DB_PREFS (object);
+	sdbp->priv = g_new0 (SymbolDBPrefsPriv, 1);
+	priv = sdbp->priv;
+	
+	priv->pkg_list = NULL;
+	
+	DEBUG_PRINT ("symbol_db_prefs_init ()");
+	
+	if (priv->prefs_gxml == NULL)
+	{
+		/* Create the preferences page */
+		priv->prefs_gxml = glade_xml_new (GLADE_FILE, GLADE_ROOT, NULL);	
+	}		
 	
 	/* init GtkListStore */
-	if (sdb_plugin->prefs_list_store == NULL) 
+	if (priv->prefs_list_store == NULL) 
 	{
-		sdb_plugin->prefs_list_store = gtk_list_store_new (COLUMN_MAX, G_TYPE_BOOLEAN, 
+		priv->prefs_list_store = gtk_list_store_new (COLUMN_MAX, G_TYPE_BOOLEAN, 
 													   G_TYPE_STRING);
 		require_scan = TRUE;
 	}
-	treeview = glade_xml_get_widget (gxml, "tags_treeview");
+	
+	treeview = glade_xml_get_widget (priv->prefs_gxml, "tags_treeview");
+	/* on_listall_exit will reactivate this */
+	gtk_widget_set_sensitive (treeview, FALSE);
 	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
-							 GTK_TREE_MODEL (sdb_plugin->prefs_list_store));	
+							 GTK_TREE_MODEL (priv->prefs_list_store));	
 
 	/* Add the column for stock treeview */
 	renderer = gtk_cell_renderer_toggle_new ();
 	g_signal_connect (G_OBJECT (renderer), "toggled",
-					  G_CALLBACK (on_tag_load_toggled), sdb_plugin);
+					  G_CALLBACK (on_tag_load_toggled), sdbp);
 	column = gtk_tree_view_column_new_with_attributes (_("Load"),
 													   renderer,
 													   "active",
@@ -372,61 +463,130 @@
 	
 	/* frame3 show all */
 	GtkWidget *frame3;
-	frame3 = glade_xml_get_widget (gxml, "frame3");
+	frame3 = glade_xml_get_widget (priv->prefs_gxml, "frame3");
 	gtk_widget_show_all (frame3);
-	GtkWidget *prefs_progressbar = glade_xml_get_widget (gxml, "prefs_progressbar");
+	GtkWidget *prefs_progressbar = glade_xml_get_widget (priv->prefs_gxml, 
+														 "prefs_progressbar");
 	gtk_widget_hide (prefs_progressbar);	
 	
-	
 	/* listall launcher thing */
 	if (require_scan == TRUE) 
 	{
-		sdb_plugin->pkg_config_launcher = anjuta_launcher_new ();
+		priv->pkg_config_launcher = anjuta_launcher_new ();
 
-		anjuta_launcher_set_check_passwd_prompt (sdb_plugin->pkg_config_launcher, 
+		anjuta_launcher_set_check_passwd_prompt (priv->pkg_config_launcher,
 												 FALSE);
-		/* the on_listall_exit callback will continue calling the launcher to process
-		 * every entry received
-		 */
-		g_signal_connect (G_OBJECT (sdb_plugin->pkg_config_launcher), "child-exited",
-					  	G_CALLBACK (on_listall_exit), sdb_plugin);	
+
+		g_signal_connect (G_OBJECT (priv->pkg_config_launcher), "child-exited",
+					  	G_CALLBACK (on_listall_exit), sdbp);	
 	
 		exe_string = g_strdup ("pkg-config --list-all");
 	
-		anjuta_launcher_execute (sdb_plugin->pkg_config_launcher,
-							 	exe_string, on_listall_output, 
-							 	sdb_plugin);
-	}
-	
+		anjuta_launcher_execute (priv->pkg_config_launcher,
+							 	exe_string, on_listall_output,
+							 	sdbp);
+	}	
 		
 	/* unrefs unused memory objects */
-	g_free (ctags_value);
 	g_free (exe_string);
-	
-	/* pkg_tmp_file will be released on launcher_exit */	
-	initialized = TRUE;
 }
 
-void 
-symbol_db_prefs_finalize (SymbolDBPlugin *sdb_plugin, AnjutaPreferences *prefs)
-{	
+static void
+sdb_prefs_finalize (GObject *object)
+{
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
+	
+	sdbp = SYMBOL_DB_PREFS (object);
+	priv = sdbp->priv;
+	
 	DEBUG_PRINT ("symbol_db_prefs_finalize ()");
-	anjuta_preferences_notify_remove(prefs, sdb_plugin->prefs_notify_id);
-	anjuta_preferences_remove_page(prefs, _("Symbol Database"));
+	
+	anjuta_preferences_notify_remove(priv->prefs, priv->prefs_notify_id);
+	anjuta_preferences_remove_page(priv->prefs, _("Symbol Database"));
 
-	if (cflags_launcher != NULL)
-		g_object_unref (cflags_launcher);
-	cflags_launcher = NULL;
+	if (priv->pkg_config_launcher != NULL)
+		g_object_unref (priv->pkg_config_launcher);
+	priv->pkg_config_launcher = NULL;
 	
 	/* free pkg_list */
-	g_list_foreach (pkg_list, (GFunc)g_free, NULL);
-	g_list_free (pkg_list);
-	pkg_list = NULL;
+	g_list_foreach (priv->pkg_list, (GFunc)g_free, NULL);
+	g_list_free (priv->pkg_list);
+	priv->pkg_list = NULL;
+
+	if (priv->prefs_gxml != NULL)
+		g_object_unref (priv->prefs_gxml);
+
+	if (priv->prefs_list_store != NULL)
+		g_object_unref (priv->prefs_list_store);
 	
-	if (gxml != NULL)
-		g_object_unref (gxml);
+	if (priv->enabled_packages_hash)
+	{
+		g_hash_table_destroy (priv->enabled_packages_hash);
+	}
 	
-	/* FIXME: disconnect signals */
-		
-	initialized = FALSE;
+	G_OBJECT_CLASS (sdb_prefs_parent_class)->finalize (object);
+}
+
+static void
+sdb_prefs_class_init (SymbolDBPrefsClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	signals[PACKAGE_ADD]
+		= g_signal_new ("package-add",
+						G_OBJECT_CLASS_TYPE (object_class),
+						G_SIGNAL_RUN_FIRST,
+						G_STRUCT_OFFSET (SymbolDBPrefsClass, package_add),
+						NULL, NULL,
+						g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 
+						1,
+						G_TYPE_STRING);
+
+	signals[PACKAGE_REMOVE]
+		= g_signal_new ("package-remove",
+						G_OBJECT_CLASS_TYPE (object_class),
+						G_SIGNAL_RUN_FIRST,
+						G_STRUCT_OFFSET (SymbolDBPrefsClass, package_remove),
+						NULL, NULL,
+						g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 
+						1,
+						G_TYPE_STRING);	
+	
+	object_class->finalize = sdb_prefs_finalize;
 }
+
+SymbolDBPrefs *
+symbol_db_prefs_new (SymbolDBSystem *sdbs, SymbolDBEngine *sdbe_project,
+					 SymbolDBEngine *sdbe_globals, AnjutaPreferences *prefs,
+					 GList *enabled_packages)
+{
+	SymbolDBPrefs *sdbp;
+	SymbolDBPrefsPriv *priv;
+
+	sdbp = g_object_new (SYMBOL_TYPE_DB_PREFS, NULL);
+	
+	priv = sdbp->priv;	
+	
+	priv->sdbs = sdbs;
+	priv->prefs = prefs;
+	priv->sdbe_project = sdbe_project;
+	priv->sdbe_globals = sdbe_globals;
+	priv->enabled_packages_hash = g_hash_table_new_full (g_str_hash, g_str_equal, 
+													g_free, NULL);
+
+	/* we'll convert the list of strings in input into an hash table, so that
+	 * a lookup there will be done quicker
+	 */
+	GList *item = enabled_packages;
+	while (item != NULL)
+	{
+		g_hash_table_insert (priv->enabled_packages_hash, (gpointer)g_strdup (item->data), 
+							 (gpointer)TRUE);
+		item = item->next;
+	}	
+	
+	sdb_prefs_init1 (sdbp);	
+	return sdbp;
+}
+

Modified: trunk/plugins/symbol-db/symbol-db-prefs.h
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-prefs.h	(original)
+++ trunk/plugins/symbol-db/symbol-db-prefs.h	Wed Jul 16 16:11:05 2008
@@ -1,36 +1,68 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
- * symbol-db-prefs.h
- * Copyright (C) Massimo Cora' 2007-2008 <maxcvs email it>
+ * anjuta_trunk
+ * Copyright (C) Massimo Cora' 2008 <maxcvs email it>
  * 
- * plugin.c is free software.
+ * anjuta_trunk is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
  * 
- * You may redistribute it and/or modify it under the terms of the
- * GNU General Public License, as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * plugin.c is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * anjuta_trunk is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License
- * along with plugin.c.  If not, write to:
- * 	The Free Software Foundation, Inc.,
- * 	51 Franklin Street, Fifth Floor
- * 	Boston, MA  02110-1301, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __SYMBOL_DB_PREFS_H__
-#define __SYMBOL_DB_PREFS_H__
+#ifndef _SYMBOL_DB_PREFS_H_
+#define _SYMBOL_DB_PREFS_H_
+
+#include <glib-object.h>
+
+
+G_BEGIN_DECLS
+
+#define SYMBOL_TYPE_DB_PREFS             (sdb_prefs_get_type ())
+#define SYMBOL_DB_PREFS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SYMBOL_TYPE_DB_PREFS, SymbolDBPrefs))
+#define SYMBOL_DB_PREFS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SYMBOL_TYPE_DB_PREFS, SymbolDBPrefsClass))
+#define SYMBOL_IS_DB_PREFS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SYMBOL_TYPE_DB_PREFS))
+#define SYMBOL_IS_DB_PREFS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SYMBOL_TYPE_DB_PREFS))
+#define SYMBOL_DB_PREFS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SYMBOL_TYPE_DB_PREFS, SymbolDBPrefsClass))
+
+typedef struct _SymbolDBPrefsClass SymbolDBPrefsClass;
+typedef struct _SymbolDBPrefs SymbolDBPrefs;
+typedef struct _SymbolDBPrefsPriv SymbolDBPrefsPriv;
 
 #include "plugin.h"
+#include "symbol-db-system.h"
 
-void symbol_db_prefs_init (SymbolDBPlugin *plugin, AnjutaPreferences *prefs);
-void symbol_db_prefs_finalize (SymbolDBPlugin *plugin, AnjutaPreferences *prefs);
+struct _SymbolDBPrefsClass
+{
+	GObjectClass parent_class;
+	
+	/* signals */
+	void (* package_add) 		(const gchar *package);
+	void (* package_remove)		(const gchar *package);
+	
+};
 
-/*
-void symbol_db_load_global_tags (gpointer plugin);
-*/
-#endif
+struct _SymbolDBPrefs
+{
+	GObject parent_instance;	
+	SymbolDBPrefsPriv *priv;
+};
+
+GType sdb_prefs_get_type (void) G_GNUC_CONST;
+
+SymbolDBPrefs *
+symbol_db_prefs_new (SymbolDBSystem *sdbs, SymbolDBEngine *sdbe_project,
+					 SymbolDBEngine *sdbe_globals, AnjutaPreferences *prefs,
+					 GList *enabled_packages);
+
+
+G_END_DECLS
+
+#endif /* _SYMBOL_DB_PREFS_H_ */

Modified: trunk/plugins/symbol-db/symbol-db-system.c
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-system.c	(original)
+++ trunk/plugins/symbol-db/symbol-db-system.c	Wed Jul 16 16:11:05 2008
@@ -42,7 +42,7 @@
 	
 	GQueue *sscan_queue;
 	GQueue *engine_queue;
-};
+}; 
 
 typedef struct _SingleScanData {
 	SymbolDBSystem *sdbs;
@@ -59,6 +59,9 @@
 	SymbolDBSystem *sdbs;
 	gchar *package_name;	
 	GList *cflags;
+	gboolean special_abort_scan;
+	GPtrArray *files_to_scan_array;		
+	GPtrArray *languages_array;			
 	
 } EngineScanData;
 
@@ -80,6 +83,8 @@
 				   int exit_status, gulong time_taken_in_seconds,
 				   gpointer user_data);
 
+static void
+on_engine_package_scan_end (SymbolDBEngine *dbe, gpointer user_data);
 
 static void
 destroy_single_scan_data (SingleScanData *ss_data)
@@ -102,6 +107,15 @@
 	}
 	
 	g_free (es_data->package_name);
+	
+	if (es_data->special_abort_scan == TRUE)
+	{
+		g_ptr_array_foreach (es_data->files_to_scan_array, (GFunc)g_free, NULL);
+		g_ptr_array_free (es_data->files_to_scan_array, TRUE);
+			
+		g_ptr_array_foreach (es_data->languages_array, (GFunc)g_free, NULL);
+		g_ptr_array_free (es_data->languages_array, TRUE);
+	}
 	g_free (es_data);
 }
 
@@ -415,6 +429,70 @@
 	} while ((node = node->next) != NULL);
 }
 
+static inline void
+sdb_system_do_engine_scan (SymbolDBSystem *sdbs, EngineScanData *es_data)
+{
+	SymbolDBSystemPriv *priv;
+	GPtrArray *files_to_scan_array; 
+	GPtrArray *languages_array;
+	
+	priv = sdbs->priv;
+			
+	g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
+ 			G_CALLBACK (on_engine_package_scan_end), es_data);
+
+	if (es_data->special_abort_scan == FALSE)
+	{
+		files_to_scan_array = g_ptr_array_new ();
+		languages_array = g_ptr_array_new();
+		
+		/* the above arrays will be populated with this function */
+		prepare_files_to_be_scanned (sdbs, es_data->cflags, files_to_scan_array,
+								 languages_array);
+
+		symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
+								  		es_data->package_name);
+	}
+	else 
+	{
+		files_to_scan_array = es_data->files_to_scan_array;
+		languages_array = es_data->languages_array;
+	}		
+							
+	
+	/* notify the listeners about our intention of adding new files
+	 * to the db 
+	 */
+	g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0, 
+				   files_to_scan_array->len,
+				   es_data->package_name); 
+			
+	/* note the FALSE as last parameter: we don't want
+	 * to re-scan an already present file. There's the possibility
+	 * infact to have more references of the same files in different
+	 * packages
+	 */
+	symbol_db_engine_add_new_files (priv->sdbe_globals,
+							es_data->special_abort_scan == FALSE ? 
+									es_data->package_name : NULL, 
+							files_to_scan_array,
+							languages_array,
+							es_data->special_abort_scan == FALSE ? 
+									FALSE : TRUE);
+		
+	/* hey, destroy_engine_scan_data () will take care of destroying these for us,
+	 * in case we're on a special_abort_scan
+	 */
+	if (es_data->special_abort_scan == FALSE)
+	{
+		g_ptr_array_foreach (files_to_scan_array, (GFunc)g_free, NULL);
+		g_ptr_array_free (files_to_scan_array, TRUE);
+			
+		g_ptr_array_foreach (languages_array, (GFunc)g_free, NULL);
+		g_ptr_array_free (languages_array, TRUE);	
+	}
+}
+
 static void
 on_engine_package_scan_end (SymbolDBEngine *dbe, gpointer user_data)
 {
@@ -440,37 +518,11 @@
 	
 	/* have we got something left in the queue? */
 	if (g_queue_get_length (priv->engine_queue) > 0)
-	{
-		GPtrArray *files_to_scan_array;
-		GPtrArray *languages_array;
-		EngineScanData *es_data;
-		
-		files_to_scan_array = g_ptr_array_new ();
-		languages_array = g_ptr_array_new();
-				
+	{				
 		/* peek the head */
 		es_data = g_queue_peek_head (priv->engine_queue);
 	
-		DEBUG_PRINT ("gonna scanning on_engine_package_scan_end %s", es_data->package_name);
-		/* the above arrays will be populated with this function */
-		prepare_files_to_be_scanned (sdbs, es_data->cflags, files_to_scan_array,
-									 languages_array);
-				
-		g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
-	  			G_CALLBACK (on_engine_package_scan_end), es_data);
-				
-		symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
-									  		es_data->package_name);
-			
-		g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0, 
-					   files_to_scan_array->len,
-					   es_data->package_name); 
-		
-		symbol_db_engine_add_new_files (priv->sdbe_globals,
-									es_data->package_name, 
-									files_to_scan_array,
-									languages_array,
-									FALSE);
+		sdb_system_do_engine_scan (sdbs, es_data);
 	}
 }
 
@@ -482,6 +534,8 @@
 	gchar *exe_string;
 	priv = sdbs->priv;
 	
+	DEBUG_PRINT ("sdb_system_do_scan_package_1 SCANNING %s", 
+				 ss_data->package_name);
 	exe_string = g_strdup_printf ("pkg-config --cflags %s", 
 								  ss_data->package_name);
 	
@@ -581,6 +635,7 @@
 		es_data->sdbs = sdbs;
 		es_data->cflags = cflags;
 		es_data->package_name = g_strdup (ss_data->package_name);
+		es_data->special_abort_scan = FALSE;
 			
 		/* is the engine queue already full && working? */
 		if (g_queue_get_length (priv->engine_queue) > 0) 
@@ -593,39 +648,10 @@
 		}
 		else
 		{
-			GPtrArray *files_to_scan_array = g_ptr_array_new ();
-			GPtrArray *languages_array = g_ptr_array_new();
-			
 			/* push the tail to signal a 'working engine' */
 			g_queue_push_tail (priv->engine_queue, es_data);
 			
-			/* the above arrays will be populated with this function */
-			prepare_files_to_be_scanned (sdbs, cflags, files_to_scan_array,
-										 languages_array);
-			
-			g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
-	  			G_CALLBACK (on_engine_package_scan_end), es_data);
-							
-			symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
-										  		es_data->package_name);
-	
-			/* notify the listeners about our intention of adding new files
-			 * to the db 
-			 */
-			g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0, 
-						   files_to_scan_array->len,
-						   es_data->package_name); 
-			
-			/* note the FALSE as last parameter: we don't want
-			 * to re-scan an already present file. There's the possibility
-			 * infact to have more references of the same files in different
-			 * packages
-			 */
-			symbol_db_engine_add_new_files (priv->sdbe_globals,
-										es_data->package_name, 
-										files_to_scan_array,
-										languages_array,
-										FALSE);
+			sdb_system_do_engine_scan (sdbs, es_data);
 		}
 	}
 	
@@ -652,10 +678,15 @@
 	/* does is already exist on db? */
 	if (symbol_db_system_is_package_parsed (sdbs, package_name) == TRUE)
 	{
-		DEBUG_PRINT ("symbol_db_system_scan_package: no need to scan %s",
+		DEBUG_PRINT ("symbol_db_system_scan_package (): no need to scan %s",
 					 package_name);
 		return FALSE;
 	}
+	else 
+	{
+		DEBUG_PRINT ("symbol_db_system_scan_package (): NEED to scan %s",
+					 package_name);
+	}
 	
 	/* create the object to store in the queue */
 	ss_data = (SingleScanData*)g_new0 (SingleScanData, 1);
@@ -702,3 +733,46 @@
 	/* package is a new one. No worries about scan queue */
 	sdb_system_do_scan_new_package (sdbs, ss_data);
 }
+
+void 
+symbol_db_parse_aborted_package (SymbolDBSystem *sdbs, 
+								 GPtrArray *files_to_scan_array,
+								 GPtrArray *languages_array)
+{
+	SymbolDBSystemPriv *priv;
+	EngineScanData *es_data;
+	
+	g_return_if_fail (sdbs != NULL);
+	g_return_if_fail (files_to_scan_array != NULL);
+	g_return_if_fail (languages_array != NULL);
+	
+	priv = sdbs->priv;
+	
+	/* create a special EngineScanData */
+	es_data = g_new0 (EngineScanData, 1);
+	es_data->sdbs = sdbs;
+	es_data->cflags = NULL;
+	es_data->package_name = g_strdup (_("Resuming glb scan."));
+	es_data->special_abort_scan = TRUE;
+	es_data->files_to_scan_array = files_to_scan_array;
+	es_data->languages_array = languages_array;
+		
+		
+	/* is the engine queue already full && working? */
+	if (g_queue_get_length (priv->engine_queue) > 0) 
+	{
+		/* just push the tail waiting for a later processing [i.e. after
+		 * a scan-end received 
+		 */
+		DEBUG_PRINT ("pushing on engine queue %s", es_data->package_name);
+		g_queue_push_tail (priv->engine_queue, es_data);
+	}
+	else
+	{
+		/* push the tail to signal a 'working engine' */
+		g_queue_push_tail (priv->engine_queue, es_data);
+		
+		sdb_system_do_engine_scan (sdbs, es_data);
+	}
+}
+

Modified: trunk/plugins/symbol-db/symbol-db-system.h
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-system.h	(original)
+++ trunk/plugins/symbol-db/symbol-db-system.h	Wed Jul 16 16:11:05 2008
@@ -101,6 +101,17 @@
 symbol_db_system_scan_package (SymbolDBSystem *sdbs,
 							  const gchar * package_name);
 
+/**
+ * Scan global db for unscanned files.
+ * @warning @param files_to_scan_array Must not to be freed by caller. They'll be 
+ * freed inside this function. This for speed reasons.
+ * @warning @param languages_array Must not to be freed by caller. They'll be 
+ * freed inside this function. This for speed reasons.
+ */
+void 
+symbol_db_parse_aborted_package (SymbolDBSystem *sdbs, 
+								 GPtrArray *files_to_scan_array,
+								 GPtrArray *languages_array);
 G_END_DECLS
 
 #endif /* _SYMBOL_DB_SYSTEM_H_ */

Modified: trunk/plugins/symbol-db/symbol-db-view.c
==============================================================================
--- trunk/plugins/symbol-db/symbol-db-view.c	(original)
+++ trunk/plugins/symbol-db/symbol-db-view.c	Wed Jul 16 16:11:05 2008
@@ -976,7 +976,9 @@
 									TRUE,
 									-1,
 									-1,
-									SYMINFO_SIMPLE| SYMINFO_KIND| SYMINFO_ACCESS
+									SYMINFO_SIMPLE| 
+									SYMINFO_KIND| 
+									SYMINFO_ACCESS
 									);
 
 	g_ptr_array_free (filter_array, TRUE);
@@ -1024,10 +1026,6 @@
 	
 	store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (dbv)));
 
-	filter_array = g_ptr_array_new ();
-	g_ptr_array_add (filter_array, "class");
-	g_ptr_array_add (filter_array, "struct");
-
 	DEBUG_PRINT ("sdb_view_global_row_expanded ()");
 	
 	/* check if there's another expanding idle_func running */
@@ -1036,11 +1034,16 @@
 	{
 		return;
 	}
+
+	filter_array = g_ptr_array_new ();
+	g_ptr_array_add (filter_array, "class");
+	g_ptr_array_add (filter_array, "struct");
 	
 	/* check for the presence of namespaces. 
 	 * If that's the case then populate the root with a 'Global' node.
 	 */
-	iterator = symbol_db_engine_get_global_members_filtered (dbe, filter_array, TRUE, 
+	iterator = symbol_db_engine_get_global_members_filtered (dbe, filter_array, 
+													TRUE, 
 													TRUE, 
 													-1,
 													-1,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]