[anjuta/newproject] Reload directory with dir project backend



commit f7d3bd58c3d173d65cc0fe0ec547d19259559d0d
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sun May 2 12:58:24 2010 +0200

    Reload directory with dir project backend

 libanjuta/anjuta-project.c              |   26 ++++-
 libanjuta/anjuta-project.h              |    1 +
 plugins/dir-project/dir-project.c       |   75 ++++++++----
 plugins/project-manager/plugin.c        |    2 +-
 plugins/project-manager/project-model.c |   95 ++++++++++++----
 plugins/project-manager/project-model.h |    9 +-
 plugins/project-manager/project-view.c  |    2 +-
 plugins/project-manager/project.c       |  196 ++++++++++++++++++++++++++++---
 plugins/project-manager/tree-data.c     |   11 ++
 plugins/project-manager/tree-data.h     |    2 +
 10 files changed, 349 insertions(+), 70 deletions(-)
---
diff --git a/libanjuta/anjuta-project.c b/libanjuta/anjuta-project.c
index 3013478..a2549b2 100644
--- a/libanjuta/anjuta-project.c
+++ b/libanjuta/anjuta-project.c
@@ -289,6 +289,18 @@ anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *
 }
 
 AnjutaProjectNode *
+anjuta_project_node_replace (AnjutaProjectNode *node, AnjutaProjectNode *replacement)
+{
+	if (node->parent != NULL)
+	{
+		g_node_insert_after (node->parent, node, replacement);
+		g_node_unlink (node);
+	}
+	
+	return replacement;
+}
+
+AnjutaProjectNode *
 anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node)
 {
 	return g_node_prepend (parent, node);
@@ -386,7 +398,7 @@ anjuta_project_node_get_file (AnjutaProjectNode *node)
 		AnjutaProjectNode *parent;
 
 		parent = anjuta_project_node_parent (node);
-		if (NODE_DATA (parent)->file != NULL)
+		if ((parent != NULL) && (NODE_DATA (parent)->file != NULL))
 		{
 			data->file = g_file_get_child (NODE_DATA (parent)->file, data->name);
 		}
@@ -706,10 +718,15 @@ anjuta_project_proxy_new (AnjutaProjectNode *node)
 		AnjutaProjectProxyData *proxy;
 		AnjutaProjectNodeData *data = NODE_DATA (node);
 
+		/* Create proxy node */
 		proxy = g_slice_new0(AnjutaProjectProxyData);
 		proxy->reference = 1;
 		proxy->node = node;
 		proxy->base.type = data->type | ANJUTA_PROJECT_PROXY;
+		proxy->base.file = g_object_ref (data->file);
+		proxy->base.name = g_strdup (data->name);
+		
+		/* Shallow copy of all properties */
 		if ((data->properties == NULL) || (((AnjutaProjectPropertyInfo *)data->properties->data)->override == NULL))
 		{
 			proxy->base.properties = data->properties;
@@ -731,9 +748,10 @@ anjuta_project_proxy_new (AnjutaProjectNode *node)
 				item->data = new_info;
 			}
 		}
-		proxy->base.file = g_object_ref (data->file);
-		proxy->base.name = g_strdup (data->name);
-		node = g_node_new (proxy);
+		
+		/* Replace node */
+		node->data = proxy;
+		node = anjuta_project_node_replace (node, g_node_new (data));
 	}
 
 	return node;
diff --git a/libanjuta/anjuta-project.h b/libanjuta/anjuta-project.h
index 1fcca83..8d5b1e9 100644
--- a/libanjuta/anjuta-project.h
+++ b/libanjuta/anjuta-project.h
@@ -166,6 +166,7 @@ AnjutaProjectNode *anjuta_project_node_append (AnjutaProjectNode *parent, Anjuta
 AnjutaProjectNode *anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
 AnjutaProjectNode *anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node);
+AnjutaProjectNode *anjuta_project_node_replace (AnjutaProjectNode *node, AnjutaProjectNode *replacement);
 
 void anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
 void anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
