[anjuta/newproject] pm: Fix refresh of node including shortcut



commit 439c9b483aa9cc544b9b47d1b6e78fe1cb16fd6a
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Mon Aug 16 19:43:48 2010 +0200

    pm: Fix refresh of node including shortcut

 plugins/am-project/am-project.c         |   58 ++++++++++++++-
 plugins/project-manager/Makefile.am     |   22 +++++-
 plugins/project-manager/plugin.c        |   68 ++++++++++++++----
 plugins/project-manager/project-model.c |  119 +++++++++++++++++++++++++++++--
 plugins/project-manager/project-view.c  |   68 ++++++++++++------
 plugins/project-manager/project-view.h  |    1 +
 plugins/project-manager/project.c       |   40 ++++++++---
 plugins/project-manager/tree-data.c     |   10 ++-
 plugins/project-manager/tree-data.h     |    4 +-
 9 files changed, 329 insertions(+), 61 deletions(-)
---
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index 4791963..dbbbd47 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -111,6 +111,8 @@ struct _AmpGroupData {
 	GList *tokens[AM_GROUP_TOKEN_LAST];					/* List of token used by this group */
 	AnjutaToken *make_token;
 	GHashTable *variables;
+	GFileMonitor *monitor;			/* File monitor */
+	AmpProject *project;			/* Project used by file monitor */
 };
 
 typedef enum _AmpTargetFlag
@@ -849,6 +851,37 @@ amp_group_set_dist_only (AmpGroup *node, gboolean dist_only)
  	AMP_GROUP_DATA (node)->dist_only = dist_only;
 }
 
+static void
+on_group_monitor_changed (GFileMonitor *monitor,
+											GFile *file,
+											GFile *other_file,
+											GFileMonitorEvent event_type,
+											gpointer data)
+{
+	AmpGroup *g_node = data;
+
+	switch (event_type) {
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		case G_FILE_MONITOR_EVENT_DELETED:
+			g_message ("node updated node %p group %p project %p", g_node, AMP_GROUP_DATA (g_node), AMP_GROUP_DATA (g_node)->project);
+			/* project can be NULL, if the node is dummy node because the
+			 * original one is reloaded. */
+			if (!(anjuta_project_node_get_full_type ((AnjutaProjectNode *)g_node) & ANJUTA_PROJECT_PROXY))
+			{
+				g_signal_emit_by_name (G_OBJECT (AMP_GROUP_DATA (g_node)->project), "node-updated", data);
+			}
+			else
+			{
+				g_message ("proxy changed");
+			}
+			g_message ("signal emitted");
+			break;
+		default:
+			break;
+	}
+}
+
+
 static AnjutaTokenFile*
 amp_group_set_makefile (AmpGroup *node, GFile *makefile, AmpProject* project)
 {
@@ -872,12 +905,28 @@ amp_group_set_makefile (AmpGroup *node, GFile *makefile, AmpProject* project)
 		scanner = amp_am_scanner_new (project, node);
 		group->make_token = amp_am_scanner_parse_token (scanner, anjuta_token_new_static (ANJUTA_TOKEN_FILE, NULL), token, makefile, NULL);
 		amp_am_scanner_free (scanner);
+
+		group->monitor = g_file_monitor_file (makefile, 
+						      									G_FILE_MONITOR_NONE,
+						       									NULL,
+						       									NULL);
+		if (group->monitor != NULL)
+		{
+			g_message ("add monitor %s node %p data %p project %p", g_file_get_path (makefile), node, group, project);
+			group->project = project;
+			g_signal_connect (G_OBJECT (group->monitor),
+					  "changed",
+					  G_CALLBACK (on_group_monitor_changed),
+					  node);
+		}
 	}
 	else
 	{
 		group->makefile = NULL;
 		group->tfile = NULL;
 		group->make_token = NULL;
+		if (group->monitor) g_object_unref (group->monitor);
+		group->monitor = NULL;
 	}
 
 	return group->tfile;
@@ -902,7 +951,6 @@ amp_group_new (GFile *file, gboolean dist_only)
 	group->dist_only = dist_only;
 	group->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)amp_variable_free);
 
-
     return g_node_new (group);
 }
 
