[anjuta/newproject] Implement new IAnjutaProject interface (with signals and without thread in pm)



commit 2dd08a39f068e3202b3cdf74e3ca4e7b71c3800d
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sat Oct 23 22:43:16 2010 +0200

    Implement new IAnjutaProject interface (with signals and without thread in pm)

 libanjuta/interfaces/libanjuta.idl      |   36 ++-
 plugins/am-project/am-node.c            |   19 +
 plugins/am-project/am-node.h            |    1 +
 plugins/am-project/am-project.c         |  192 +++++++++-
 plugins/project-manager/project-model.c |   93 ++---
 plugins/project-manager/project-model.h |    6 +-
 plugins/project-manager/project.c       |  655 +++----------------------------
 plugins/project-manager/project.h       |   11 +-
 8 files changed, 323 insertions(+), 690 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index 2206856..e216c49 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -3097,15 +3097,47 @@ interface IAnjutaProject
 	/* Signals */
 	
 	/**
-	* IAnjutaProject::project_updated:
+	* IAnjutaProject::node_updated:
 	* @obj: Self
 	* @node: Updated node.
 	* 
-	* This signal is emitted when the project is changed.
+	* This signal is emitted when the project is changed on the disk.
 	*/
 	void ::node_updated (gpointer node);
 
 	/**
+	* IAnjutaProject::node_modified:
+	* @obj: Self
+	* @node: Modfied node.
+    * @error: Error while modifying node
+	* 
+	* This signal is emitted when a node is modified (by a function of this
+	* interface) and return an eventual error.
+	*/
+	void ::node_modified (gpointer node, GError *error);
+
+	/**
+	* IAnjutaProject::node_saved:
+	* @obj: Self
+	* @node: Saved node.
+    * @error: Error while saving node
+	* 
+	* This signal is emitted when a node is saved and return an eventual error
+	*/
+	void ::node_saved (gpointer node, GError *error);
+
+	/**
+	* IAnjutaProject::node_loaded:
+	* @obj: Self
+	* @node: Loaded node.
+    * @error: Error while loading node
+	* 
+	* This signal is emitted when a node is loaded and return an eventual error
+	*/
+	void ::node_loaded (gpointer node, GError *error);
+
+
+	/**
 	 * ianjuta_project_load_node:
 	 * @obj: Self
 	 * @node: Project node to reload
diff --git a/plugins/am-project/am-node.c b/plugins/am-project/am-node.c
index 3582b3c..cba3b3b 100644
--- a/plugins/am-project/am-node.c
+++ b/plugins/am-project/am-node.c
@@ -574,6 +574,25 @@ amp_group_get_makefile_name (AnjutaAmGroupNode *group)
 	return basename;
 }
 
+void
+amp_group_update_monitor (AnjutaAmGroupNode *group)
+{
+		if (group->monitor != NULL) g_object_unref (group->monitor);
+	
+		group->monitor = g_file_monitor_file (group->makefile, 
+						      									G_FILE_MONITOR_NONE,
+						       									NULL,
+						       									NULL);
+		if (group->monitor != NULL)
+		{
+			g_signal_connect (G_OBJECT (group->monitor),
+					  "changed",
+					  G_CALLBACK (on_group_monitor_changed),
+					  group);
+		}
+	
+}
+
 AnjutaAmGroupNode*
 amp_group_new (GFile *file, gboolean dist_only, GError **error)
 {
diff --git a/plugins/am-project/am-node.h b/plugins/am-project/am-node.h
index 7964ce9..fad9541 100644
--- a/plugins/am-project/am-node.h
+++ b/plugins/am-project/am-node.h
@@ -65,6 +65,7 @@ AnjutaTokenFile* amp_group_set_makefile (AnjutaAmGroupNode *group, GFile *makefi
 AnjutaToken* amp_group_get_makefile_token (AnjutaAmGroupNode *group);
 gchar *amp_group_get_makefile_name (AnjutaAmGroupNode *group);
 gboolean amp_group_update_makefile (AnjutaAmGroupNode *group, AnjutaToken *token);
+void amp_group_update_monitor (AnjutaAmGroupNode *node);
 AnjutaAmGroupNode* amp_group_new (GFile *file, gboolean dist_only, GError **error);
 void amp_group_free (AnjutaAmGroupNode *node);
 
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index 17780b7..baf2d6b 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -551,7 +551,7 @@ monitor_cb (GFileMonitor *monitor,
 			/* 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");
+			g_signal_emit_by_name (G_OBJECT (project), "node-updated");
 			break;
 		default:
 			break;
@@ -1438,6 +1438,161 @@ amp_project_set_am_variable (AmpProject* project, AnjutaAmGroupNode* group, Anju
 	}
 }
 
+/* Map function
+ *---------------------------------------------------------------------------*/
+
+static gint
+amp_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_node_type (old_node) == anjuta_project_node_get_node_type (new_node))
+		&& ((name1 == NULL) || (name2 == NULL) || (strcmp (name1, name2) == 0))
+		&& ((file1 == NULL) || (file2 == NULL) || g_file_equal (file1, file2)) ? 0 : 1;
+}
+
+static void
+amp_project_map_children (GHashTable *map, AnjutaProjectNode *old_node, AnjutaProjectNode *new_node)
+{
+	GList *children = NULL;
+
+	if (new_node != 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);
+		}
+		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)amp_project_compare_node);
+
+		if (same != NULL)
+		{
+			g_hash_table_insert (map, (AnjutaProjectNode *)same->data, old_node);
+
+			amp_project_map_children (map, old_node, (AnjutaProjectNode *)same->data);
+			children = g_list_delete_link (children, same);
+		}
+		else
+		{
+			/* Mark deleted node */
+			g_hash_table_insert (map, old_node, NULL);
+		}
+	}
+
+	/* Add remaining node in hash table */
+	for (; children != NULL; children = g_list_delete_link (children,  children))
+	{
+		g_hash_table_insert (map, children->data, children->data);
+	}
+}
+
+static GHashTable *
+amp_project_map_node (AnjutaProjectNode *old_node, AnjutaProjectNode *new_node)
+{
+	GHashTable *map;
+	
+	map = g_hash_table_new (g_direct_hash, NULL);
+
+	g_hash_table_insert (map, new_node, old_node);
+
+	amp_project_map_children (map, old_node, new_node);
+
+	return map;
+}
+
+
+static void
+amp_project_replace_node (AnjutaProjectNode *new_node, AnjutaProjectNode *old_node, GHashTable *map)
+{
+	if (old_node == NULL)
+	{
+		/* Delete old node */
+		g_object_unref (old_node);
+	}
+	else
+	{
+		if (old_node != new_node)
+		{
+			GTypeQuery type_info;
+			gchar *data;
+
+			g_type_query (G_TYPE_FROM_INSTANCE (old_node), &type_info);
+
+			/* Swap new and old node */
+			data = g_new0 (gchar, type_info.instance_size - sizeof (GInitiallyUnowned));
+			memcpy (data, (gchar *)old_node + sizeof (GInitiallyUnowned), type_info.instance_size - sizeof (GInitiallyUnowned));
+			memcpy ((gchar *)old_node + sizeof (GInitiallyUnowned), (gchar *)new_node + sizeof (GInitiallyUnowned),  type_info.instance_size - sizeof (GInitiallyUnowned));
+			memcpy ((gchar *)new_node + sizeof (GInitiallyUnowned), data,  type_info.instance_size - sizeof (GInitiallyUnowned));
+			g_free (data);
+
+			/* Update file monitor if it is a group */
+			if (anjuta_project_node_get_node_type (old_node) == ANJUTA_PROJECT_GROUP)
+			{
+				amp_group_update_monitor (old_node);
+			}
+
+			/* Get old file */
+			if (old_node->file != NULL) g_object_unref (old_node->file);
+			old_node->file = new_node->file;
+			new_node->file = NULL;
+
+			/* Unlink old node and free it */
+			new_node->parent = NULL;
+			new_node->children = NULL;
+			new_node->next = NULL;
+			new_node->prev = NULL;
+			g_object_unref (new_node);
+
+			new_node = old_node;
+		}
+		
+		/* Update links */
+		old_node = g_hash_table_lookup (map, new_node->parent);
+		if (old_node != NULL) new_node->parent = old_node;
+		old_node = g_hash_table_lookup (map, new_node->children);
+		if (old_node != NULL) new_node->children = old_node;
+		old_node = g_hash_table_lookup (map, new_node->next);
+		if (old_node != NULL) new_node->next = old_node;
+		old_node = g_hash_table_lookup (map, new_node->prev);
+		if (old_node != NULL) new_node->prev = old_node;
+	}
+}
+
+static AnjutaProjectNode *
+amp_project_duplicate_node (AnjutaProjectNode *old_node)
+{
+	AnjutaProjectNode *new_node;
+	GTypeQuery type_info;
+	gchar *data;
+
+	/* Create new node */
+	new_node = g_object_new (G_TYPE_FROM_INSTANCE (old_node), NULL);
+	g_type_query (G_TYPE_FROM_INSTANCE (old_node), &type_info);
+	memcpy ((gchar *)new_node + sizeof (GInitiallyUnowned), (gchar *)old_node + sizeof (GInitiallyUnowned),  type_info.instance_size - sizeof (GInitiallyUnowned));
+	new_node->custom_properties = NULL;
+	new_node->file = g_file_dup (new_node->file);
+	new_node->name = g_strdup (new_node->name);
+	new_node->children = NULL;
+
+	/* Remove loaded node specific data */
+	memset ((gchar *)old_node + sizeof (AnjutaProjectNode), 0, type_info.instance_size - sizeof (AnjutaProjectNode));
+
+	return new_node;
+}
 
 /* Public functions
  *---------------------------------------------------------------------------*/