diff --git a/plugins/dir-project/dir-project.c b/plugins/dir-project/dir-project.c
index 5b86260..847117b 100644
--- a/plugins/dir-project/dir-project.c
+++ b/plugins/dir-project/dir-project.c
@@ -49,8 +49,6 @@ struct _DirProject {
 
 	GFile			*root_file;
 
-	AnjutaProjectNode        *root_node;
-	
 	/* shortcut hash tables, mapping id -> GNode from the tree above */
 	GHashTable		*groups;
 	
@@ -62,7 +60,7 @@ struct _DirProject {
 };
 
 /* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
-#define DIR_NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
+#define NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
 #define DIR_GROUP_DATA(node)  ((node) != NULL ? (DirGroupData *)((node)->data) : NULL)
 #define DIR_TARGET_DATA(node)  ((node) != NULL ? (DirTargetData *)((node)->data) : NULL)
 #define DIR_SOURCE_DATA(node)  ((node) != NULL ? (DirSourceData *)((node)->data) : NULL)
@@ -261,7 +259,7 @@ dir_root_new (GFile *file)
 static void
 dir_root_free (AnjutaProjectNode *node)
 {
-	AnjutaProjectNodeData *data = DIR_NODE_DATA (node);
+	AnjutaProjectNodeData *data = NODE_DATA (node);
 	
 	if (data->file != NULL) g_object_unref (data->file);
 	g_free (data->name);
@@ -283,6 +281,8 @@ dir_group_new (GFile *file)
 	group = g_slice_new0(DirGroupData); 
 	group->base.type = ANJUTA_PROJECT_GROUP;
 	group->base.file = g_object_ref (file);
+	group->base.state = ANJUTA_PROJECT_CAN_ADD_GROUP |
+						ANJUTA_PROJECT_CAN_REMOVE;
 
     return g_node_new (group);
 }
@@ -340,21 +340,25 @@ dir_source_free (DirSource *node)
 
 
 static void
-foreach_node_destroy (AnjutaProjectNode    *g_node,
+foreach_node_destroy (AnjutaProjectNode *node,
 		      gpointer  data)
 {
-	switch (DIR_NODE_DATA (g_node)->type) {
+	gint type = NODE_DATA (node)->type;
+	
+	g_message ("dir free node %p", node);
+	switch (type & ANJUTA_PROJECT_TYPE_MASK)
+	{
 		case ANJUTA_PROJECT_GROUP:
-			dir_group_free (g_node);
+			dir_group_free (node);
 			break;
 		case ANJUTA_PROJECT_TARGET:
-			dir_target_free (g_node);
+			dir_target_free (node);
 			break;
 		case ANJUTA_PROJECT_SOURCE:
-			dir_source_free (g_node);
+			dir_source_free (node);
 			break;
 		case ANJUTA_PROJECT_ROOT:
-			dir_root_free (g_node);
+			dir_root_free (node);
 			break;
 		default:
 			g_assert_not_reached ();
@@ -394,8 +398,9 @@ project_node_new (DirProject *project, AnjutaProjectNodeType type, GFile *file,
 			g_assert_not_reached ();
 			break;
 	}
-	if (node != NULL) DIR_NODE_DATA (node)->type = type;
-
+	if (node != NULL) NODE_DATA (node)->type = type;
+	g_message ("dir new node %p type %x", node, type);
+	
 	return node;
 }
 
@@ -711,7 +716,7 @@ dir_project_list_directory (DirProject *project, DirGroup* parent, GError **erro
 				/* Create a group for directory */
 				DirGroup *group;
 				
-				group = dir_group_new (file);
+				group = project_node_new (project, ANJUTA_PROJECT_GROUP, file, NULL);
 				g_hash_table_insert (project->groups, g_file_get_uri (file), group);
 				anjuta_project_node_append (parent, group);
 				ok = dir_project_list_directory (project, group, error);
@@ -722,7 +727,7 @@ dir_project_list_directory (DirProject *project, DirGroup* parent, GError **erro
 				/* Create a source for files */
 				DirSource *source;
 
-				source = dir_source_new (file);
+				source = project_node_new (project, ANJUTA_PROJECT_SOURCE, file, NULL);
 				anjuta_project_node_append (parent, source);
 			}
 		}
