[anjuta] symbol-db: fixed some issues related to local-view



commit 5ee8e6cbb09400543ce6cd92b14bc8c4a9e06ff9
Author: Massimo Corà <mcora src gnome org>
Date:   Tue Jul 21 19:45:36 2009 +0200

    symbol-db: fixed some issues related to local-view
    
    we can have a weird behaviour updating the buffer if we're not paying the right attention:
    a timeout scan could have been launched and a millisecond later the user could
    have switched editor: we'll be getting the symbol inserted in the previous
    editor into the new one's view, creating confusion.

 plugins/symbol-db/plugin.c                |  135 +++++++++++++++++++++--------
 plugins/symbol-db/plugin.h                |   10 ++-
 plugins/symbol-db/symbol-db-engine-core.c |    6 +-
 plugins/symbol-db/symbol-db-prefs.c       |    2 +-
 plugins/symbol-db/symbol-db-view-locals.c |  106 ++++++++++++++++++++---
 5 files changed, 205 insertions(+), 54 deletions(-)
---
diff --git a/plugins/symbol-db/plugin.c b/plugins/symbol-db/plugin.c
index 21e8e3b..def1b52 100644
--- a/plugins/symbol-db/plugin.c
+++ b/plugins/symbol-db/plugin.c
@@ -351,33 +351,6 @@ enable_view_signals (SymbolDBPlugin *sdb_plugin, gboolean enable, gboolean force
 	}
 }
 
-static void
-on_editor_buffer_symbol_update_scan_end (SymbolDBEngine *dbe, gint process_id, 
-										  gpointer data)
-{
-	SymbolDBPlugin *sdb_plugin;
-	gint i;
-	
-	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);	
-	
-	/* search for the proc id */
-	for (i = 0; i < sdb_plugin->buffer_update_ids->len; i++)
-	{
-		if (g_ptr_array_index (sdb_plugin->buffer_update_ids, i) == GINT_TO_POINTER (process_id))
-		{
-			gchar *str;
-			/* hey we found it */
-			/* remove both the items */
-			g_ptr_array_remove_index (sdb_plugin->buffer_update_ids, i);
-			
-			str = (gchar*)g_ptr_array_remove_index (sdb_plugin->buffer_update_files, 
-													i);
-			/* we can now free it */
-			g_free (str);			
-		}
-	}
-}
-
 static gboolean
 on_editor_buffer_symbols_update_timeout (gpointer user_data)
 {
@@ -491,6 +464,76 @@ on_editor_buffer_symbols_update_timeout (gpointer user_data)
 }
 
 static void
+on_editor_buffer_symbol_update_scan_end (SymbolDBEngine *dbe, gint process_id, 
+										  gpointer data)
+{
+	SymbolDBPlugin *sdb_plugin;
+	gint i;
+	
+	sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);	
+	
+	/* search for the proc id */
+	for (i = 0; i < sdb_plugin->buffer_update_ids->len; i++)
+	{
+		if (g_ptr_array_index (sdb_plugin->buffer_update_ids, i) == GINT_TO_POINTER (process_id))
+		{
+			gchar *str;
+			/* hey we found it */
+			/* remove both the items */
+			g_ptr_array_remove_index (sdb_plugin->buffer_update_ids, i);
+			
+			str = (gchar*)g_ptr_array_remove_index (sdb_plugin->buffer_update_files, 
+													i);
+			/* we can now free it */
+			g_free (str);			
+		}
+	}
+
+	/* was the updating of view-locals symbols blocked while we were scanning?
+	 * e.g. was the editor switched? */
+	if (sdb_plugin->buffer_update_semaphore == TRUE)
+	{
+		GFile *file;
+		gchar *local_path;
+		gboolean tags_update;
+		if (!IANJUTA_IS_EDITOR (sdb_plugin->current_editor))
+			return;
+	
+		file = ianjuta_file_get_file (IANJUTA_FILE (sdb_plugin->current_editor), 
+		    NULL);
+	
+		if (file == NULL)
+			return;
+
+		local_path = g_file_get_path (file);
+	
+		if (local_path == NULL)
+		{
+			g_critical ("local_path == NULL");
+			return;
+		}	
+
+		symbol_db_view_locals_update_list (
+					SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
+					 sdb_plugin->sdbe_project, local_path, FALSE);
+
+		/* add a default timeout to the updating of buffer symbols */	
+		tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
+		
+		if (tags_update)
+		{
+			sdb_plugin->buf_update_timeout_id = 
+					g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
+										   on_editor_buffer_symbols_update_timeout,
+										   sdb_plugin);
+		}		
+		
+		g_free (local_path);
+		
+	}	 
+}
+
+static void
 on_editor_destroy (SymbolDBPlugin *sdb_plugin, IAnjutaEditor *editor)
 {
 	const gchar *uri;
@@ -639,10 +682,33 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
 		g_critical ("local_path == NULL");
 		return;
 	}	