@@ -2116,25 +2271,43 @@ amp_project_add_file (AmpProject *project, GFile *file, AnjutaTokenFile* token)
 /* Implement IAnjutaProject
  *---------------------------------------------------------------------------*/
 
+
 static gboolean
-iproject_load_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+iproject_load_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **error)
 {
+	AnjutaProjectNode *new_node;
+	AnjutaProjectNode *proxy;
+	GHashTable *map;
+	GError *err = NULL;
+	
 	if (node == NULL) node = AMP_PROJECT (obj)->root;
+
+	proxy = amp_project_duplicate_node (node);
 	
-	node = amp_project_load_node (AMP_PROJECT (obj), node, err);
+	new_node = amp_project_load_node (AMP_PROJECT (obj), proxy, &err);
+	map = amp_project_map_node (node, new_node);
+	g_hash_table_foreach (map, (GHFunc)amp_project_replace_node, map);
+	node->parent = new_node->parent;
+	proxy->parent = NULL;
+	g_hash_table_destroy (map);
+	g_object_unref (proxy);
+	g_signal_emit_by_name (obj, "node-loaded", node,  err);
+	g_error_free (err);
 
-	return node != NULL;
+	return new_node != NULL;
 }
 
 static gboolean
 iproject_save_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **error)
 {
+	GError *err = NULL;
+	
 	if (node == NULL) node = AMP_PROJECT (obj)->root;
 	
 	switch (anjuta_project_node_get_node_type (node))
 	{
 		case ANJUTA_PROJECT_ROOT:
-			if (!amp_project_save (AMP_PROJECT (obj), error))
+			if (!amp_project_save (AMP_PROJECT (obj), &err))
 			{
 				node = NULL;
 			}
@@ -2143,6 +2316,8 @@ iproject_save_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **error
 			node = project_node_save (AMP_PROJECT (obj), node, error);
 			break;
 	}
+	g_signal_emit_by_name (obj, "node-saved", node,  err);
+	g_error_free (err);
 	
 	return node != NULL;
 }