@@ -923,6 +971,9 @@ amp_group_free (AmpGroup *node)
     g_slice_free (AmpGroupData, group);
 	if (group->variables) g_hash_table_destroy (group->variables);
 
+	if (group->monitor) g_object_unref (group->monitor);
+	group->monitor = NULL;
+	
 	g_node_destroy (node);
 }
 
@@ -1122,6 +1173,7 @@ monitor_cb (GFileMonitor *monitor,
 		case G_FILE_MONITOR_EVENT_DELETED:
 			/* monitor will be removed here... is this safe? */
 			//amp_project_reload (project, NULL);
+			g_message ("project updated");
 			g_signal_emit_by_name (G_OBJECT (project), "project-updated");
 			break;
 		default:
@@ -1157,7 +1209,7 @@ monitor_add (AmpProject *project, GFile *file)
 			{
 				g_signal_connect (G_OBJECT (monitor),
 						  "changed",
-						  G_CALLBACK (monitor_cb),
+						  G_CALLBACK (on_group_monitor_changed),
 						  project);
 				g_hash_table_insert (project->monitors,
 						     g_object_ref (file),
@@ -2203,7 +2255,7 @@ amp_project_load_root (AmpProject *project, AnjutaProjectNode *node, GError **er
 			return NULL;
 	}
 
-	monitors_setup (project);
+//	monitors_setup (project);
 
 	/* Load all makefiles recursively */
 	if (project_load_makefile (project, project->root_file, node, FALSE) == NULL)
diff --git a/plugins/project-manager/Makefile.am b/plugins/project-manager/Makefile.am
index 4f7f513..3cdc002 100644
--- a/plugins/project-manager/Makefile.am
+++ b/plugins/project-manager/Makefile.am
@@ -22,6 +22,20 @@ plugin_in_files = anjuta-project-manager.plugin.in
 project_plugindir = $(anjuta_plugin_dir)
 project_plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
+# Additional marshaller
+project-marshal.h: project-marshal.list
+	$(AM_V_GEN)@GLIB_GENMARSHAL@ \
+	        --prefix=pm_cclosure_marshal $(srcdir)/project-marshal.list --header > xgen-gmc \
+	&& cp xgen-gmc $(@F) \
+	&& rm -f xgen-gmc
+
+project-marshal.c: project-marshal.h project-marshal.list
+	$(AM_V_GEN)echo "#include \"project-marshal.h\"" > xgenc-gmc \
+	&& @GLIB_GENMARSHAL@ \
+	        --prefix=pm_cclosure_marshal $(srcdir)/project-marshal.list --body >> xgenc-gmc \
+	&& cp xgenc-gmc $(@F) \
+	&& rm -f xgenc-gmc
+
 # Include paths
 AM_CPPFLAGS = \
 	$(WARN_CFLAGS) \
@@ -36,6 +50,8 @@ plugindir = $(anjuta_plugin_dir)
 plugin_LTLIBRARIES = libanjuta-project-manager.la
 
 # Plugin sources
+BUILT_SOURCES = project-marshal.c project-marshal.h
+
 libanjuta_project_manager_la_SOURCES = \
 	plugin.c \
 	plugin.h \
@@ -52,7 +68,8 @@ libanjuta_project_manager_la_SOURCES = \
 	project.h		\
 	project.c		\
 	dialogs.c		\
-	dialogs.h
+	dialogs.h		\
+	$(BUILT_SOURCES)
 
 libanjuta_project_manager_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 
@@ -65,7 +82,8 @@ EXTRA_DIST = \
 	$(project_plugin_DATA) \
 	$(project_ui_DATA) \
 	$(project_pixmaps_DATA) \
-	$(project_glade_DATA)
+	$(project_glade_DATA) \
+	project-marshal.list
 
 DISTCLEANFILES = \
 	$(project_plugin_DATA) \
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 538a9ef..e43d725 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1244,7 +1244,23 @@ value_removed_current_editor (AnjutaPlugin *plugin,
 }
 
 static void
-on_project_updated (AnjutaPmProject *project, GError *error, ProjectManagerPlugin *plugin)
+add_primary_target (AnjutaProjectNode *node, gpointer data)
+{
+	GList ** list = (GList **)data;
+
+	if (anjuta_project_node_get_full_type (node) & ANJUTA_PROJECT_PRIMARY)
+	{
+		gchar *path;
+		
+		path = g_file_get_path (anjuta_project_node_get_file (node));
+		
+		*list = g_list_prepend (*list, g_strconcat ("C ", path, NULL));
+		g_free (path);
+	}
+}
+
+static void
+on_project_updated (AnjutaPmProject *project, AnjutaProjectNode *node, GError *error, ProjectManagerPlugin *plugin)
 {
 	AnjutaStatus *status;
 	gchar *dirname;
@@ -1252,9 +1268,9 @@ on_project_updated (AnjutaPmProject *project, GError *error, ProjectManagerPlugi
 	dirname = anjuta_util_get_local_path_from_uri (plugin->project_root_uri);
 	if (!error)
 	{
-		/* Restore existing shortcut */
 		if (plugin->shortcuts != NULL)
 		{
+			/* Restore existing shortcut */
 			GList *item;
 			
 			gbf_project_view_set_shortcut_list (GBF_PROJECT_VIEW (plugin->view), plugin->shortcuts);
@@ -1275,12 +1291,26 @@ on_project_updated (AnjutaPmProject *project, GError *error, ProjectManagerPlugi
 				}
 			}
 		}
+		else
+		{
+			GList *list = NULL;
+			
+			/* Add new shortcut for PRIMARY target */
+			anjuta_project_node_all_foreach (node, add_primary_target, &list);
+
+			if (list != NULL)
+			{
+				list = g_list_reverse (list);
+				gbf_project_view_set_shortcut_list (GBF_PROJECT_VIEW (plugin->view), list);
+				g_list_free (list);
+			}
+		}
 	}
 	g_free (dirname);
 }
 
 static void
-on_project_loaded (AnjutaPmProject *project, GError *error, ProjectManagerPlugin *plugin)
+on_project_loaded (AnjutaPmProject *project, AnjutaProjectNode *node, GError *error, ProjectManagerPlugin *plugin)
 {
 	AnjutaStatus *status;
 	gchar *dirname;
@@ -1310,21 +1340,29 @@ on_project_loaded (AnjutaPmProject *project, GError *error, ProjectManagerPlugin
 			GList *item;
 			
 			gbf_project_view_set_shortcut_list (GBF_PROJECT_VIEW (plugin->view), plugin->shortcuts);
-			/* Remove used shortcuts */
+			/* Remove all shortcuts, as the project is completely loaded */
 			for (item = g_list_first (plugin->shortcuts); item != NULL;)
 			{
-				if (*((char *)item->data) == 'U')
-				{
-					GList *next = g_list_next (item);
+				GList *next = g_list_next (item);
 					
-					g_free (item->data);
-					plugin->shortcuts = g_list_remove_link (plugin->shortcuts, item);
-					item = next;
-				}
-				else
-				{
-					item = g_list_next (item);
-				}
+				g_free (item->data);
+				plugin->shortcuts = g_list_remove_link (plugin->shortcuts, item);
+				item = next;
+			}
+		}
+		else
+		{
+			GList *list = NULL;
+			
+			/* Add new shortcut for PRIMARY target */
+			anjuta_project_node_all_foreach (node, add_primary_target, &list);
+
+			if (list != NULL)
+			{
+				list = g_list_reverse (list);
+				gbf_project_view_set_shortcut_list (GBF_PROJECT_VIEW (plugin->view), list);
+				g_list_foreach (list, (GFunc)g_free, NULL);
+				g_list_free (list);
 			}
 		}
 		gchar *basename = g_path_get_basename (dirname);
diff --git a/plugins/project-manager/project-model.c b/plugins/project-manager/project-model.c
index c92119f..f70ac08 100644
--- a/plugins/project-manager/project-model.c
+++ b/plugins/project-manager/project-model.c
@@ -261,8 +261,9 @@ gbf_project_model_instance_init (GbfProjectModel *model)
 
 /* Model data functions ------------ */
 
-gboolean
-gbf_project_model_remove (GbfProjectModel *model, GtkTreeIter *iter)
+/* Remove node without checking its shortcuts */
+static gboolean
+gbf_project_model_remove_children (GbfProjectModel *model, GtkTreeIter *iter)
 {
 	GtkTreeIter child;
 	GbfTreeData *data;
@@ -272,12 +273,108 @@ gbf_project_model_remove (GbfProjectModel *model, GtkTreeIter *iter)
 	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter);
 	while (valid)
 	{
-		valid = gbf_project_model_remove (model, &child);
+		valid = gbf_project_model_remove_children (model, &child);
+		
+		/* Free children node */
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
+		   	 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+		    	-1);
+		valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
+		if (data != NULL) gbf_tree_data_free (data);
 	}
-	
+
+	return valid;
+}
+
+static gboolean
+gbf_project_model_invalidate_children (GbfProjectModel *model, GtkTreeIter *iter)
+{
+	GtkTreeIter child;
+	GbfTreeData *data;
+	gboolean valid;
+
+	/* Mark all children as invalid */
+	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter);
+	while (valid)
+	{
+		valid = gbf_project_model_invalidate_children (model, &child);
+		
+		/* Invalidate children node */
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
+		   	 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+		    	-1);
+		gbf_tree_data_invalidate (data);
+
+		valid = gtk_tree_model_iter_next (model, &child);
+	}
+
+	return valid;
+}
+
+static gboolean
+gbf_project_model_remove_invalid_shortcut (GbfProjectModel *model, GtkTreeIter *iter)
+{
+	GtkTreeIter child;
+	gboolean valid;
+	GbfTreeData *data;
+
+	g_message ("remove_invalid_shortcut %p", iter);
+	/* Get all shortcut */
+	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter);
+	while (valid)
+	{
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
+	   		 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+	    		-1);
+		/* Shortcuts are always at the beginning */
+		if (data->type != GBF_TREE_NODE_SHORTCUT) break;
+		
+		if (data->shortcut->type == GBF_TREE_NODE_INVALID)
+		{
+			g_message ("remove shortcut %p", data);
+			gbf_project_model_remove_children (model, &child);
+			valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
+			if (data != NULL) gbf_tree_data_free (data);
+		}
+		else
+		{
+			gbf_project_model_remove_invalid_shortcut (model, &child); 
+			valid = gtk_tree_model_iter_next (model, &child);
+		}
+	}
+		
+	return FALSE;
+}
+
+gboolean
+gbf_project_model_remove (GbfProjectModel *model, GtkTreeIter *iter)
+{
+	GtkTreeIter child;
+	GbfTreeData *data;
+	gboolean valid;
+
+	/* Check if node is not a shortcut. In this case we need to remove
+	 * all shortcuts first. */
 	gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 		    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 		    -1);