@@ -743,12 +748,10 @@ dir_project_load_root (DirProject *project, AnjutaProjectNode *node, GError **er
 	GFile *source_file;
 	DirGroup *group;
 
-	/* Unload current project */
-	dir_project_unload (project);
-	DEBUG_PRINT ("reload project %p root file %p", project, root_file);
 	root_file = g_object_ref (anjuta_project_node_get_file (node));
+	DEBUG_PRINT ("reload project %p root file %p", project, root_file);
 	project->root_file = root_file;
-	project->root_node = node;
+	//project->root_node = node;
 
 	/* shortcut hash tables */
 	project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -762,7 +765,7 @@ dir_project_load_root (DirProject *project, AnjutaProjectNode *node, GError **er
 		return NULL;
 	}
 
-	group = dir_group_new (root_file);
+	group = project_node_new (project, ANJUTA_PROJECT_GROUP, root_file, NULL);
 	anjuta_project_node_append (node, group);
 	g_hash_table_insert (project->groups, g_file_get_uri (root_file), group);
 
@@ -813,8 +816,8 @@ dir_project_unload (DirProject *project)
 	monitors_remove (project);
 	
 	/* project data */
-	project_node_destroy (project, project->root_node);
-	project->root_node = NULL;
+	/*project_node_destroy (project, project->root_node);
+	project->root_node = NULL;*/
 
 	if (project->root_file) g_object_unref (project->root_file);
 	project->root_file = NULL;
@@ -908,7 +911,7 @@ dir_project_get_node_info (DirProject *project, GError **error)
 static DirGroup *
 dir_project_get_root (DirProject *project)
 {
-	return project->root_node;
+	return NULL;
 }
 
 
@@ -1010,9 +1013,31 @@ iproject_add_file_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaPr
 }
 
 static AnjutaProjectNode *
-iproject_add_name_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNodeType type, const gchar *name, GError **err)
+iproject_add_name_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNodeType type, const gchar *name, GError **error)
 {
-	return NULL;
+	AnjutaProjectNode *node = NULL;
+	GFile *file;
+	
+	/* Create a group for directory */
+	switch (type & ANJUTA_PROJECT_TYPE_MASK)
+	{
+	case ANJUTA_PROJECT_GROUP:
+		file = g_file_get_child (anjuta_project_node_get_file (parent), name);
+		if (g_file_make_directory (file, NULL, error))
+		{
+			node = project_node_new (DIR_PROJECT (obj), type, file, NULL);
+			anjuta_project_node_append (parent, node);
+		}
+		g_object_unref (file);
+		break;
+	default:
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+					IANJUTA_PROJECT_ERROR_NOT_SUPPORTED,
+			_("Project doesn't allow to add such type of element"));
+		break;
+	}
+	
+	return node;
 }
 
 static gboolean
@@ -1100,7 +1125,7 @@ dir_project_instance_init (DirProject *project)
 	
 	/* project data */
 	project->root_file = NULL;
-	project->root_node = NULL;
+	//project->root_node = NULL;
 
 	project->monitors = NULL;
 	project->groups = NULL;
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 5237bf9..e76c3b2 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1876,7 +1876,7 @@ get_tree_iter_from_file (ProjectManagerPlugin *plugin, GtkTreeIter* iter, GFile
 {
 	gboolean found;
 	
-	found = gbf_project_model_find_tree_file (anjuta_pm_project_get_model (plugin->project), iter, NULL, type, file);
+	found = gbf_project_model_find_file (anjuta_pm_project_get_model (plugin->project), iter, NULL, type, file);
 
 	return found ? iter : NULL;
 }
diff --git a/plugins/project-manager/project-model.c b/plugins/project-manager/project-model.c
index 6a650ea..9ef94a7 100644
--- a/plugins/project-manager/project-model.c
+++ b/plugins/project-manager/project-model.c
@@ -644,7 +644,7 @@ add_root (GbfProjectModel 	*model,
 static void
 project_updated_cb (IAnjutaProject *project, GbfProjectModel *model)
 {
-	gbf_project_model_update_tree (model, NULL, NULL);
+	gbf_project_model_update_tree (model, NULL, NULL, NULL);
 }
 
 static void
@@ -737,52 +737,67 @@ recursive_find_tree_data (GtkTreeModel  *model,
 }
 
 void
-gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *iter)
+gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *iter, GHashTable *map)
 {
 	GtkTreeIter child;
 	GList *node;
 	GList *nodes;
 
-	/* group can be NULL, but we iterate anyway to remove any
-	 * shortcuts the old group could have had */
+	/* Update parent */
+	if (iter != NULL)
+	{
+		GbfTreeData *data = NULL;
+
+		gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
+				GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+				-1);
+		gbf_tree_data_replace_node (data, parent);
+	}
 	
 	/* Get all new nodes */
 	nodes = gbf_project_util_all_child (parent, ANJUTA_PROJECT_UNKNOWN);