@@ -2181,6 +2356,7 @@ iproject_add_node_before (IAnjutaProject *obj, AnjutaProjectNode *parent, Anjuta
 			anjuta_project_node_insert_before (parent, sibling, node);
 			break;
 	}
+	g_signal_emit_by_name (obj, "node-modified", node,  NULL);
 	
 	return node;
 }
@@ -2219,6 +2395,7 @@ iproject_add_node_after (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaP
 			anjuta_project_node_insert_after (parent, sibling, node);
 			break;
 	}
+	g_signal_emit_by_name (obj, "node-modified", node,  NULL);
 	
 	return node;
 }
@@ -2244,6 +2421,7 @@ iproject_remove_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err
 		default:
 			break;
 	}
+	g_signal_emit_by_name (obj, "node-modified", node,  NULL);
 
 	return TRUE;
 }
@@ -2266,6 +2444,7 @@ iproject_set_property (IAnjutaProject *obj, AnjutaProjectNode *node, AnjutaProje
 	{
 		amp_project_update_am_property (AMP_PROJECT (obj), node, new_prop);
 	}
+	g_signal_emit_by_name (obj, "node-modified", node,  NULL);
 	
 	return new_prop;
 }
@@ -2277,6 +2456,7 @@ iproject_remove_property (IAnjutaProject *obj, AnjutaProjectNode *node, AnjutaPr
 
 	old_prop = anjuta_project_node_remove_property (node, property);
 	amp_property_free (old_prop);
+	g_signal_emit_by_name (obj, "node-modified", node,  NULL);
 	
 	return TRUE;
 }
diff --git a/plugins/project-manager/project-model.c b/plugins/project-manager/project-model.c
index 65aff24..ea9c058 100644
--- a/plugins/project-manager/project-model.c
+++ b/plugins/project-manager/project-model.c
@@ -339,7 +339,7 @@ gbf_project_model_remove_invalid_shortcut (GbfProjectModel *model, GtkTreeIter *
 		else
 		{
 			gbf_project_model_remove_invalid_shortcut (model, &child); 
-			valid = gtk_tree_model_iter_next (model, &child);
+			valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
 		}
 	}
 		
@@ -726,9 +726,7 @@ add_root (GbfProjectModel 	*model,
     AnjutaProjectNode	*root,
     GtkTreeIter     	*parent)
 {
-	GtkTreeIter iter;
 	AnjutaProjectNode *node;
-	GtkTreePath *root_path;
 
 	if ((!root) || (anjuta_project_node_get_node_type (root) != ANJUTA_PROJECT_ROOT))
 		return;
@@ -750,7 +748,7 @@ add_root (GbfProjectModel 	*model,
 static void
 project_updated_cb (IAnjutaProject *project, GbfProjectModel *model)
 {
-	gbf_project_model_update_tree (model, NULL, NULL, NULL);
+	gbf_project_model_update_tree (model, NULL, NULL);
 }
 
 static void
@@ -844,14 +842,14 @@ recursive_find_tree_data (GtkTreeModel  *model,
 }
 
 void
-gbf_project_model_update_shortcut (GbfProjectModel *model, GtkTreeIter *iter, GHashTable *map)
+gbf_project_model_update_shortcut (GbfProjectModel *model, AnjutaProjectNode *parent)
 {
 	GtkTreeIter child;
 	gboolean valid;
 
-	/* Get all children */
-	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, iter);
-	
+	/* Get all root node */
+	valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &child, NULL);
+
 	while (valid)
 	{
 		GbfTreeData *data;
@@ -861,42 +859,23 @@ gbf_project_model_update_shortcut (GbfProjectModel *model, GtkTreeIter *iter, GH
 		gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
 	  			 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 	    			-1);
-			
+
 		/* Shortcuts are always at the beginning */
-		if ((iter == NULL) && (data->type != GBF_TREE_NODE_SHORTCUT)) break;
+		if (data->type != GBF_TREE_NODE_SHORTCUT) break;
 
 		old_node = gbf_tree_data_get_node (data);
-		if (g_hash_table_lookup_extended (map, old_node, NULL, &new_node))
-		{
-			/* Find node */
-			if (new_node != NULL)
-			{
-				/* Node has been changed */
-				gbf_tree_data_replace_node (data, new_node);
-				
-				/* update recursively */
-				gbf_project_model_update_tree (model, new_node, &child, map);
-				
-				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
-			}
-			else
-			{
-				/* Node has been removed */
-				valid = gbf_project_model_remove (model, &child);
-			}
-		}
-		else
+		if (old_node == parent)
 		{
-			/* Node has not changed */
-			gbf_project_model_update_shortcut (model, &child, map);
-			
-			valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
+			/* check children */
+			gbf_project_model_update_tree (model, parent, &child);
 		}
-	}
+		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
+	}	
 }
 
+	
 void
-gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *iter, GHashTable *map)
+gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *iter)
 {
 	GtkTreeIter child;
 	GList *node;
@@ -912,39 +891,35 @@ gbf_project_model_update_tree (GbfProjectModel *model, AnjutaProjectNode *parent
 		
 		while (valid) {
 			GbfTreeData *data = NULL;
-			AnjutaProjectNode* new_node = NULL;
-			AnjutaProjectNode* old_node = NULL;
+			AnjutaProjectNode* data_node = NULL;
 
-			if (map != NULL)
-			{
-				/* Look for old node */
+			/* Look for current node */
 				
-				gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
-					GBF_PROJECT_MODEL_COLUMN_DATA, &data,
-					-1);
+			gtk_tree_model_get (GTK_TREE_MODEL (model), &child,
+				GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+				-1);
 
-				old_node = gbf_tree_data_get_node (data);
-				new_node = g_hash_table_lookup (map, old_node);
-			}
-			
-			if (new_node != NULL)
+			data_node = gbf_tree_data_get_node (data);
+
+			node = g_list_find (nodes, data_node);
+
+			if (node != NULL)
 			{
-				/* Remove from the new node list */
-				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);
-				
+				/* Node already exist, remove it from the list */
+				nodes = g_list_delete_link (nodes, node);
+
+				/* Update shortcut */
+				gbf_project_model_update_shortcut (model, data_node);
+				                                   
 				/* update recursively */
-				gbf_project_model_update_tree (model, new_node, &child, map);
+				gbf_project_model_update_tree (model, data_node, &child);
+
 				
 				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &child);
 			}
 			else
 			{
-				/* update recursively */
+				/* Node has been deleted */
 				valid = gbf_project_model_remove (model, &child);
 			}
 		}
diff --git a/plugins/project-manager/project-model.h b/plugins/project-manager/project-model.h
index 1c179ba..35217bf 100644
--- a/plugins/project-manager/project-model.h
+++ b/plugins/project-manager/project-model.h
@@ -86,11 +86,7 @@ void             gbf_project_model_add_shortcut      (GbfProjectModel *model,
 
 void            gbf_project_model_update_tree (GbfProjectModel *model,
                                                     AnjutaProjectNode *parent,
-                                                    GtkTreeIter *iter,
-                                                    GHashTable *map);
-void            gbf_project_model_update_shortcut (GbfProjectModel *model,
-                                                    GtkTreeIter *iter,
-                                                    GHashTable *map);
+                                                    GtkTreeIter *iter);
 
 
 #endif
diff --git a/plugins/project-manager/project.c b/plugins/project-manager/project.c
index 65add31..fb55277 100644
--- a/plugins/project-manager/project.c
+++ b/plugins/project-manager/project.c
@@ -32,106 +32,9 @@
 #include "dialogs.h"
 
 
-/*
-
-2 Threads: GUI and Work
-
-Add new source.
-
-1. Work add new node
- + Obvious, because it has the parent node
- - Not possible, if the GUI has to get all child of the same node
-
-2. Work add new node, GUI use tree data
-
-3. Work create new node only but doesn't add it
-
-4. GUI create a new node and call the save function later
-
-
-The GUI cannot change links, else the Work cannot follow links when getting a
-node. The Work can even need parent links.
-=> GUI cannot read links except in particular case
-
-The GUI can read and write common part
-=> We need to copy the properties anyway when changing them
-
-The GUI can only read common part
-=> 
-
-Have a proxy node for setting properties, this proxy will copy add common data
-and keep a link with the original node and reference count. The GUI can still
-read all data in the proxy without disturbing the Work which can change the
-underlines node. The proxy address is returned immediatly when the
-set_properties function is used. If another set_properties is done on the same
-node the proxy is reused, incrementing reference count.
-
-There is no need to proxy after add or remove functions, because the links are
-already copied in the module.
- 
-After changing a property should we reload automatically ?
-
-
-Reloading a node can change its property, so we need a proxy for the load too.
-
-Proxy has to be created in GUI, because we need to update tree data.
-
-Instead of using a Proxy, we can copy all data everytime, this will allow
-automatic reload.
- 
-
- 
- Work has always a full access to link
- GUI read a special GNode tree created by thread
-
- Work can always read common data, and can write them before sending them to GUI
- or in when modification are requested by the GUI (the GUI get a proxy)
- GUI can only read common data
-
- Work has always a full access to specific data.
- GUI has no access to specific data
- 
- 
-*/
- 
 /* Types
  *---------------------------------------------------------------------------*/
 
-typedef enum
-{
-	LOAD = 0,
-	RELOAD,
-	SAVE,
-	ADD,
-	REMOVE,
-	EXIT,
-	LAST_COMMAND
-} PmCommand;
-
-typedef struct _PmJob PmJob;
-
-typedef gboolean (*PmCommandFunc) (AnjutaPmProject *project, PmJob *job);
-
-typedef struct _PmCommandWork
-{
-	PmCommandFunc setup;
-	PmCommandFunc worker;
-	PmCommandFunc complete;
-} PmCommandWork;
-
-struct _PmJob
-{
-	PmCommand command;
-	AnjutaProjectNodeType type;
-	GFile *file;
-	gchar *name;
-	AnjutaProjectNode *node;
-	AnjutaProjectNode *sibling;
-	GError *error;
-	AnjutaProjectNode *proxy;
-	GHashTable *map;
-};
-
 /* Signal
  *---------------------------------------------------------------------------*/
 
@@ -144,259 +47,6 @@ enum
 
 static unsigned int signals[LAST_SIGNAL] = { 0 };
 