+
+	/* we can have a weird behaviour here if we're not paying the right attention:
+	 * A timeout scan could have been launched and a millisecond later the user could
+	 * have switched editor: we'll be getting the symbol inserted in the previous
+	 * editor into the new one's view.
+	 */
+	if (sdb_plugin->buffer_update_files->len > 0)
+	{
+		sdb_plugin->buffer_update_semaphore = TRUE;
+	}
+	else
+	{
+		symbol_db_view_locals_update_list (
+					SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
+					 sdb_plugin->sdbe_project, local_path, FALSE);
+
+		/* add a default timeout to the updating of buffer symbols */	
+		tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
 				
-	symbol_db_view_locals_update_list (
-				SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
-				 sdb_plugin->sdbe_project, local_path, FALSE);
+		if (tags_update)
+		{
+			sdb_plugin->buf_update_timeout_id = 
+					g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
+										   on_editor_buffer_symbols_update_timeout,
+										   plugin);
+		}		
+	}
 				 
 	if (g_hash_table_lookup (sdb_plugin->editor_connected, editor) == NULL)
 	{
@@ -673,14 +739,6 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
 	g_free (uri);
 	g_free (local_path);
 	
-	/* add a default timeout to the updating of buffer symbols */	
-	tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
-				
-	if (tags_update)
-		sdb_plugin->buf_update_timeout_id = 
-				g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
-									   on_editor_buffer_symbols_update_timeout,
-									   plugin);
 	sdb_plugin->need_symbols_update = FALSE;
 }
 
@@ -2180,6 +2238,7 @@ symbol_db_activate (AnjutaPlugin *plugin)
 	 */
 	sdb_plugin->buffer_update_files = g_ptr_array_new ();
 	sdb_plugin->buffer_update_ids = g_ptr_array_new ();
+	sdb_plugin->buffer_update_semaphore = FALSE;
 	
 	sdb_plugin->is_offline_scanning = FALSE;
 	sdb_plugin->is_project_importing = FALSE;