+	g_message ("gbf_project_model_update_tree %p", nodes);
 
 	/* walk the tree nodes */
-	if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter)) {
+	if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter))
+	{
 		gboolean valid = TRUE;
 		
 		while (valid) {
-			AnjutaProjectNode* data;
-			GbfTreeData *tree_data = NULL;
-
-			/* Get tree data */
-			gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
-			    GBF_PROJECT_MODEL_COLUMN_DATA, &tree_data,
-			    -1);
+			GbfTreeData *data = NULL;
+			AnjutaProjectNode* new_node = NULL;
 
-			data = gbf_project_model_get_node (model, &child);
+			if (map != NULL)
+			{
+				/* Look for old node */
+				AnjutaProjectNode* old_node;
+				
+				gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
+					GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+					-1);
 
-			if (data != NULL)
+				old_node = gbf_tree_data_get_node (data);
+				new_node = g_hash_table_lookup (map, old_node);
+			}
+			
+			if (new_node != NULL)
 			{
 				/* Remove from the new node list */
-				node = g_list_find (nodes, data);
+				node = g_list_find (nodes, new_node);
 				if (node != NULL)
 				{
 					nodes = g_list_delete_link (nodes, node);
 				}
-
+				gbf_tree_data_replace_node (data, new_node);
+				
 				/* update recursively */
-				gbf_project_model_update_tree (model, data, &child);
+				gbf_project_model_update_tree (model, new_node, &child, map);
 				
 				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
 			}
 			else
 			{
 				/* update recursively */
-				gbf_project_model_update_tree (model, data, &child);
-				
 				valid = gbf_project_model_remove (model, &child);
 			}
 		}