-/* Command functions
- *---------------------------------------------------------------------------*/
-
-static PmCommandWork PmCommands[LAST_COMMAND];
-
-
-/* Forward declarations
- *---------------------------------------------------------------------------*/
-
-static gboolean pm_project_idle_func (AnjutaPmProject *project);
-static gboolean pm_project_run_command (AnjutaPmProject *project);
-
-/* Job functions
- *---------------------------------------------------------------------------*/
-
-static PmJob *
-pm_job_new (PmCommand command, AnjutaProjectNode *node, AnjutaProjectNode *sibling, AnjutaProjectNodeType type, GFile *file, const gchar *name)
-{
-	PmJob *job;
-
-	job = g_new0 (PmJob, 1);
-	job->command = command;
-	job->node = node;
-	job->sibling = sibling;
-	job->type = type;
-	if (file != NULL) job->file = g_object_ref (file);
-	if (name != NULL) job->name = g_strdup (name);
-
-	return job;
-}
-
-static void
-pm_job_free (PmJob *job)
-{
-	if (job->error != NULL) g_error_free (job->error);
-	if (job->map != NULL) g_hash_table_destroy (job->map);
-	if (job->file != NULL) g_object_unref (job->file);
-	if (job->name != NULL) g_free (job->name);
-}
-
-/* Worker 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_node_type (old_node) == anjuta_project_node_get_node_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;
-
-	if (new_node != 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);
-		}
-		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);
-		
-		if (same != NULL)
-		{
-			g_hash_table_insert (job->map, old_node, (AnjutaProjectNode *)same->data);
-			
-			pm_project_map_children ((PmJob *)job, old_node, (AnjutaProjectNode *)same->data);
-			children = g_list_delete_link (children, same);
-		}
-		else
-		{
-			/* Mark deleted node */
-			g_hash_table_insert (job->map, old_node, NULL);
-			pm_project_map_children ((PmJob *)job, old_node, NULL);
-		}
-	}
-	
-	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->proxy;
-		new_node = job->node;
-
-		g_hash_table_insert (job->map, old_node, new_node);
-			
-		pm_project_map_children (job, old_node, new_node);
-	}
-}
-
-static gboolean
-pm_command_load_work (AnjutaPmProject *project, PmJob *job)
-{
-	AnjutaProjectNode *node;
-	
-
-	if (ianjuta_project_load_node (project->project, job->node, &(job->error)))
-	{
-		pm_project_map_node (job);
-	}
-	
-	return TRUE;
-}
-
-static gboolean
-pm_command_save_work (AnjutaPmProject *project, PmJob *job)
-{
-	return ianjuta_project_save_node (project->project, job->node, &(job->error));
-}
-
-static gboolean
-pm_command_exit_work (AnjutaPmProject *project, PmJob *job)
-{
-	g_return_val_if_fail (job != NULL, FALSE);
-
-	/* Push job in complete queue as g_thread_exit will stop the thread
-	 * immediatly */
-	g_async_queue_push (project->done_queue, job);
-	g_thread_exit (0);
-	
-	return TRUE;
-}
-
-/* Run work function in worker thread */
-static gpointer
-pm_project_thread_main_loop (AnjutaPmProject *project)
-{
-	for (;;)
-	{
-		PmJob *job;
-		PmCommandFunc func;
-		
-		/* Get new job */
-		job = (PmJob *)g_async_queue_pop (project->work_queue);
-
-		/* Get work function and call it if possible */
-		func = PmCommands[job->command].worker;
-		if (func != NULL)
-		{
-			func (project, job);
-		}
-		
-		/* Push completed job in queue */
-		g_async_queue_push (project->done_queue, job);
-	}
-}
-
-/* Main thread functions
- *---------------------------------------------------------------------------*/
-
-static gboolean
-pm_project_start_thread (AnjutaPmProject *project, GError **error)
-{
-	project->done_queue = g_async_queue_new ();
-	project->work_queue = g_async_queue_new ();
-	project->job_queue = g_queue_new ();
-
-	project->worker = g_thread_create ((GThreadFunc) pm_project_thread_main_loop, project, TRUE, error);
-
-	if (project->worker == NULL) {
-		g_async_queue_unref (project->work_queue);
-		project->work_queue = NULL;
-		g_async_queue_unref (project->done_queue);
-		project->done_queue = NULL;
-		g_queue_free (project->job_queue);
-		project->job_queue = NULL;
-
-		return FALSE;
-	}
-	else
-	{
-		project->idle_func = g_idle_add ((GSourceFunc) pm_project_idle_func, project);
-		project->stopping = FALSE;
-
-		return TRUE;
-	}
-}
-
-static gboolean
-pm_project_stop_thread (AnjutaPmProject *project)
-{
-	if (project->job_queue)
-	{
-		PmJob *job;
-		
-		project->stopping = TRUE;
-
-		// Remove idle function
-		g_idle_remove_by_data (project);
-		project->idle_func = 0;
-
-		// Request to terminate thread
-		job = pm_job_new (EXIT, NULL, NULL, 0, NULL, NULL);
-		g_async_queue_push (project->work_queue, job);
-		g_thread_join (project->worker);
-		project->worker = NULL;
-
-		// Free queue
-		g_async_queue_unref (project->work_queue);
-		project->work_queue = 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);
-		}
-		project->done_queue = NULL;
-	}
-
-	return TRUE;
-}
-
-static void
-pm_project_push_command (AnjutaPmProject *project, PmCommand command, AnjutaProjectNode *node, AnjutaProjectNode *sibling, AnjutaProjectNodeType type, GFile *file, const gchar *name)
-{
-	PmJob *job;
-
-	job = pm_job_new (command, node, sibling, type, file, name);
-	g_queue_push_tail (project->job_queue, job);
-	
-	pm_project_run_command (project);
-}
-
 static void
 on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project)
 {
@@ -408,287 +58,83 @@ on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project
 		project->incomplete_node++;
 		anjuta_project_node_set_state (node, ANJUTA_PROJECT_LOADING);
 		//g_message ("load incomplete %p", node);
-		pm_project_push_command (project, RELOAD, node, NULL, 0, NULL, NULL);
-	}
-}
-
-static gboolean
-pm_command_load_setup (AnjutaPmProject *project, PmJob *job)
-{
-	g_return_val_if_fail (job != NULL, FALSE);
-	g_return_val_if_fail (job->node != NULL, FALSE);
-	
-	job->proxy = anjuta_project_proxy_new (job->node);
-	anjuta_project_node_replace (job->node, job->proxy);
-	/*anjuta_project_proxy_exchange_data (job->node, job->proxy);*/
-	
-	return TRUE;
-}
-
-static void
-check_queue (GQueue *queue, GHashTable *map)
-{
-	guint i;
-	
-	//g_message ("check queue size %d", g_queue_get_length (queue));
-	for (i = 0;; i++)
-	{
-		PmJob *job = (PmJob *)g_queue_peek_nth (queue, i);
-		
-		if (job == NULL) break;
-		if (job->node != NULL)
-		{
-			AnjutaProjectNode *replace;
-			AnjutaProjectNode *node;
-			
-			/* Get original node if we have a proxy here */
-			node = anjuta_project_proxy_get_node (job->node);
-			
-			if (g_hash_table_lookup_extended (map, node, NULL, (gpointer *)&replace))
-			{
-				//g_message ("*** delete node %p used ***", job->node);
-				if (replace != NULL)
-				{
-					/* Replaced node */
-					job->node = replace;
-				}
-				else
-				{
-					/* node has been deleted */
-					g_warning ("Node %s has been delete before executing command %d", anjuta_project_node_get_name (job->node), job->command);
-					job = g_queue_pop_nth (queue, i);
-					pm_job_free (job);
-					i--;
-				}
-			}
-		}
+		ianjuta_project_load_node (project->project, node, NULL);
 	}
 }
 
 static gboolean