diff --git a/plugins/symbol-db/plugin.h b/plugins/symbol-db/plugin.h
index c435766..c4edceb 100644
--- a/plugins/symbol-db/plugin.h
+++ b/plugins/symbol-db/plugin.h
@@ -72,6 +72,12 @@ struct _SymbolDBPlugin {
 	GTimer *update_timer;
 	GPtrArray *buffer_update_files;
 	GPtrArray *buffer_update_ids;
+	gboolean buffer_update_semaphore;		/* it monitors the update status of the
+	 										 * buffer _and_ the editor switching.
+	 										 * A new page cannot be updated with the
+	 										 * new view-locals symbols if a scanning
+	 										 * is in progress 
+	 										 */
 	guint editor_watch_id;
 	gchar *project_root_uri;
 	gchar *project_root_dir;
@@ -130,7 +136,9 @@ struct _SymbolDBPlugin {
 	gchar *current_scanned_package;
 	GList *session_packages;
 	
-	GTree *proc_id_tree;
+	GTree *proc_id_tree;				/* the scan processes'll receive an id from 
+	 									 * the symbol engine when scan-end happens. 
+	 									 * Track them here */
 	
 	gboolean is_project_importing;		/* refreshes or resumes after abort */
 	gboolean is_project_updating;		/* makes up to date symbols of the project's files */
diff --git a/plugins/symbol-db/symbol-db-engine-core.c b/plugins/symbol-db/symbol-db-engine-core.c
index 779017d..9f0c8e7 100644
--- a/plugins/symbol-db/symbol-db-engine-core.c
+++ b/plugins/symbol-db/symbol-db-engine-core.c
@@ -5984,12 +5984,12 @@ symbol_db_engine_update_buffer_symbols (SymbolDBEngine * dbe, const gchar *proje
 	/* in case we didn't have any good buffer to scan...*/
 	ret_id = -1;
 	
-	/* it may happens that no buffer is correctly set up */
+	/* it may happen that no buffer is correctly set up */
 	if (real_files_on_db->len > 0)
 	{
 		/* data will be freed when callback will be called. The signal will be
-	 	* disconnected too, don't worry about disconnecting it by hand.
-	 	*/
+	 	 * disconnected too, don't worry about disconnecting it by hand.
+	 	 */
 		g_signal_connect (G_OBJECT (dbe), "scan-end",
 						  G_CALLBACK (on_scan_update_buffer_end), real_files_list);
 	
diff --git a/plugins/symbol-db/symbol-db-prefs.c b/plugins/symbol-db/symbol-db-prefs.c
index 2a1952c..9e00e82 100644
--- a/plugins/symbol-db/symbol-db-prefs.c
+++ b/plugins/symbol-db/symbol-db-prefs.c
@@ -358,7 +358,7 @@ sdb_prefs_init1 (SymbolDBPrefs *sdbp)
 {
 	SymbolDBPrefsPriv *priv;
 /*	GtkWidget *fchooser;*/
-	gchar *ctags_value;
+/*	gchar *ctags_value;*/
 
 	priv = sdbp->priv;
 
diff --git a/plugins/symbol-db/symbol-db-view-locals.c b/plugins/symbol-db/symbol-db-view-locals.c
index be68abc..b53db9a 100644
--- a/plugins/symbol-db/symbol-db-view-locals.c
+++ b/plugins/symbol-db/symbol-db-view-locals.c
@@ -51,8 +51,8 @@ typedef struct _WaitingForSymbol {
 
 typedef struct _TraverseData {
 	SymbolDBViewLocals *dbvl;
-	SymbolDBEngine *dbe;
-
+	void *data;
+	
 } TraverseData;
 
 typedef struct _FileSymbolsStatus {
@@ -74,7 +74,8 @@ struct _SymbolDBViewLocalsPriv {
 	
 	GTree *nodes_displayed;
 	GTree *waiting_for;	
-	GQueue *symbols_inserted_ids;
+	GQueue *symbols_inserted_ids;	
+	GTree *nodes_not_yet_removed;		/* this'll remain active across views */
 
 	gboolean display_nothing;
 	gboolean recv_signals;
@@ -220,6 +221,12 @@ symbol_db_view_locals_clear_cache (SymbolDBViewLocals *dbvl)
 			priv->waiting_for = NULL;
 		}
 
+		if (priv->nodes_not_yet_removed)
+		{
+			g_tree_destroy (priv->nodes_not_yet_removed);
+			priv->nodes_not_yet_removed = NULL;
+		}
+			
 		store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (dbvl)));
 		if (store != NULL)
 			g_object_unref (store);
@@ -274,7 +281,7 @@ sdb_view_locals_init (SymbolDBViewLocals *dbvl)
 	
 	g_return_if_fail (dbvl != NULL);
 
-	DEBUG_PRINT ("%s", "sdb_view_locals_init  ()");
+	/*DEBUG_PRINT ("%s", "sdb_view_locals_init  ()");*/
 	dbvl->priv = g_new0 (SymbolDBViewLocalsPriv, 1);		
 	priv = dbvl->priv;
 		
@@ -282,6 +289,10 @@ sdb_view_locals_init (SymbolDBViewLocals *dbvl)
 	priv->current_local_file_path = NULL;
 	priv->nodes_displayed = NULL;
 	priv->waiting_for = NULL;
+	priv->nodes_not_yet_removed = g_tree_new_full ((GCompareDataFunc)&symbol_db_gtree_compare_func, 
+	    											NULL,
+	    											NULL,
+	    											NULL);
 	priv->symbols_inserted_ids = NULL;
 	priv->insert_handler = 0;
 	priv->scan_end_handler = 0;
@@ -490,7 +501,7 @@ traverse_on_scan_end (gpointer key, gpointer value, gpointer data)
 
 	tdata = (TraverseData *)data;
 
-	dbe = tdata->dbe;
+	dbe = SYMBOL_DB_ENGINE (tdata->data);
 	dbvl = tdata->dbvl;
 
 	g_return_val_if_fail (dbe != NULL, FALSE);
@@ -843,7 +854,7 @@ consume_symbols_inserted_queue_idle_destroy (gpointer data)
 	tdata = (TraverseData *)data;
 
 	dbvl = tdata->dbvl;
-	dbe = tdata->dbe;	
+	dbe = SYMBOL_DB_ENGINE (tdata->data);
 	g_return_if_fail (dbvl != NULL);
 	priv = dbvl->priv;
 	
@@ -889,7 +900,7 @@ consume_symbols_inserted_queue_idle (gpointer data)
 	tdata = (TraverseData *)data;
 
 	dbvl = tdata->dbvl;
-	dbe = tdata->dbe;	
+	dbe = SYMBOL_DB_ENGINE (tdata->data);
 	g_return_val_if_fail (dbvl != NULL, FALSE);
 	priv = dbvl->priv;
 	
@@ -1039,7 +1050,7 @@ on_scan_end (SymbolDBEngine *dbe, gint process_id, gpointer data)
 	
 	tdata = g_new (TraverseData, 1);
 	tdata->dbvl = dbvl;
-	tdata->dbe = dbe;
+	tdata->data = dbe;
 	
 	/*DEBUG_PRINT ("%s", "locals: on_scan_end");*/
 	if (priv->symbols_inserted_ids != NULL)
@@ -1117,11 +1128,14 @@ on_symbol_removed (SymbolDBEngine *dbe, gint symbol_id, gpointer data)
 		return;
 	}
 	
-	/*DEBUG_PRINT ("on_symbol_removed (): -local- %d", symbol_id);*/
+	/* DEBUG_PRINT ("-local- %d", symbol_id); */
 
 	row_ref = g_tree_lookup (priv->nodes_displayed, GINT_TO_POINTER (symbol_id));
 	if (sdb_view_locals_get_iter_from_row_ref (dbvl, row_ref, &iter) == FALSE)
 	{
+		/* DEBUG_PRINT ("found no row...."); */
+		g_tree_insert (priv->nodes_not_yet_removed, GINT_TO_POINTER (symbol_id), 
+		    GINT_TO_POINTER (symbol_id));
 		return;
 	}
 
@@ -1174,6 +1188,8 @@ on_symbol_inserted (SymbolDBEngine *dbe, gint symbol_id, gpointer data)
 	{
 		return;
 	}
+
+	/* DEBUG_PRINT ("-local- %d", symbol_id); */
 	
 	/* save the symbol_id to be added in the queue and just return */
 	g_queue_push_head (priv->symbols_inserted_ids, GINT_TO_POINTER (symbol_id));
@@ -1309,6 +1325,44 @@ symbol_db_view_locals_display_nothing (SymbolDBViewLocals *dbvl,
 	}
 }
 
+static gboolean 
+traverse_check_for_unremoved_symbols (gpointer key, gpointer value, gpointer data)
+{
+	SymbolDBViewLocals *dbvl;
+	SymbolDBViewLocalsPriv *priv;	
+    GtkTreeIter iter;	
+	GtkTreeRowReference *row_ref;	
+	GList *removed_items = NULL;
+	TraverseData *tdata;
+
+	tdata = (TraverseData *)data;
+	
+	dbvl = tdata->dbvl;
+	removed_items = tdata->data;
+	
+	priv = dbvl->priv;
+
+	row_ref = g_tree_lookup (priv->nodes_displayed, GINT_TO_POINTER (key));
+	if (sdb_view_locals_get_iter_from_row_ref (dbvl, row_ref, &iter) == FALSE)
+	{
+		tdata->data = removed_items;
+		/* nothing found */
+		/* continue traversing */
+		return FALSE;
+	}
+		
+	do_recurse_subtree_and_remove (dbvl, &iter);	
+
+	/* we've removed something. Save it in the list so later the items
+	 * can be removed from the gtree.
+	 */
+	removed_items = g_list_prepend (removed_items, key);
+
+	tdata->data = removed_items;
+	/* continue traversing */
+	return FALSE;
+}
+
 void
 symbol_db_view_locals_update_list (SymbolDBViewLocals *dbvl, SymbolDBEngine *dbe,
 							  const gchar* filepath, gboolean force_update)
@@ -1441,13 +1495,43 @@ symbol_db_view_locals_update_list (SymbolDBViewLocals *dbvl, SymbolDBEngine *dbe
 			
 			tdata = g_new0 (TraverseData, 1);
 			tdata->dbvl = dbvl;
-			tdata->dbe = dbe;
+			tdata->data = dbe;
 			
 			priv->insertion_idle_handler = g_idle_add_full (G_PRIORITY_LOW, 
 						 (GSourceFunc) consume_symbols_inserted_queue_idle,
 						 (gpointer) tdata,
 						 (GDestroyNotify) consume_symbols_inserted_queue_idle_destroy);			
-		}		
+		}
+
+		/* fine, but some symbol-remove signals can have been left. Check if they
+		 * can be removed 
+		 */
+		GList *removed_list;
+		TraverseData *tdata;
+
+		tdata = g_new0 (TraverseData, 1);
+		tdata->dbvl = dbvl;
+
+		g_tree_foreach (priv->nodes_not_yet_removed, 
+		    traverse_check_for_unremoved_symbols, tdata);
+
+		/* the result */
+		removed_list = tdata->data;
+		
+		/* have we removed something? We'll know that checking the list */
+		if (removed_list != NULL)
+		{
+			GList *node = removed_list;
+			while (node != NULL)
+			{
+				g_tree_remove (priv->nodes_not_yet_removed, node->data);
+
+				node = node->next;
+			}			
+		}
+		
+		g_list_free (removed_list);
+		g_free (tdata);	
 	}
 	else 
 	{	



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