+	if (data->type != GBF_TREE_NODE_SHORTCUT)
+	{
+		/* Mark all nodes those will be removed */
+		gbf_project_model_invalidate_children (model, iter);
+		gbf_tree_data_invalidate (data);
+
+		gbf_project_model_remove_invalid_shortcut (model, NULL);
+	}
+	
+	/* Free all children */
+	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter);
+	while (valid)
+	{
+		valid = gbf_project_model_remove_children (model, &child);
+	}
+
+	/* Free parent node */
 	valid = gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
 	if (data != NULL) gbf_tree_data_free (data);
 
@@ -373,6 +470,7 @@ add_source (GbfProjectModel    	      *model,
 	
 	data = gbf_tree_data_new_source (source);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+	g_message ("add source %p", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
@@ -415,10 +513,13 @@ add_target_shortcut (GbfProjectModel *model,
 	{
 		data = target;
 	}
+	g_message ("add target shortcut %p", data);
 	gtk_tree_store_insert_before (GTK_TREE_STORE (model), &iter, NULL, &sibling);
+	//g_message ("insert done %p ", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
+	g_message ("set done %p ", data);
 	
 	/* add sources */
 	parent = anjuta_pm_project_get_node (model->priv->proj, target);
@@ -474,6 +575,7 @@ move_target_shortcut (GbfProjectModel *model,
 	{
 		gtk_tree_store_remove (GTK_TREE_STORE (model), iter);			
 		gtk_tree_store_insert_before (GTK_TREE_STORE (model), iter, NULL, &sibling);
+		g_message ("move_target_shortcut %p", shortcut);
 		gtk_tree_store_set (GTK_TREE_STORE (model), iter, 
 				    GBF_PROJECT_MODEL_COLUMN_DATA, shortcut,
 				    -1);
@@ -503,6 +605,7 @@ add_package (GbfProjectModel    	      *model,
 	
 	data = gbf_tree_data_new_package (package);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+	g_message ("add package %p", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
@@ -528,6 +631,7 @@ add_module (GbfProjectModel 		*model,
 	
 	data = gbf_tree_data_new_module (module);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+	g_message ("add_module %p", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
@@ -553,6 +657,7 @@ add_target (GbfProjectModel 		*model,
 	
 	data = gbf_tree_data_new_target (target);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+	g_message("add_target %p", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
@@ -568,10 +673,10 @@ add_target (GbfProjectModel 		*model,
 	 * set of public functions to add/remove shortcuts to save
 	 * this information in the project metadata (when that's
 	 * implemented) */
-	if (anjuta_project_node_get_full_type (target) & ANJUTA_PROJECT_PRIMARY)
+	/*if (anjuta_project_node_get_full_type (target) & ANJUTA_PROJECT_PRIMARY)
 	{
 		add_target_shortcut (model, NULL, data, NULL);
-	}
+	}*/
 }
 
 static void 
@@ -588,6 +693,7 @@ add_target_group (GbfProjectModel 	*model,
 	
 	data = gbf_tree_data_new_group (group);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+	g_message("add_target_group %p", data);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
@@ -676,6 +782,7 @@ insert_empty_node (GbfProjectModel *model)
 	empty_node = gbf_tree_data_new_string (_("No project loaded"));
 
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+	g_message ("insert_empty_node %p", empty_node);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, empty_node,
 			    -1);
diff --git a/plugins/project-manager/project-view.c b/plugins/project-manager/project-view.c
index 9f3d064..2591fd9 100644
--- a/plugins/project-manager/project-view.c
+++ b/plugins/project-manager/project-view.c
@@ -175,10 +175,15 @@ set_pixbuf (GtkTreeViewColumn *tree_column,
 	
 	gtk_tree_model_get (model, iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+	g_message("set_pixbuf data %p", data);
 	g_return_if_fail (data != NULL);
+	/* FIXME: segmentation fault with shortcut when corresponding
+	 * data is removed before the shortcut, so data = NULL.
+	 * Perhaps we can add a GtkTreeReference to the shortcut
+	 * node to remove the shortcut when the node is destroyed */
 
-	if (data->type == GBF_TREE_NODE_SHORTCUT)
-	{
+	if ((data->type == GBF_TREE_NODE_SHORTCUT) && (data->shortcut != NULL))
+ 	{
 		data = data->shortcut;
 	}
 	switch (data->type) {
@@ -222,6 +227,8 @@ set_pixbuf (GtkTreeViewColumn *tree_column,
 			break;
 		}
 		default:
+			/* Can reach this if type = GBF_TREE_NODE_SHORTCUT. It 
+			 * means a shortcut with the original data removed */
 			pixbuf = NULL;
 	}
 
@@ -240,8 +247,11 @@ set_text (GtkTreeViewColumn *tree_column,
 	GbfTreeData *data;
   
 	gtk_tree_model_get (model, iter, GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+	/* data can be NULL just after gtk_tree_store_insert before
+	calling gtk_tree_store_set */ 
+	g_message ("data is %p", data);
 	g_object_set (GTK_CELL_RENDERER (cell), "text", 
-		      data->name, NULL);
+		      data == NULL ? "" : data->name, NULL);
 }
 
 static gboolean
@@ -574,6 +584,37 @@ gbf_project_view_get_shortcut_list (GbfProjectView *view)
 }
 
 void
+gbf_project_view_remove_all_shortcut (GbfProjectView* view)
+{
+	GtkTreeModel* model;
+	gboolean valid;
+	GtkTreeIter iter;
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+
+	/* Remove all current shortcuts */
+	for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
+		valid == TRUE;)
+	{
+		GbfTreeData *data;
+			
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 
+		    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+	    	-1);
+
+		if (data->type == GBF_TREE_NODE_SHORTCUT)
+		{
+			valid = gbf_project_model_remove (GBF_PROJECT_MODEL (model), &iter);
+		}
+		else
+		{
+			/* No more shortcut */
+			break;
+		}
+	}
+}
+
+void
 gbf_project_view_set_shortcut_list (GbfProjectView *view, GList *shortcuts)
 {
 	GtkTreeModel* model;
@@ -585,26 +626,7 @@ gbf_project_view_set_shortcut_list (GbfProjectView *view, GList *shortcuts)
 		gboolean valid;
 		GtkTreeIter iter;
 		
-		/* Remove all current shortcuts */
-		for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
-			valid == TRUE;)
-		{
-			GbfTreeData *data;
-			
-			gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 
-			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
-		    	-1);
-
-			if (data->type == GBF_TREE_NODE_SHORTCUT)
-			{
-				valid = gbf_project_model_remove (GBF_PROJECT_MODEL (model), &iter);
-			}
-			else
-			{
-				/* No more shortcut, add saved one */
-				break;
-			}
-		}
+		valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
 
 		if (valid)
 		{
diff --git a/plugins/project-manager/project-view.h b/plugins/project-manager/project-view.h
index 107a9a5..54728be 100644
--- a/plugins/project-manager/project-view.h
+++ b/plugins/project-manager/project-view.h
@@ -69,6 +69,7 @@ GList                      *gbf_project_view_get_all_selected  (GbfProjectView *
 GList                      *gbf_project_view_get_all_selected_iter  (GbfProjectView *view);
 
 GList                      *gbf_project_view_get_shortcut_list (GbfProjectView *view);
+void			gbf_project_view_remove_all_shortcut (GbfProjectView* view);
 void                        gbf_project_view_set_shortcut_list (GbfProjectView *view,
                                                                  GList          *shortcuts);
 
diff --git a/plugins/project-manager/project.c b/plugins/project-manager/project.c
index 153550a..779bf6d 100644
--- a/plugins/project-manager/project.c
+++ b/plugins/project-manager/project.c
@@ -24,7 +24,7 @@
 #endif
 
 #include "project.h"
-#include <libanjuta/anjuta-marshal.h>
+#include "project-marshal.h"
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-error.h>
 #include <libanjuta/interfaces/ianjuta-project-backend.h>
@@ -485,10 +485,11 @@ pm_command_load_complete (AnjutaPmProject *project, PmJob *job)
 	anjuta_project_proxy_exchange_data (job->proxy, job->node);
 	anjuta_project_node_exchange (job->proxy, job->node);
 
+	g_message ("pm_command_load_complete");
 	if (job->error != NULL)
 	{
 		g_warning ("unable to load node");
-		g_signal_emit (G_OBJECT (project), signals[job->command == LOAD ? LOADED : UPDATED], 0, job->error);
+		g_signal_emit (G_OBJECT (project), signals[job->command == LOAD ? LOADED : UPDATED], 0, job->node, job->error);
 	}
 	else
 	{
@@ -524,10 +525,15 @@ pm_command_load_complete (AnjutaPmProject *project, PmJob *job)
 		}
 		anjuta_project_node_clear_state (job->node, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
 		anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
-		
-		if (project->incomplete_node == 0)
+
+		g_message ("emit node %p", job->node);
+		if (load && (project->incomplete_node == 0))
 		{
-			g_signal_emit (G_OBJECT (project), signals[load ? LOADED : UPDATED], 0, NULL);
+			g_signal_emit (G_OBJECT (project), signals[LOADED], 0, job->node, NULL);
+		}
+		else
+		{
+			g_signal_emit (G_OBJECT (project), signals[UPDATED], 0, job->node, NULL);
 		}
 		check_queue (project->job_queue, job->map);
 	}
@@ -1122,14 +1128,29 @@ anjuta_pm_project_class_init (AnjutaPmProjectClass *klass)
 	
 	object_class->finalize = anjuta_pm_project_finalize;
 
+
+ 	/*Change both signal to use marshal_VOID__POINTER_BOXED
+	adding a AnjutaProjectNode pointer corresponding to the
+	 loaded node => done
+	 Such marshal doesn't exist as glib marshal, so look in the
+	 symbol db plugin how to add new marshal => done
+	 ToDo :
+	 This new argument can be used in the plugin object in
+	 order to add corresponding shortcut when the project
+	 is loaded and a new node is loaded.
+	 The plugin should probably get the GFile from the
+	 AnjutaProjectNode object and then use a function
+	 in project-view.c to create the corresponding shortcut*/
+	
 	signals[UPDATED] = g_signal_new ("updated",
 	    G_OBJECT_CLASS_TYPE (object_class),
 	    G_SIGNAL_RUN_LAST,
 	    G_STRUCT_OFFSET (AnjutaPmProjectClass, updated),
 	    NULL, NULL,
-	    g_cclosure_marshal_VOID__BOXED,
+	    pm_cclosure_marshal_VOID__POINTER_BOXED,
 	    G_TYPE_NONE,
-	    1,
+	    2,
+	    G_TYPE_POINTER,
 	    G_TYPE_ERROR);
 	
 	signals[LOADED] = g_signal_new ("loaded",
@@ -1137,9 +1158,10 @@ anjuta_pm_project_class_init (AnjutaPmProjectClass *klass)
 		G_SIGNAL_RUN_LAST,
 		G_STRUCT_OFFSET (AnjutaPmProjectClass, loaded),
 		NULL, NULL,
-		g_cclosure_marshal_VOID__BOXED,
+		pm_cclosure_marshal_VOID__POINTER_BOXED,
 		G_TYPE_NONE,
-		1,
+		2,
+	    G_TYPE_POINTER,
 		G_TYPE_ERROR);
 }
 
diff --git a/plugins/project-manager/tree-data.c b/plugins/project-manager/tree-data.c
index 297fc21..8394da2 100644
--- a/plugins/project-manager/tree-data.c
+++ b/plugins/project-manager/tree-data.c
@@ -224,6 +224,12 @@ gbf_tree_data_equal_file (GbfTreeData *data, AnjutaProjectNodeType type, GFile *
 	return equal;
 }
 
+void
+gbf_tree_data_invalidate (GbfTreeData *data)
+{
+	data->type = GBF_TREE_NODE_INVALID;
+}
+
 GbfTreeData *
 gbf_tree_data_new_string (const gchar *string)
 {
@@ -248,7 +254,7 @@ gbf_tree_data_new_shortcut (GbfTreeData *src)
 	data->source = src->source == NULL ? NULL : g_object_ref (src->source);
 	data->is_shortcut = TRUE;
 	data->shortcut = src;
-	src->shortcut = data;
+	//src->shortcut = data;
 	
 	return data;
 }
@@ -375,7 +381,7 @@ gbf_tree_data_free (GbfTreeData *data)
 		if (data->group != NULL) g_object_unref (data->group);
 		g_free (data->target);
 		if (data->source != NULL) g_object_unref (data->source);
-		if (data->shortcut) data->shortcut->shortcut = NULL;
+		//if (data->shortcut) data->shortcut->shortcut = NULL;
 		if (data->properties_dialog) gtk_widget_destroy (data->properties_dialog);
 		g_slice_free (GbfTreeData, data);
 	}
diff --git a/plugins/project-manager/tree-data.h b/plugins/project-manager/tree-data.h
index 0c23b56..415aecf 100644
--- a/plugins/project-manager/tree-data.h
+++ b/plugins/project-manager/tree-data.h
@@ -39,7 +39,8 @@ typedef enum {
 	GBF_TREE_NODE_PACKAGE,
 	GBF_TREE_NODE_SOURCE,
 	GBF_TREE_NODE_ROOT,
-	GBF_TREE_NODE_SHORTCUT
+	GBF_TREE_NODE_SHORTCUT,
+	GBF_TREE_NODE_INVALID
 } GbfTreeNodeType;
 
 struct _GbfTreeData
@@ -77,6 +78,7 @@ GbfTreeData   *gbf_tree_data_new_target         (AnjutaProjectNode     *target);
 GbfTreeData   *gbf_tree_data_new_source         (AnjutaProjectNode     *source);
 GbfTreeData   *gbf_tree_data_new_module         (AnjutaProjectNode     *module);
 GbfTreeData   *gbf_tree_data_new_package        (AnjutaProjectNode     *package);
+void				gbf_tree_data_invalidate (GbfTreeData *data);
 void           gbf_tree_data_free               (GbfTreeData           *data);
 
 



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