-pm_command_load_complete (AnjutaPmProject *project, PmJob *job)
+pm_command_load_complete (AnjutaPmProject *project, AnjutaProjectNode *node, GError *error)
 {
-	//anjuta_project_proxy_exchange (job->proxy, job->node);
-	anjuta_project_node_exchange (job->proxy, job->node);
-
 	g_message ("pm_command_load_complete");
-	if (job->error != NULL)
+	
+	if (error != NULL)
 	{
 		g_warning ("unable to load node");
-		g_signal_emit (G_OBJECT (project), signals[job->command == LOAD ? LOADED : UPDATED], 0, job->node, job->error);
+		g_signal_emit (G_OBJECT (project), project->loaded ? LOADED : UPDATED, 0, node, error);
 	}
 	else
 	{
-		gboolean load = job->command == LOAD;
-	
-		if (job->command == LOAD)
+		if (project->root == node)
 		{
 			g_object_set (G_OBJECT (project->model), "project", project, NULL);
 			project->incomplete_node = 0;
-		}
-		
-		if (project->root == job->node)
-		{
-			gbf_project_model_update_tree (project->model, job->node, NULL, job->map);
-			gbf_project_model_update_shortcut (project->model, NULL, job->map);
+			gbf_project_model_update_tree (project->model, node, NULL);
 		}
 		else
 		{
 			GtkTreeIter iter;
 			gboolean found;
 			
-			found = gbf_project_model_find_node (project->model, &iter, NULL, job->node);
-			gbf_project_model_update_tree (project->model, job->node, found ? &iter : NULL, job->map);
-			gbf_project_model_update_shortcut (project->model, NULL, job->map);
+			found = gbf_project_model_find_node (project->model, &iter, NULL, node);
+			gbf_project_model_update_tree (project->model, node, found ? &iter : NULL);
 		}
 		
-		
 		// Check for incompletely loaded object and load them
-		if (anjuta_project_node_get_state (job->node) & ANJUTA_PROJECT_INCOMPLETE)
+		if (anjuta_project_node_get_state (node) & ANJUTA_PROJECT_INCOMPLETE)
 		{
 			project->incomplete_node--;
 			//g_message ("remaining node %d", project->incomplete_node);
-			if (project->incomplete_node == 0) load = TRUE;
 		}
-		anjuta_project_node_clear_state (job->node, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
-		anjuta_project_node_foreach (job->node, G_POST_ORDER, (AnjutaProjectNodeForeachFunc)on_pm_project_load_incomplete, project);
+		anjuta_project_node_clear_state (node, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
+		anjuta_project_node_foreach (node, G_POST_ORDER, (AnjutaProjectNodeForeachFunc)on_pm_project_load_incomplete, project);
 
-		g_message ("emit node %p", job->node);
-		if (load && (project->incomplete_node == 0))
+		g_message ("emit node %p", node);
+		if (!project->loaded && (project->incomplete_node == 0))
 		{
-			g_signal_emit (G_OBJECT (project), signals[LOADED], 0, job->node, NULL);
+			g_signal_emit (G_OBJECT (project), signals[LOADED], 0, node, NULL);
+			project->loaded = TRUE;
 		}
 		else
 		{
-			g_signal_emit (G_OBJECT (project), signals[UPDATED], 0, job->node, NULL);
+			g_signal_emit (G_OBJECT (project), signals[UPDATED], 0, node, NULL);
 		}
-		check_queue (project->job_queue, job->map);
 	}
-
-	anjuta_project_proxy_unref  (job->proxy);
-	//anjuta_project_node_foreach (job->proxy, G_POST_ORDER, (AnjutaProjectNodeForeachFunc)pm_free_node, project->project);
-	
-	return TRUE;
-}
-
-static gboolean
-pm_command_add_setup (AnjutaPmProject *project, PmJob *job)
-{
-	AnjutaProjectNode *node;
-	
-	g_return_val_if_fail (job != NULL, FALSE);
-	g_return_val_if_fail (job->node != NULL, FALSE);
-
-	node = ianjuta_project_add_node_before (project->project, job->node, job->sibling, job->type, NULL, job->name, NULL);
-	job->node = node;
 	
 	return TRUE;
 }
 
-static gboolean
-pm_command_remove_setup (AnjutaPmProject *project, PmJob *job)
+static void
+on_node_updated (IAnjutaProject *sender, AnjutaProjectNode *node, AnjutaPmProject *project)
 {
-	GtkTreeIter iter;
-	
-	g_return_val_if_fail (job != NULL, FALSE);
-	g_return_val_if_fail (job->node != NULL, FALSE);
-
-	/* Remove node from project tree */
-	if (gbf_project_model_find_node (project->model, &iter, NULL, job->node))
-	{
-		gbf_project_model_remove (project->model, &iter);
-		ianjuta_project_remove_node (project->project, job->node, NULL);
-		
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
+	ianjuta_project_load_node (project->project, node, NULL);
 }
 
-static gboolean
-pm_command_remove_complete (AnjutaPmProject *project, PmJob *job)
-{
-	g_return_val_if_fail (job != NULL, FALSE);
-	g_return_val_if_fail (job->node != NULL, FALSE);
-
-	/* Remove node from node tree */
-	//anjuta_project_node_remove (job->node);
-	//pm_free_node (job->node, project->project);
-	//anjuta_project_node_foreach (job->node, G_POST_ORDER, (AnjutaProjectNodeForeachFunc)pm_free_node, project->project);
-	
-	return TRUE;
-}
- 
-static PmCommandWork PmCommands[LAST_COMMAND] = {
-			{pm_command_load_setup,
-			pm_command_load_work,
-			pm_command_load_complete},
-			{pm_command_load_setup,
-			pm_command_load_work,
-			pm_command_load_complete},
-			{NULL,
-			pm_command_save_work,
-			NULL},
-			{pm_command_add_setup,
-			pm_command_save_work,
-			NULL},
-			{pm_command_remove_setup,
-			pm_command_save_work,
-			pm_command_remove_complete},
-			{NULL,
-			pm_command_exit_work,
-			NULL}};
-
-/* Run a command in job queue */
-static gboolean
-pm_project_run_command (AnjutaPmProject *project)
+static void
+on_node_loaded (IAnjutaProject *sender, AnjutaProjectNode *node, GError *error, AnjutaPmProject *project)
 {
-	gboolean running = TRUE;
-	
-	if (project->busy == 0)
-	{
-		/* Worker thread is waiting for new command, check job queue */
-		PmJob *job;
-		
-		do
-		{
-			PmCommandFunc func;
-			
-			/* Get next command */
-			job = g_queue_pop_head (project->job_queue);
-			running = job != NULL;
-			if (!running) break;
-			
-			/* Get setup function and call it if possible */
-			func = PmCommands[job->command].setup;
-			if (func != NULL)
-			{
-				running = func (project, job);
-			}
-				
-			if (running)
-			{
-				/* Execute work function in the worker thread */
-				project->busy = 1;
-				
-				if (project->idle_func == 0)
-				{
-					project->idle_func = g_idle_add ((GSourceFunc) pm_project_idle_func, project);
-				}
-				g_async_queue_push (project->work_queue, job);
-			}
-			else
-			{
-				/* Discard command */
-				pm_job_free (job);
-			}
-		} while (!running);
-	}
-	
-	return running;
+	pm_command_load_complete (project, node, error);
 }
 
-static gboolean
-pm_project_idle_func (AnjutaPmProject *project)
+static void
+on_node_changed (IAnjutaProject *sender, AnjutaProjectNode *node, GError *error, AnjutaPmProject *project)
 {
-	gboolean running;
-
-	for (;;)
-	{
-		PmCommandFunc func;
-		PmJob *job;
-		
-		/* Get completed command */
-		job = (PmJob *)g_async_queue_try_pop (project->done_queue);
-		if (job == NULL) break;
-
-		/* Get complete function and call it if possible */
-		func = PmCommands[job->command].complete;
-		if (func != NULL)
-		{
-			running = func (project, job);
-		}
-		pm_job_free (job);
-		project->busy--;
-	}
-	
-	running = pm_project_run_command (project);
-	if (!running) project->idle_func = 0;
-	
-	return running;
+	ianjuta_project_save_node (project->project, node, NULL);
 }
 
 /* Public functions
  *---------------------------------------------------------------------------*/
 
-static void
-on_node_updated (IAnjutaProject *sender, AnjutaProjectNode *node, AnjutaPmProject *project)
-{
-	pm_project_push_command (project, RELOAD, node, NULL, 0, NULL, NULL);
-}
- 
+
 gboolean 
 anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 {
@@ -696,7 +142,6 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 	GList *desc;
 	IAnjutaProjectBackend *backend;
 	gint found = 0;
-	GError *err = NULL;
 	
 	g_return_val_if_fail (file != NULL, FALSE);
 	
@@ -704,6 +149,7 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 	{
 		g_object_unref (project->project);
 		project->project = NULL;
+		project->loaded = FALSE;
 	}
 	
 	DEBUG_PRINT ("loading gbf backendâ?¦\n");
@@ -767,17 +213,21 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 		return FALSE;
 	}
 
-	if (!pm_project_start_thread(project, &err))
-	{
-		return FALSE;
-	}
 	g_signal_connect (G_OBJECT (project->project),
 						"node-updated",
 						G_CALLBACK (on_node_updated),
 						project);
+	g_signal_connect (G_OBJECT (project->project),
+						"node-loaded",
+						G_CALLBACK (on_node_loaded),
+						project);
+	g_signal_connect (G_OBJECT (project->project),
+						"node-changed",
+						G_CALLBACK (on_node_changed),
+						project);
 	
 	project->root = ianjuta_project_get_root (project->project, NULL);
-	pm_project_push_command (project, LOAD, project->root, NULL, 0, NULL, NULL);
+	ianjuta_project_load_node (project->project, project->root, NULL);
 	
 	return TRUE;
 }
@@ -785,7 +235,7 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
 static gboolean
 anjuta_pm_project_reload_node (AnjutaPmProject *project, AnjutaProjectNode *node, GError **error)
 {
-	pm_project_push_command (project, RELOAD, node, NULL, 0, NULL, NULL);
+	ianjuta_project_load_node (project->project, project->root, NULL);	
 
 	return TRUE;
 }
@@ -793,11 +243,10 @@ anjuta_pm_project_reload_node (AnjutaPmProject *project, AnjutaProjectNode *node
 gboolean 
 anjuta_pm_project_unload (AnjutaPmProject *project, GError **error)
 {
-	pm_project_stop_thread (project);
-	
 	g_object_set (G_OBJECT (project->model), "project", NULL, NULL);
 	g_object_unref (project->project);
 	project->project = NULL;
+	project->loaded = FALSE;
 
 	/* Remove project properties dialogs */
 	if (project->properties_dialog != NULL) gtk_widget_destroy (project->properties_dialog);
@@ -809,9 +258,7 @@ anjuta_pm_project_unload (AnjutaPmProject *project, GError **error)
 gboolean
 anjuta_pm_project_refresh (AnjutaPmProject *project, GError **error)
 {
-	//g_message ("reload project %p", project->root);
-	
-	pm_project_push_command (project, RELOAD, project->root, NULL, 0, NULL, NULL);
+	ianjuta_project_load_node (project->project, project->root, NULL);	
 
 	return TRUE;
 }
@@ -909,7 +356,7 @@ anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *parent
 	
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	pm_project_push_command (project, ADD, parent, sibling, ANJUTA_PROJECT_GROUP, NULL, name);
+	node = ianjuta_project_add_node_before (project->project, parent, sibling, ANJUTA_PROJECT_GROUP, NULL, name, NULL);
 
 	return node;
 }
@@ -921,7 +368,7 @@ anjuta_pm_project_add_target (AnjutaPmProject *project, AnjutaProjectNode *paren
 	
 	g_return_val_if_fail (project->project != NULL, NULL);
 
-	pm_project_push_command (project, ADD, parent, sibling, ANJUTA_PROJECT_TARGET | type, NULL, name);
+	node = ianjuta_project_add_node_before (project->project, parent, sibling, ANJUTA_PROJECT_TARGET | type, NULL, name, NULL);
 
 	return node;
 }
@@ -933,7 +380,7 @@ anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *paren
 
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	pm_project_push_command (project, ADD, parent, sibling, ANJUTA_PROJECT_SOURCE, NULL, name);
+	node = ianjuta_project_add_node_before (project->project, parent, sibling, ANJUTA_PROJECT_SOURCE, NULL, name, NULL);
 
 	return node;
 }
@@ -941,7 +388,7 @@ anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *paren
 gboolean
 anjuta_pm_project_remove (AnjutaPmProject *project, AnjutaProjectNode *node, GError **error)
 {
-	pm_project_push_command (project, REMOVE, node, NULL, 0, NULL, NULL);
+	ianjuta_project_remove_node (project->project, node, NULL);
 
 	return TRUE;
 }
@@ -960,8 +407,6 @@ anjuta_pm_project_set_properties (AnjutaPmProject *project, AnjutaProjectNode *n
 		if (!valid) break;
 	}
 	
-	if (valid) pm_project_push_command (project, SAVE, node, NULL, 0, NULL, NULL);
-	
 	return valid;
 }
 
@@ -982,7 +427,6 @@ anjuta_pm_project_remove_data (AnjutaPmProject *project, GbfTreeData *data, GErr
 	}
 }
 