@@ -791,9 +806,11 @@ gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent
 	/* add the remaining sources, targets and groups */
 	for (node = nodes; node; node = node->next)
 	{
+		//g_message ("Add node %p type %x", node->data, anjuta_project_node_get_type (node->data));
 		switch (anjuta_project_node_get_type (node->data))
 		{
 		case ANJUTA_PROJECT_GROUP:
+			//g_message ("Add group %p name %s", anjuta_project_node_get_name (node));
 			add_target_group (model, node->data, iter);
 			break;
 		case ANJUTA_PROJECT_TARGET:
@@ -836,7 +853,7 @@ gbf_project_model_find_tree_data (GbfProjectModel 	*model,
 }
 
 gboolean 
-gbf_project_model_find_tree_file (GbfProjectModel 	*model,
+gbf_project_model_find_file (GbfProjectModel 	*model,
     GtkTreeIter		*found,
     GtkTreeIter		*parent,
     AnjutaProjectNodeType type,
@@ -865,7 +882,43 @@ gbf_project_model_find_tree_file (GbfProjectModel 	*model,
 	{
 		for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent); valid == TRUE; valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
 		{
-			if (gbf_project_model_find_tree_file (model, found, &iter, type, file)) return TRUE;
+			if (gbf_project_model_find_file (model, found, &iter, type, file)) break;
+		}
+	}
+
+	return valid;
+}
+
+gboolean 
+gbf_project_model_find_node (GbfProjectModel 	*model,
+    GtkTreeIter		*found,
+    GtkTreeIter		*parent,
+    AnjutaProjectNode	*node)
+{
+	GtkTreeIter iter;
+	gboolean valid;
+
+	/* Search for direct children */
+	for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent); valid == TRUE; valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
+	{
+		GbfTreeData *data;
+		
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+			GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+
+		if (node == gbf_tree_data_get_node (data))
+		{
+			*found = iter;
+			break;
+		}
+	}
+
+	/* Search for children of children */
+	if (!valid)
+	{
+		for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent); valid == TRUE; valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
+		{
+			if (gbf_project_model_find_node (model, found, &iter, node)) break;
 		}
 	}
 
diff --git a/plugins/project-manager/project-model.h b/plugins/project-manager/project-model.h
index 76434c3..e16cb68 100644
--- a/plugins/project-manager/project-model.h
+++ b/plugins/project-manager/project-model.h
@@ -67,11 +67,15 @@ gboolean         gbf_project_model_remove            (GbfProjectModel *model,
 gboolean         gbf_project_model_find_tree_data    (GbfProjectModel   *model,
                                                       GtkTreeIter       *iter,
                                                       GbfTreeData       *data);
-gboolean         gbf_project_model_find_tree_file    (GbfProjectModel   *model,
+gboolean         gbf_project_model_find_file         (GbfProjectModel   *model,
                                                       GtkTreeIter       *iter,
                                                       GtkTreeIter       *parent,
                                                       AnjutaProjectNodeType type,
                                                       GFile             *file);
+gboolean         gbf_project_model_find_node         (GbfProjectModel   *model,
+                                                      GtkTreeIter       *iter,
+                                                      GtkTreeIter       *parent,
+                                                      AnjutaProjectNode *node);
 AnjutaProjectNode *gbf_project_model_get_node        (GbfProjectModel *model,
                                                       GtkTreeIter     *iter);
 
@@ -82,7 +86,8 @@ void             gbf_project_model_add_shortcut      (GbfProjectModel *model,
 
 void            gbf_project_model_update_tree (GbfProjectModel *model,
                                                     AnjutaProjectNode *parent,
-                                                    GtkTreeIter *iter);
+                                                    GtkTreeIter *iter,
+                                                    GHashTable *map);
 
 
 #endif
diff --git a/plugins/project-manager/project-view.c b/plugins/project-manager/project-view.c
index 58eddce..9f3d064 100644
--- a/plugins/project-manager/project-view.c
+++ b/plugins/project-manager/project-view.c
@@ -629,7 +629,7 @@ gbf_project_view_set_shortcut_list (GbfProjectView *view, GList *shortcuts)
 				}
 				file = g_file_new_for_path (path);
 
-				if (gbf_project_model_find_tree_file  (GBF_PROJECT_MODEL (model), &shortcut, NULL, ANJUTA_PROJECT_UNKNOWN, file))
+				if (gbf_project_model_find_file  (GBF_PROJECT_MODEL (model), &shortcut, NULL, ANJUTA_PROJECT_UNKNOWN, file))
 				{
 					GbfTreeData *data;
 
diff --git a/plugins/project-manager/project.c b/plugins/project-manager/project.c
index 4d0402f..9f1fece 100644
--- a/plugins/project-manager/project.c
+++ b/plugins/project-manager/project.c
@@ -103,6 +103,7 @@ typedef enum
 	LOAD,
 	UNLOAD,
 	RELOAD,
+	RELOAD_NODE,
 	EXIT
 } PmCommand;
 
@@ -118,7 +119,8 @@ struct _PmJob
 	AnjutaProjectNode *node;
 	PmJobCallback callback;
 	GError *error;
-	AnjutaProjectNode *new_node;
+	AnjutaProjectNode *proxy;
+	GHashTable *map;
 };
 
 /* Signal
@@ -145,18 +147,45 @@ pm_job_new (PmCommand command, GFile *file, const gchar *name, AnjutaProjectNode
 	job->command = command;
 	job->file = file != NULL ? g_object_ref (file) : NULL;
 	job->name = name != NULL ? g_strdup (name) : NULL;
-	job->node = node;
+	if (node != NULL)
+	{
+		job->node = node;
+		job->proxy = anjuta_project_proxy_new (node);
+		g_message ("node %p proxy %p", job->node, job->proxy);
+	}
 	job->callback = callback;
 
 	return job;
 }
 
 static void
-pm_job_free (PmJob *job)
+pm_free_node (AnjutaProjectNode *node, IAnjutaProject *project)
+{
+	gint type = anjuta_project_node_get_full_type (node);
+	
+	if (type & ANJUTA_PROJECT_PROXY)
+	{
+		g_message ("free proxy %p", node);
+		anjuta_project_proxy_unref (node);
+	}
+	else
+	{
+		ianjuta_project_remove_node (project, node, NULL);
+	}
+}
+
+static void
+pm_job_free (PmJob *job, IAnjutaProject *project)
 {
 	if (job->file != NULL) g_object_unref (job->file);
 	if (job->name != NULL) g_free (job->name);
 	if (job->error != NULL) g_error_free (job->error);
+	if ((job->proxy != NULL) && (job->node != NULL))
+	{
+		g_message ("free proxy %p", job->node);
+		anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)pm_free_node, project);
+	}
+	if (job->map != NULL) g_hash_table_destroy (job->map);
 }
 
 static void
@@ -180,6 +209,78 @@ pm_project_push_command (AnjutaPmProject *project, PmCommand command, GFile *fil
 /* Thread functions
  *---------------------------------------------------------------------------*/
 
+static gint
+pm_project_compare_node (AnjutaProjectNode *old_node, AnjutaProjectNode *new_node)
+{
+	gchar *name1;
+	gchar *name2;
+	GFile *file1;
+	GFile *file2;
+
+	name1 = anjuta_project_node_get_name (old_node);
+	name2 = anjuta_project_node_get_name (new_node);
+	file1 = anjuta_project_node_get_file (old_node);
+	file2 = anjuta_project_node_get_file (new_node);
+
+	return (anjuta_project_node_get_type (old_node) == anjuta_project_node_get_type (new_node))
+		&& ((name1 == NULL) || (name2 == NULL) || (strcmp (name1, name2) == 0))
+		&& ((file1 == NULL) || (file2 == NULL) || g_file_equal (file1, file2)) ? 0 : 1;
+}
+
+static void
+pm_project_map_children (PmJob *job, AnjutaProjectNode *old_node, AnjutaProjectNode *new_node)
+{
+	GList *children = NULL;
+
+	for (new_node = anjuta_project_node_first_child (new_node); new_node != NULL; new_node = anjuta_project_node_next_sibling (new_node))
+	{
+		children = g_list_prepend (children, new_node);
+		g_message ("prepend %p", new_node);
+	}
+	children = g_list_reverse (children);
+
+	for (old_node = anjuta_project_node_first_child (old_node); old_node != NULL; old_node = anjuta_project_node_next_sibling (old_node))
+	{
+		GList *same;
+
+		same = g_list_find_custom (children, old_node, (GCompareFunc)pm_project_compare_node);
+		g_message ("find %p get %p", old_node, same->data);
+		
+		if (same != NULL)
+		{
+			g_hash_table_insert (job->map, old_node, (AnjutaProjectNode *)same->data);
+			g_message ("map %p->%p", old_node, same->data);
+			
+			pm_project_map_children ((PmJob *)job, old_node, (AnjutaProjectNode *)same->data);
+			children = g_list_delete_link (children, same);
+		}
+	}
+	
+	g_list_free (children);
+}
+ 
+static void
+pm_project_map_node (PmJob *job)
+{
+	if ((job->proxy != NULL) && (job->node != NULL))
+	{
+		AnjutaProjectNode *old_node;
+		AnjutaProjectNode *new_node;
+		
+		job->map = g_hash_table_new (g_direct_hash, NULL);
+		old_node = job->node;
+		new_node = job->proxy;
+		
+		if (pm_project_compare_node (old_node, new_node) == 0)
+		{
+			g_hash_table_insert (job->map, old_node, new_node);
+			g_message ("map %p->%p", old_node, new_node);
+			
+			pm_project_map_children (job, old_node, new_node);
+		}
+	}
+}
+ 
 static gpointer
 pm_project_thread_main_loop (AnjutaPmProject *project)
 {
@@ -209,15 +310,28 @@ pm_project_thread_main_loop (AnjutaPmProject *project)
 			break;
 		case RELOAD:
 			node = ianjuta_project_load_node (project->project, job->node, &(job->error));
-			if (job->error == NULL)
+			/*if (job->error == NULL)
 			{
 				job->node = node;
-			}
+			}*/
 			break;						
+		case RELOAD_NODE:
+			g_message ("thread load node %p", job->proxy);
+			node = ianjuta_project_load_node (project->project, job->proxy, &(job->error));
+			g_message ("thread load node complete");
+			if (job->error == NULL)
+			{
+				pm_project_map_node (job);
+			}
+			/*if (job->error == NULL)
+			{
+				job->node = node;
+			}*/
+			break;
 		case EXIT:
 			do
 			{
-				pm_job_free (job);
+				pm_job_free (job, project->project);
 				job = (PmJob *)g_async_queue_try_pop (project->done_queue);
 			}
 			while (job != NULL);
@@ -244,7 +358,7 @@ pm_project_idle_func (AnjutaPmProject *project)
 		{
 			job->callback (project, job);
 		}
-		pm_job_free (job);
+		pm_job_free (job, project->project);
 		project->busy--;
 		if (project->busy == 0)
 		{
@@ -308,14 +422,14 @@ pm_project_stop_thread (AnjutaPmProject *project)
 		// Free queue
 		g_async_queue_unref (project->work_queue);
 		project->work_queue = NULL;
-		g_queue_foreach (project->job_queue, (GFunc)pm_job_free, NULL);
+		g_queue_foreach (project->job_queue, (GFunc)pm_job_free, project->project);
 		g_queue_free (project->job_queue);
 		project->job_queue = NULL;
 		for (;;)
 		{
 			job = g_async_queue_try_pop (project->done_queue);
 			if (job == NULL) break;
-			pm_job_free (job);
+			pm_job_free (job, project->project);
 		}
 		project->done_queue = NULL;
 	}
@@ -329,6 +443,54 @@ pm_project_stop_thread (AnjutaPmProject *project)
 static void on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project);
 
 static void
+on_pm_project_reloaded_node (AnjutaPmProject *project, PmJob *job)
+{
+	if (job->error != NULL)
+	{
+		g_warning ("unable to load node");
+		pm_project_stop_thread (project);
+		g_object_unref (project->project);
+		project->project = NULL;
+		g_signal_emit (G_OBJECT (project), signals[LOADED], 0, job->error);
+	}
+	else
+	{
+		g_message ("reloaded node");
+		//g_object_set (G_OBJECT (project->model), "project", project, NULL);
+		// Check for incompletely loaded object and load them
+		if (anjuta_project_node_get_state (job->proxy) & ANJUTA_PROJECT_INCOMPLETE)
+		{
+			project->incomplete_node--;
+			g_message ("remaining node %d", project->incomplete_node);
+		}
+		anjuta_project_node_clear_state (job->proxy, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
+		anjuta_project_node_all_foreach (job->proxy, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
+		
+		if (project->root == job->node)
+		{
+			project->root = job->proxy;
+			g_message ("reload root");
+			gbf_project_model_update_tree (project->model, job->proxy, NULL, job->map);
+		}
+		else
+		{
+			GtkTreeIter iter;
+			gboolean found;
+			
+			found = gbf_project_model_find_node (project->model, &iter, NULL, job->node);
+			g_message ("reload node %d", found);
+			gbf_project_model_update_tree (project->model, job->proxy, &iter, job->map);
+		}
+		
+		
+		if (project->incomplete_node == 0)
+		{
+			g_signal_emit (G_OBJECT (project), signals[LOADED], 0, NULL);
+		}
+	}
+}
+
+static void
 on_pm_project_reloaded (AnjutaPmProject *project, PmJob *job)
 {
 	if (job->error != NULL)
@@ -341,6 +503,7 @@ on_pm_project_reloaded (AnjutaPmProject *project, PmJob *job)
 	}
 	else
 	{
+#if 0
 		//g_object_set (G_OBJECT (project->model), "project", project, NULL);
 		// Check for incompletely loaded object and load them
 		anjuta_project_node_clear_state (job->node, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
@@ -348,12 +511,13 @@ on_pm_project_reloaded (AnjutaPmProject *project, PmJob *job)
 		project->incomplete_node--;
 		anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
 		//g_signal_emit (G_OBJECT (project), signals[UPDATED], 0, job->error);
-		gbf_project_model_update_tree (project->model, NULL, NULL);
+		gbf_project_model_update_tree (project->model, NULL, NULL, NULL);
 		
 		if (project->incomplete_node == 0)
 		{
 			g_signal_emit (G_OBJECT (project), signals[LOADED], 0, NULL);
 		}
+#endif
 	}
 }
 
@@ -366,7 +530,7 @@ on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project
 	{
 		project->incomplete_node++;
 		anjuta_project_node_set_state (node, ANJUTA_PROJECT_LOADING);
-		pm_project_push_command (project, RELOAD, NULL, NULL, node, on_pm_project_reloaded);
+		pm_project_push_command (project, RELOAD_NODE, NULL, NULL, node, on_pm_project_reloaded_node);
 	}
 }
 
@@ -389,7 +553,7 @@ on_pm_project_loaded (AnjutaPmProject *project, PmJob *job)
 		g_message ("root all nodes %d", g_node_n_nodes (job->node, G_TRAVERSE_ALL));
 		project->root = job->node;
 		g_object_set (G_OBJECT (project->model), "project", project, NULL);
-		gbf_project_model_update_tree (project->model, NULL, NULL);
+		gbf_project_model_update_tree (project->model, project->root, NULL, NULL);
 		
 		// Check for incompletely loaded object and load them
 		project->incomplete_node = 0;
@@ -492,7 +656,6 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 gboolean
 anjuta_pm_project_reload_node (AnjutaPmProject *project, AnjutaProjectNode *node, GError **error)
 {
-	
 	pm_project_push_command (project, RELOAD, NULL, NULL, node, on_pm_project_reloaded);
 
 	return TRUE;
@@ -517,7 +680,8 @@ anjuta_pm_project_unload (AnjutaPmProject *project, GError **error)
 gboolean
 anjuta_pm_project_refresh (AnjutaPmProject *project, GError **error)
 {
-	ianjuta_project_refresh (project->project, error);
+	g_message ("reload project");
+	pm_project_push_command (project, RELOAD_NODE, NULL, NULL, project->root, on_pm_project_reloaded_node);
 
 	return TRUE;
 }
@@ -560,7 +724,7 @@ anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *group,
 {
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	return ianjuta_project_add_group (project->project, group, name, error);
+	return ianjuta_project_add_name_node (project->project, group, NULL, ANJUTA_PROJECT_GROUP, name, error);
 }
 
 AnjutaProjectNode *
@@ -666,7 +830,7 @@ anjuta_pm_project_get_node_from_file (AnjutaPmProject *project, AnjutaProjectNod
 	GtkTreeIter iter;
 	AnjutaProjectNode *node = NULL;
 	
-	if (gbf_project_model_find_tree_file (project->model, &iter, NULL, type, file))
+	if (gbf_project_model_find_file (project->model, &iter, NULL, type, file))
 	{
 		
 		node = gbf_project_model_get_node (project->model, &iter);
diff --git a/plugins/project-manager/tree-data.c b/plugins/project-manager/tree-data.c
index a9e0461..297fc21 100644
--- a/plugins/project-manager/tree-data.c
+++ b/plugins/project-manager/tree-data.c
@@ -121,6 +121,17 @@ gbf_tree_data_get_node (GbfTreeData *data)
 	return data->node;
 }
 
+void
+gbf_tree_data_replace_node (GbfTreeData *data, AnjutaProjectNode *node)
+{
+	GFile *file = ((AnjutaProjectNodeData *)node->data)->file;
+	
+	/* Replace file to keep the same interface */
+	((AnjutaProjectNodeData *)node->data)->file = ((AnjutaProjectNodeData *)data->node->data)->file;
+	((AnjutaProjectNodeData *)data->node->data)->file = file;
+	data->node = node;
+}
+
 gboolean
 gbf_tree_data_equal (GbfTreeData *data_a, GbfTreeData *data_b)
 {
diff --git a/plugins/project-manager/tree-data.h b/plugins/project-manager/tree-data.h
index 066901c..0c23b56 100644
--- a/plugins/project-manager/tree-data.h
+++ b/plugins/project-manager/tree-data.h
@@ -59,6 +59,8 @@ gchar	      *gbf_tree_data_get_uri		    (GbfTreeData           *data);
 GFile	      *gbf_tree_data_get_file		    (GbfTreeData           *data);
 const gchar   *gbf_tree_data_get_name		    (GbfTreeData           *data);
 AnjutaProjectNode *gbf_tree_data_get_node		(GbfTreeData           *data);
+void 			gbf_tree_data_replace_node		(GbfTreeData           *data,
+												 AnjutaProjectNode     *node);
 
 gchar		  *gbf_tree_data_get_path		    (GbfTreeData           *data);
 



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