-
 gboolean
 anjuta_pm_project_is_open (AnjutaPmProject *project)
 {
@@ -1088,7 +532,7 @@ anjuta_pm_project_show_properties_dialog (AnjutaPmProject *project, GbfTreeData
 			node);
 		if (*dialog_ptr != NULL)
 		{
-			g_object_add_weak_pointer (*dialog_ptr, dialog_ptr);
+			g_object_add_weak_pointer (G_OBJECT (*dialog_ptr), (gpointer *)dialog_ptr);
 		}
 	}
 
@@ -1105,16 +549,9 @@ anjuta_pm_project_init (AnjutaPmProject *project)
 {
 	project->model = gbf_project_model_new (NULL);
 	project->plugin = NULL;
+	project->loaded = FALSE;
 
 	project->properties_dialog = NULL;
-	
-	project->job_queue = NULL;
-	project->work_queue = NULL;
-	project->done_queue = NULL;
-	project->worker = NULL;
-	project->idle_func = 0;
-	project->stopping = FALSE;
-	project->busy = 0;
 }
 
 static void
diff --git a/plugins/project-manager/project.h b/plugins/project-manager/project.h
index 462ef31..f86e674 100644
--- a/plugins/project-manager/project.h
+++ b/plugins/project-manager/project.h
@@ -63,18 +63,11 @@ struct _AnjutaPmProject
 	AnjutaProjectNode *root;
 	
 	guint incomplete_node;
+
+	gboolean loaded;
 	
 	/* project properties dialog */
 	GtkWidget *properties_dialog;
-	
-	/* Thread queue */
-	GQueue *job_queue;
-	GAsyncQueue *work_queue;
-	GAsyncQueue *done_queue;
-	GThread *worker;
-	guint idle_func;
-	gboolean stopping;
-	guint busy;
 };
 
 GType anjuta_pm_project_get_type (void) G_GNUC_CONST;



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