[anjuta] pm: Remove all use of ids (in shortcuts and properties dialog)



commit 3f040b14e7be15fd4a9f60c6ac5f7ef4922dce06
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Thu Jan 7 22:15:29 2010 +0100

    pm: Remove all use of ids (in shortcuts and properties dialog)

 plugins/project-manager/gbf-project-model.c |  440 +++++++++++++++++----------
 plugins/project-manager/gbf-project-model.h |    6 +-
 plugins/project-manager/gbf-project-util.c  |   35 +--
 plugins/project-manager/gbf-project-util.h  |   10 +-
 plugins/project-manager/gbf-project-view.c  |   60 +++-
 plugins/project-manager/gbf-project-view.h  |    2 +
 plugins/project-manager/gbf-tree-data.c     |  210 ++++++++++----
 plugins/project-manager/gbf-tree-data.h     |   40 ++--
 plugins/project-manager/plugin.c            |  370 +++++++++-------------
 plugins/project-manager/plugin.h            |    4 +-
 10 files changed, 680 insertions(+), 497 deletions(-)
---
diff --git a/plugins/project-manager/gbf-project-model.c b/plugins/project-manager/gbf-project-model.c
index c42e56b..30aea8d 100644
--- a/plugins/project-manager/gbf-project-model.c
+++ b/plugins/project-manager/gbf-project-model.c
@@ -89,6 +89,27 @@ static GtkTreeStoreClass *parent_class = NULL;
 
 /* Implementation ---------------- */
 
+/* Helper functions */
+
+static void
+my_gtk_tree_model_foreach_child (GtkTreeModel *const model,
+                           GtkTreeIter *const parent,
+                           GtkTreeModelForeachFunc func,
+                           gpointer user_data)
+{
+  GtkTreeIter iter;
+  gboolean success = gtk_tree_model_iter_children(model, &iter, parent);
+  while(success)
+  {
+    if(gtk_tree_model_iter_has_child(model, &iter))
+        my_gtk_tree_model_foreach_child (model, &iter, func, NULL);
+
+        success = (!func(model, NULL, &iter, user_data) &&
+               gtk_tree_model_iter_next (model, &iter));
+  }
+}
+
+
 /* Type & interfaces initialization */
 
 static void
@@ -258,34 +279,38 @@ gbf_project_model_instance_init (GbfProjectModel *model)
 /* Model data functions ------------ */
 
 static gboolean
-gbf_project_model_remove (GbfProjectModel *model, GtkTreeIter *iter)
+gbf_project_model_remove_node (GtkTreeModel *model,
+    GtkTreePath *path,
+    GtkTreeIter *iter,
+    gpointer user_data)
 {
 	GbfTreeData *data;
 	
-	gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
+	gtk_tree_model_get (model, iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 			    -1);
 	if (data != NULL) gbf_tree_data_free (data);
-
-	return gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+	
+	return FALSE;
 }
 
 static gboolean
-gbf_project_model_remove_node (GtkTreeModel *model,
-    GtkTreePath *path,
-    GtkTreeIter *iter,
-    gpointer user_data)
+gbf_project_model_remove (GbfProjectModel *model, GtkTreeIter *iter)
 {
 	GbfTreeData *data;
 	
-	gtk_tree_model_get (model, iter,
+	gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 			    -1);
 	if (data != NULL) gbf_tree_data_free (data);
-	
-	return FALSE;
+
+	/* Free all children */
+	my_gtk_tree_model_foreach_child (GTK_TREE_MODEL (model), iter, gbf_project_model_remove_node, NULL);
+
+	return gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
 }
 
+
 static void
 gbf_project_model_clear (GbfProjectModel *model)
 {
@@ -310,17 +335,26 @@ default_sort_func (GtkTreeModel *model,
 			    -1);
 
 	if (data_a->is_shortcut && data_b->is_shortcut) {
-		GList *l;
+		GtkTreeIter iter;
+		gboolean valid;
 		
 		/* special case: the order of shortcuts is
 		 * user customizable */
-		for (l = GBF_PROJECT_MODEL (model)->priv->shortcuts; l; l = l->next) {
-			if (l->data == data_a->id) {
+		for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
+		    valid == TRUE;
+		    valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
+		{
+			GbfTreeData *data;
+			
+			gtk_tree_model_get (model, &iter,
+				    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+				    -1);
+			if (data == data_a) {
 				/* a comes first */
 				retval = -1;
 				break;
 			}
-			else if (l->data == data_b->id) {
+			else if (data == data_b) {
 				/* b comes first */
 				retval = 1;
 				break;
@@ -360,63 +394,23 @@ add_source (GbfProjectModel    	      *model,
 	if ((!source) || (anjuta_project_node_get_type (source) != ANJUTA_PROJECT_SOURCE))
 		return;
 	
-	data = gbf_tree_data_new_source (model->priv->proj, source);
+	data = gbf_tree_data_new_source (source);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
 }
 
-static GtkTreePath *
-find_shortcut (GbfProjectModel *model, const AnjutaProjectTarget *target)
-{
-	GList *l;
-	gint i;
-	
-	for (l = model->priv->shortcuts, i = 0; l; l = l->next, i++) {
-		if (target == l->data)
-			return gtk_tree_path_new_from_indices (i, -1);
-	}
-	return NULL;
-}
-
-static void
-remove_shortcut (GbfProjectModel *model, const AnjutaProjectTarget *target)
-{
-	GList *l;
-	
-	for (l = model->priv->shortcuts; l; l = l->next) {
-		if (target == l->data) {
-			model->priv->shortcuts = g_list_delete_link (
-				model->priv->shortcuts, l);
-			break;
-		}
-	}
-}
-
-static void
-update_shortcut (GbfProjectModel *model, const AnjutaProjectTarget *new_target, const AnjutaProjectTarget *old_target)
-{
-	GList *l;
-	
-	for (l = model->priv->shortcuts; l; l = l->next) {
-		if (old_target == l->data) {
-			l->data = (gpointer)new_target;
-			break;
-		}
-	}
-}
-
 static void 
 add_target_shortcut (GbfProjectModel *model,
-		     AnjutaProjectTarget *target,
+		     GbfTreeData     *target,
 		     GtkTreePath     *before_path)
 {
 	AnjutaProjectNode *node;
 	GtkTreeIter iter, sibling;
-	GtkTreePath *root_path, *old_path;
-	gint *path_indices, i;
+	GtkTreePath *root_path;
 	GbfTreeData *data;
+	AnjutaProjectNode *parent;
 	
 	if (!target)
 		return;
@@ -434,41 +428,78 @@ add_target_shortcut (GbfProjectModel *model,
 		gtk_tree_path_free (root_path);
 		return;
 	}
-	
-	path_indices = gtk_tree_path_get_indices (before_path);
-	i = path_indices [0];
-
-	/* remove the old shortcut to make sorting actually work */
-	old_path = find_shortcut (model, target);
-	if (old_path) {
-		remove_shortcut (model, target);
-		if (gtk_tree_path_compare (old_path, before_path) < 0) {
-			/* adjust shortcut insert position if the old
-			 * index was before the new site */
-			i--;
-		}
-		gtk_tree_path_free (old_path);
+
+	if (target->type != GBF_TREE_NODE_SHORTCUT)
+	{
+		data = gbf_tree_data_new_shortcut (target);
+	}
+	else
+	{
+		data = target;
 	}
-			
-	/* add entry to the shortcut list */
-	model->priv->shortcuts = g_list_insert (model->priv->shortcuts,
-						target, i);
-	
-	data = gbf_tree_data_new_target (model->priv->proj, target);
-	data->is_shortcut = TRUE;
 	gtk_tree_store_insert_before (GTK_TREE_STORE (model), &iter, NULL, &sibling);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
 			    -1);
 	
 	/* add sources */
-	for (node = anjuta_project_node_first_child (target); node; node = anjuta_project_node_next_sibling (node))
+	parent = gbf_tree_data_get_node (target, model->priv->proj);
+	for (node = anjuta_project_node_first_child (parent); node; node = anjuta_project_node_next_sibling (node))
 		add_source (model, node, &iter);
 
 	gtk_tree_path_free (root_path);
 }
 
 static void 
+move_target_shortcut (GbfProjectModel *model,
+		     GtkTreeIter     *iter,
+    		     GbfTreeData     *shortcut,
+		     GtkTreePath     *before_path)
+{
+	AnjutaProjectNode *node;
+	GtkTreeIter sibling;
+	GtkTreePath *root_path;
+	GtkTreePath *src_path;
+	AnjutaProjectNode *parent;
+	
+	if (!shortcut)
+		return;
+
+	root_path = gtk_tree_row_reference_get_path (model->priv->root_row);
+	/* check before_path */
+	if (!before_path ||
+	    gtk_tree_path_get_depth (before_path) > 1 ||
+	    gtk_tree_path_compare (before_path, root_path) > 0) {
+		before_path = root_path;
+	}
+		
+	/* get the tree iter for the row before which to insert the shortcut */
+	if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &sibling, before_path)) {
+		gtk_tree_path_free (root_path);
+		return;
+	}
+
+	src_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
+	if (gtk_tree_path_compare (src_path, before_path) != 0)
+	{
+		gtk_tree_store_remove (GTK_TREE_STORE (model), iter);			
+		gtk_tree_store_insert_before (GTK_TREE_STORE (model), iter, NULL, &sibling);
+		gtk_tree_store_set (GTK_TREE_STORE (model), iter, 
+				    GBF_PROJECT_MODEL_COLUMN_DATA, shortcut,
+				    -1);
+
+		/* add sources */
+		parent = gbf_tree_data_get_node (shortcut->shortcut, model->priv->proj);
+		for (node = anjuta_project_node_first_child (parent); node; node = anjuta_project_node_next_sibling (node))
+			add_source (model, node, iter);
+	}
+
+	gtk_tree_path_free (src_path);
+	gtk_tree_path_free (root_path);
+
+}
+
+static void 
 add_target (GbfProjectModel 		*model,
 	    AnjutaProjectTarget   *target,
 	    GtkTreeIter     	        *parent)
@@ -480,7 +511,7 @@ add_target (GbfProjectModel 		*model,
 	if ((!target) || (anjuta_project_node_get_type (target) != ANJUTA_PROJECT_TARGET))
 		return;
 	
-	data = gbf_tree_data_new_target (model->priv->proj, target);
+	data = gbf_tree_data_new_target (target);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
@@ -504,7 +535,7 @@ add_target (GbfProjectModel 		*model,
 		case ANJUTA_TARGET_EXECUTABLE:
 		case ANJUTA_TARGET_PYTHON:
 		case ANJUTA_TARGET_JAVA:
-			add_target_shortcut (model, target, NULL);
+			add_target_shortcut (model, data, NULL);
 			break;
 		default:
 			break;
@@ -523,7 +554,7 @@ add_target_group (GbfProjectModel 	*model,
 	if ((!group) || (anjuta_project_node_get_type (group) != ANJUTA_PROJECT_GROUP))
 		return;
 	
-	data = gbf_tree_data_new_group (model->priv->proj, group);
+	data = gbf_tree_data_new_group (group);
 	gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
 			    GBF_PROJECT_MODEL_COLUMN_DATA, data,
@@ -582,8 +613,6 @@ update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *ite
 
 			if (data != NULL)
 			{
-				tree_data->id = data;
-
 				/* Remove from the new node list */
 				node = g_list_find (nodes, data);
 				if (node != NULL)
@@ -591,10 +620,6 @@ update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *ite
 					nodes = g_list_delete_link (nodes, node);
 				}
 
-				/* Update shortcut */
-				if (tree_data->is_shortcut)
-					update_shortcut (model, data, tree_data->id);
-	
 				/* update recursively */
 				update_tree (model, data, &child);
 				
@@ -602,10 +627,6 @@ update_tree (GbfProjectModel *model, AnjutaProjectNode *parent, GtkTreeIter *ite
 			}
 			else
 			{
-				/* Remove shortcut */
-				if (tree_data->is_shortcut)
-					remove_shortcut (model, tree_data->id);
-	
 				/* update recursively */
 				update_tree (model, data, &child);
 				
@@ -695,27 +716,26 @@ unload_project (GbfProjectModel *model)
 static gboolean 
 recursive_find_id (GtkTreeModel   	*model,
 		   GtkTreeIter     	*iter,
-		   GbfTreeNodeType  	 type,
-		   AnjutaProjectNode	*id)
+		   GbfTreeData  	*data)
 {
 	GtkTreeIter tmp;
-	GbfTreeData *data;
 	gboolean retval = FALSE;
 
 	tmp = *iter;
 	
 	do {
 		GtkTreeIter child;
+		GbfTreeData *tmp_data;
 		
 		gtk_tree_model_get (model, &tmp,
-				    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
-		if (id == data->id) {
+				    GBF_PROJECT_MODEL_COLUMN_DATA, &tmp_data, -1);
+		if (tmp_data == data) {
 			*iter = tmp;
 			retval = TRUE;
 		}
 		
 		if (gtk_tree_model_iter_children (model, &child, &tmp)) {
-			if (recursive_find_id (model, &child, type, id)) {
+			if (recursive_find_id (model, &child, data)) {
 				*iter = child;
 				retval = TRUE;
 			}
@@ -729,8 +749,7 @@ recursive_find_id (GtkTreeModel   	*model,
 gboolean 
 gbf_project_model_find_id (GbfProjectModel 	*model,
 			   GtkTreeIter     	*iter,
-			   GbfTreeNodeType  	 type,
-			   AnjutaProjectNode   *id)
+			   GbfTreeData  	*data)
 {
 	GtkTreePath *root;
 	GtkTreeIter tmp_iter;
@@ -741,7 +760,7 @@ gbf_project_model_find_id (GbfProjectModel 	*model,
 		return FALSE;
 
 	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &tmp_iter, root)) {
-		if (recursive_find_id (GTK_TREE_MODEL (model), &tmp_iter, type, id)) {
+		if (recursive_find_id (GTK_TREE_MODEL (model), &tmp_iter, data)) {
 			retval = TRUE;
 			*iter = tmp_iter;
 		}
@@ -751,6 +770,148 @@ gbf_project_model_find_id (GbfProjectModel 	*model,
 	return retval;
 }
 
+static GbfTreeData *
+recursive_find_group (GtkTreeModel   	*model,
+		   GtkTreeIter     	*parent,
+    		   GtkTreeIter		*found,
+		   GFile		*file)
+{
+	GtkTreeIter iter;
+	gboolean next;
+	GbfTreeData *data = NULL;
+
+	for (next = gtk_tree_model_iter_children (model, &iter, parent);
+	    next;
+	    next = gtk_tree_model_iter_next (model, &iter))
+	{
+		gtk_tree_model_get (model, &iter,
+		    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+
+		if (data->type == GBF_TREE_NODE_SHORTCUT)
+		{
+			data = data->shortcut;
+		}
+		if ((data->type == GBF_TREE_NODE_GROUP) && (data->group != NULL) && g_file_equal (data->group, file))
+		{
+			if (found != NULL) *found = iter;
+			return data;
+		}
+
+		data = recursive_find_group (model, &iter, found, file);
+		if (data != NULL) return data;
+	}
+
+	return NULL;
+}
+
+static GbfTreeData *
+recursive_find_target (GtkTreeModel   	*model,
+		   GtkTreeIter     	*parent,
+    		   GtkTreeIter		*found,
+		   const gchar	        *name)
+{
+	GtkTreeIter iter;
+	gboolean next;
+	GbfTreeData *data = NULL;
+
+	for (next = gtk_tree_model_iter_children (model, &iter, parent);
+	    next;
+	    next = gtk_tree_model_iter_next (model, &iter))
+	{
+		gtk_tree_model_get (model, &iter,
+		    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+
+		if (data->type == GBF_TREE_NODE_SHORTCUT)
+		{
+			data = data->shortcut;
+		}
+		if ((data->type == GBF_TREE_NODE_TARGET) && (data->name != NULL) && (strcmp (data->name, name) == 0))
+		{
+			if (found != NULL) *found = iter;
+			return data;
+		}
+		else
+		{
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+static GbfTreeData *
+recursive_find_source (GtkTreeModel   	*model,
+		   GtkTreeIter     	*parent,
+		   GtkTreeIter     	*found,
+		   GFile		*file)
+{
+	GtkTreeIter iter;
+	gboolean next;
+	GbfTreeData *data = NULL;
+
+	for (next = gtk_tree_model_iter_children (model, &iter, parent);
+	    next;
+	    next = gtk_tree_model_iter_next (model, &iter))
+	{
+		gtk_tree_model_get (model, &iter,
+		    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+
+		if (data->type == GBF_TREE_NODE_SHORTCUT)
+		{
+			data = data->shortcut;
+		}
+		if ((data->type == GBF_TREE_NODE_SOURCE) && (data->source != NULL) && g_file_equal (data->source, file))
+		{
+			if (found != NULL) *found = iter;
+			return data;
+		}
+		
+		data = recursive_find_group (model, &iter, found, file);
+		if (data != NULL) return data;
+	}
+
+	return NULL;
+}
+
+GbfTreeData*
+gbf_project_model_find_uri (GbfProjectModel     *model,
+    			    const gchar         *uri,
+    			    GbfTreeNodeType     type)
+{
+	GFile *file;
+	GFile *group;
+	gchar *name;
+	GbfTreeData *data = NULL;
+	GtkTreeIter iter;
+
+	file = g_file_new_for_uri (uri);
+	switch (type)
+	{
+	case GBF_TREE_NODE_SOURCE:
+		data = recursive_find_source (GTK_TREE_MODEL (model), NULL, NULL, file);
+		break;
+	case GBF_TREE_NODE_GROUP:
+		data = recursive_find_group (GTK_TREE_MODEL (model), NULL, NULL, file);
+		break;
+	case GBF_TREE_NODE_TARGET:
+		group = g_file_get_parent (file);
+		name = g_file_get_basename (file);
+		if (recursive_find_group (GTK_TREE_MODEL (model), NULL, &iter, group))
+		{
+			data = recursive_find_target (GTK_TREE_MODEL (model), &iter, NULL, name);
+		}
+		g_free (name);
+		g_object_unref (group);
+		break;
+	default:
+		break;
+	}
+		
+	g_object_unref (file);
+
+	return data;
+}
+
 GbfProjectModel *
 gbf_project_model_new (IAnjutaProject *project)
 {
@@ -798,55 +959,12 @@ gbf_project_model_get_node (GbfProjectModel *model,
                             GtkTreeIter     *iter)
 {
 	GbfTreeData *data = NULL;
-	AnjutaProjectNode *parent = NULL;
-	AnjutaProjectNode *node = NULL;
-	GtkTreeIter piter;
-	GFile *file;
 	
 	gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 			    -1);
-	if (data != NULL)
-	{
-		switch (data->type)
-		{
-		case GBF_TREE_NODE_GROUP:
-			file = g_file_new_for_uri (data->uri);
-			if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &piter, iter))
-				parent = gbf_project_model_get_node (model, &piter);
-			node = anjuta_project_group_get_node_from_file (parent == NULL ? ianjuta_project_get_root (model->priv->proj, NULL) : parent, file);
-			g_object_unref (file);
-			break;
-		case GBF_TREE_NODE_TARGET:
-			if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &piter, iter))
-			{
-				parent = gbf_project_model_get_node (model, &piter);
-			}
-			else
-			{
-				file = g_file_new_for_uri (data->uri);
-				parent = anjuta_project_group_get_node_from_file (ianjuta_project_get_root (model->priv->proj, NULL), file);
-				g_object_unref (file);
-			}
-	        	if (parent) node = anjuta_project_target_get_node_from_name (parent, data->name);
-			break;
-		case GBF_TREE_NODE_SOURCE:
-			if (!gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &piter, iter))
-				break;
-			parent = gbf_project_model_get_node (model, &piter);
-	        	if (parent)
-			{
-				file = g_file_new_for_uri (data->uri);
-				node = anjuta_project_source_get_node_from_file (parent, file);
-				g_object_unref (file);
-			}
-			break;
-		default:
-			break;
-		}
-	}
 
-	return node;
+	return gbf_tree_data_get_node (data, model->priv->proj);
 }
 
 /* DND stuff ------------- */
@@ -870,14 +988,9 @@ row_draggable (GtkTreeDragSource *drag_source, GtkTreePath *path)
 		retval = TRUE;
 
 	} else if (data->type == GBF_TREE_NODE_TARGET) {
-		GtkTreePath *found;
-		
 		/* don't allow duplicate shortcuts */
-		found = find_shortcut (GBF_PROJECT_MODEL (drag_source), data->id);
-		if (!found)
+		if (data->shortcut == NULL)
 			retval = TRUE;
-		else
-			gtk_tree_path_free (found);
 	}
 
 	return retval;
@@ -889,7 +1002,7 @@ drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path)
 	GtkTreeIter iter;
 	gboolean retval = FALSE;
 	
-	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
+	/*if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
 				     &iter, path)) {
 		GbfTreeData *data;
 
@@ -898,10 +1011,10 @@ drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path)
 				    -1);
 
 		if (data->is_shortcut) {
-			gbf_project_model_remove (GBF_PROJECT_MODEL (drag_source), &iter);
+			gtk_tree_store_remove (GTK_TREE_STORE (drag_source), &iter);			
 			retval = TRUE;
 		}
-	}
+	}*/
 	
 	return retval;
 }
@@ -929,9 +1042,18 @@ drag_data_received (GtkTreeDragDest  *drag_dest,
 			gtk_tree_model_get (src_model, &iter,
 					    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 					    -1);
-			if (data && data->id && data->type == GBF_TREE_NODE_TARGET) {
-				add_target_shortcut (GBF_PROJECT_MODEL (drag_dest),
-						     data->id, dest);
+			if (data != NULL)
+			{
+				if (data->type == GBF_TREE_NODE_SHORTCUT)
+				{
+					move_target_shortcut (GBF_PROJECT_MODEL (drag_dest),
+					    		&iter, data, dest);
+				}
+				else
+				{
+					add_target_shortcut (GBF_PROJECT_MODEL (drag_dest),
+						     	data, dest);
+				}
 				retval = TRUE;
 			}
 		}
diff --git a/plugins/project-manager/gbf-project-model.h b/plugins/project-manager/gbf-project-model.h
index f18b0d7..aa73dda 100644
--- a/plugins/project-manager/gbf-project-model.h
+++ b/plugins/project-manager/gbf-project-model.h
@@ -63,8 +63,10 @@ IAnjutaProject  *gbf_project_model_get_project       (GbfProjectModel   *model);
 GtkTreePath     *gbf_project_model_get_project_root  (GbfProjectModel   *model);
 gboolean         gbf_project_model_find_id           (GbfProjectModel   *model,
                                                       GtkTreeIter       *iter,
-                                                      GbfTreeNodeType    type,
-                                                      AnjutaProjectNode *id);
+                                                      GbfTreeData       *data);
+GbfTreeData     *gbf_project_model_find_uri          (GbfProjectModel   *model,
+                                                      const gchar       *uri,
+                                                      GbfTreeNodeType   type);
 AnjutaProjectNode *gbf_project_model_get_node        (GbfProjectModel *model,
                                                       GtkTreeIter     *iter);
 
diff --git a/plugins/project-manager/gbf-project-util.c b/plugins/project-manager/gbf-project-util.c
index a36f397..88d37ea 100644
--- a/plugins/project-manager/gbf-project-util.c
+++ b/plugins/project-manager/gbf-project-util.c
@@ -77,7 +77,7 @@ groups_filter_fn (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
 static void 
 setup_groups_treeview (GbfProjectModel    *model,
                        GtkWidget          *view,
-                       AnjutaProjectGroup *select_group)
+                       GbfTreeData        *select_group)
 {
     GtkTreeModel *filter;
     GtkTreePath *path;
@@ -93,8 +93,7 @@ setup_groups_treeview (GbfProjectModel    *model,
     g_object_unref (filter);
     
     /* select default group */
-    if (select_group && gbf_project_model_find_id (model, &iter,
-                                                   GBF_TREE_NODE_GROUP, select_group)) {
+    if (select_group && gbf_project_model_find_id (model, &iter, select_group)) {
         GtkTreeIter iter_filter;
 
         gtk_tree_model_filter_convert_child_iter_to_iter (
@@ -165,7 +164,7 @@ entry_changed_cb (GtkEditable *editable, gpointer user_data)
 AnjutaProjectGroup*
 gbf_project_util_new_group (GbfProjectModel    *model,
                             GtkWindow          *parent,
-                            AnjutaProjectGroup *default_group,
+                            GbfTreeData        *default_group,
                             const gchar        *default_group_name_to_add)
 {
     GtkBuilder *gui;
@@ -305,7 +304,7 @@ build_types_store (IAnjutaProject *project)
 AnjutaProjectTarget* 
 gbf_project_util_new_target (GbfProjectModel *model,
                              GtkWindow       *parent,
-                             AnjutaProjectGroup *default_group,
+                             GbfTreeData     *default_group,
                              const gchar     *default_target_name_to_add)
 {
     GtkBuilder *gui;
@@ -452,8 +451,7 @@ targets_filter_fn (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
 static void 
 setup_targets_treeview (GbfProjectModel     *model,
                         GtkWidget           *view,
-                        AnjutaProjectTarget *select_target,
-                        AnjutaProjectGroup  *select_group)
+                        GbfTreeData         *select_target)
 {
     GtkTreeModel *filter;
     GtkTreeIter iter, iter_filter;
@@ -470,19 +468,12 @@ setup_targets_treeview (GbfProjectModel     *model,
 
     /* select default target */
     if (select_target) {
-        if (gbf_project_model_find_id (model, &iter,
-                                       GBF_TREE_NODE_TARGET, select_target)) {
+        if (gbf_project_model_find_id (model, &iter, select_target))
+        {
             gtk_tree_model_filter_convert_child_iter_to_iter (
                 GTK_TREE_MODEL_FILTER (filter), &iter_filter, &iter);
             path = gtk_tree_model_get_path (filter, &iter_filter);
         }
-    } else if (select_group) {
-        if (gbf_project_model_find_id (model, &iter,
-                                       GBF_TREE_NODE_GROUP, select_group)) {
-            gtk_tree_model_filter_convert_child_iter_to_iter (
-                  GTK_TREE_MODEL_FILTER (filter), &iter_filter, &iter);
-            path = gtk_tree_model_get_path (filter, &iter_filter);
-        }
     }
     if (path)
     {
@@ -582,8 +573,7 @@ on_row_changed(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpoint
 AnjutaProjectSource*
 gbf_project_util_add_source (GbfProjectModel     *model,
                              GtkWindow           *parent,
-                             AnjutaProjectTarget *default_target,
-                             AnjutaProjectGroup  *default_group,
+                             GbfTreeData         *default_target,
                              const gchar         *default_uri)
 {
         GList* new_sources;
@@ -596,8 +586,7 @@ gbf_project_util_add_source (GbfProjectModel     *model,
         }
 	new_sources = 
 		gbf_project_util_add_source_multi (model, parent,
-                                                   default_target,
-                                                   default_group, uris);
+                                                   default_target, uris);
 	g_free (uri);
         g_list_free (uris);
 	
@@ -614,8 +603,7 @@ gbf_project_util_add_source (GbfProjectModel     *model,
 GList* 
 gbf_project_util_add_source_multi (GbfProjectModel     *model,
 				   GtkWindow           *parent,
-                                   AnjutaProjectTarget *default_target,
-                                   AnjutaProjectGroup  *default_group,
+                                   GbfTreeData         *default_target,
 				   GList               *uris_to_add)
 {
     GtkBuilder *gui;
@@ -692,8 +680,7 @@ gbf_project_util_add_source_multi (GbfProjectModel     *model,
     g_object_set_data_full (G_OBJECT (browse_button), "root",
                             project_root, g_free);
     
-    setup_targets_treeview (model, targets_view, default_target,
-			    default_group);
+    setup_targets_treeview (model, targets_view, default_target);
     gtk_widget_show (targets_view);
     
     if (parent) {
diff --git a/plugins/project-manager/gbf-project-util.h b/plugins/project-manager/gbf-project-util.h
index f859f70..26024d5 100644
--- a/plugins/project-manager/gbf-project-util.h
+++ b/plugins/project-manager/gbf-project-util.h
@@ -32,24 +32,22 @@ G_BEGIN_DECLS
 
 AnjutaProjectGroup* gbf_project_util_new_group  (GbfProjectModel   *model,
 				                GtkWindow          *parent,
-				                AnjutaProjectGroup *default_group,
+				                GbfTreeData        *default_group,
 				                const gchar        *default_group_name_to_add);
 
 AnjutaProjectTarget* gbf_project_util_new_target (GbfProjectModel  *model,
 				                GtkWindow          *parent,
-				                AnjutaProjectGroup *default_group,
+				                GbfTreeData        *default_group,
 				                const gchar        *default_target_name_to_add);
 
 AnjutaProjectSource* gbf_project_util_add_source (GbfProjectModel   *model,
 				                GtkWindow           *parent,
-				                AnjutaProjectTarget *default_target,
-				                AnjutaProjectGroup  *default_group,
+				                GbfTreeData         *default_target,
 				                const gchar         *default_uri_to_add);
 
 GList* gbf_project_util_add_source_multi (GbfProjectModel   *model,
 				        GtkWindow           *parent,
-        		                AnjutaProjectTarget *default_target,
-				        AnjutaProjectGroup  *default_group,
+        		                GbfTreeData         *default_target,
 				        GList               *uris_to_add);
 				    
 GList * gbf_project_util_all_child (AnjutaProjectNode *parent,
diff --git a/plugins/project-manager/gbf-project-view.c b/plugins/project-manager/gbf-project-view.c
index cfe3901..130f1d4 100644
--- a/plugins/project-manager/gbf-project-view.c
+++ b/plugins/project-manager/gbf-project-view.c
@@ -73,6 +73,7 @@ row_activated (GtkTreeView       *tree_view,
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	GbfTreeData *data;
+	gchar *uri;
 	
 	model = gtk_tree_view_get_model (tree_view);
 
@@ -82,23 +83,25 @@ row_activated (GtkTreeView       *tree_view,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
 			    -1);
 
-	if (data->uri) {
+	uri = gbf_tree_data_get_uri (data);
+	if (uri != NULL) {
 		g_signal_emit (G_OBJECT (tree_view), 
 			       signals [URI_ACTIVATED], 0,
-			       data->uri);
+			       uri);
 	}
 
 	if (data->type == GBF_TREE_NODE_TARGET) {
 		g_signal_emit (G_OBJECT (tree_view),
 			       signals [TARGET_SELECTED], 0,
-			       data->name);
+			       uri);
 	}
 	
 	if (data->type == GBF_TREE_NODE_GROUP) {
 		g_signal_emit (G_OBJECT (tree_view),
 			       signals [GROUP_SELECTED], 0,
-			       data->uri);
+			       uri);
 	}
+	g_free (uri);
 }
 
 static void
@@ -120,17 +123,15 @@ destroy (GtkObject *object)
 }
 
 static GdkPixbuf*
-get_icon (const gchar* uri)
+get_icon (GFile *file)
 {
 	const gchar** icon_names;
 	GtkIconInfo* icon_info;
 	GIcon* icon;
 	GdkPixbuf* pixbuf = NULL;
-	GFile* file;
 	GFileInfo* file_info;
 	GError *error = NULL;
 	
-	file = g_file_new_for_uri (uri);
 	file_info = g_file_query_info (file,
 				       G_FILE_ATTRIBUTE_STANDARD_ICON,
 				       G_FILE_QUERY_INFO_NONE,
@@ -139,7 +140,10 @@ get_icon (const gchar* uri)
 
 	if (!file_info)
 	{
-		g_warning (G_STRLOC ": Unable to query information for URI: %s: %s", uri, error->message);
+		gchar *name = g_file_get_parse_name (file);
+		
+		g_warning (G_STRLOC ": Unable to query information for URI: %s: %s", name, error->message);
+		g_free (name);
 		g_clear_error (&error);
 		return NULL;
 	}
@@ -152,6 +156,7 @@ get_icon (const gchar* uri)
 						GTK_ICON_LOOKUP_GENERIC_FALLBACK);
 	pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
 	gtk_icon_info_free(icon_info);
+	g_object_unref (file_info);
 	
 	return pixbuf;
 }
@@ -169,11 +174,15 @@ set_pixbuf (GtkTreeViewColumn *tree_column,
 	gtk_tree_model_get (model, iter,
 			    GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
 	g_return_if_fail (data != NULL);
-	
+
+	if (data->type == GBF_TREE_NODE_SHORTCUT)
+	{
+		data = data->shortcut;
+	}
 	switch (data->type) {
 		case GBF_TREE_NODE_SOURCE:
 		{
-			pixbuf = get_icon (data->uri);
+			pixbuf = get_icon (data->source);
 			break;
 		}
 		case GBF_TREE_NODE_GROUP:
@@ -396,3 +405,34 @@ gbf_project_view_find_selected (GbfProjectView *view, AnjutaProjectNodeType type
 	return node;
 }
 
+GbfTreeData *
+gbf_project_view_get_selected (GbfProjectView *view)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GbfTreeData *data;
+
+	g_return_val_if_fail (view != NULL, FALSE);
+	g_return_val_if_fail (GBF_IS_PROJECT_VIEW (view), FALSE);
+	
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		if (GTK_IS_TREE_MODEL_FILTER (model))
+		{
+			GtkTreeIter child_iter;
+			
+			gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
+			iter = child_iter;			
+		}
+		
+	
+		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+			    GBF_PROJECT_MODEL_COLUMN_DATA, &data,
+			    -1);
+	}
+
+	return data;
+}
+
diff --git a/plugins/project-manager/gbf-project-view.h b/plugins/project-manager/gbf-project-view.h
index 99c9ba4..8909624 100644
--- a/plugins/project-manager/gbf-project-view.h
+++ b/plugins/project-manager/gbf-project-view.h
@@ -63,6 +63,8 @@ GtkWidget                  *gbf_project_view_new              (void);
 
 AnjutaProjectNode          *gbf_project_view_find_selected    (GbfProjectView *view,
 							       AnjutaProjectNodeType type);
+GbfTreeData                *gbf_project_view_get_selected      (GbfProjectView *view);
+
 
 G_END_DECLS
 
diff --git a/plugins/project-manager/gbf-tree-data.c b/plugins/project-manager/gbf-tree-data.c
index b13d2b0..36465fe 100644
--- a/plugins/project-manager/gbf-tree-data.c
+++ b/plugins/project-manager/gbf-tree-data.c
@@ -1,7 +1,7 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /* gbf-tree-data.c
  *
- * Copyright (C) 2000  JP Rosevear
+ * Copyright (C) 2010  Sébastien Granjoux
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -17,8 +17,6 @@
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
- *
- * Author: JP Rosevear
  */
 
 #ifdef HAVE_CONFIG_H
@@ -28,28 +26,124 @@
 #include <gio/gio.h>
 #include "gbf-tree-data.h"
 
+/**
+ * The GbfTreeData object store all data needed by each element of the project
+ * tree view. It has the same role than AnjutaProjectNode in the project
+ * backend and normally there is one GbfTreeData for each AnjutaProjectNode.
+ * 
+ * The GbfTreeData objects do not have a pointer to their corresponding
+ * AnjutaProjectNode because they do not have the same life time. By example
+ * when a project is reloaded all AnjutaProjectNode are destroyed but the
+ * GbfTreeData stay alive. They contain enough information to be able to
+ * find the corresponding AnjutaProjectNode though, but it is a search so
+ * it takes more time.
+ *
+ * Several GbfTreeData can correspond to the same AnjutaProjectNode because
+ * the tree view can contain shortcuts on alreay existing  project node. Each
+ * shortcut has its own GbfTreeData object containing the same data than the
+ * root object.
+ *
+ * The GbfTreeData objects are not owned by the tree view which keeps only
+ * pointer on them. When removing a element in the tree view, it is the
+ * responsability of the routine to free all GbfTreeData objects before. On
+ * the other hand, it must not be freed after getting one pointer from
+ * the tree view.
+ */ 
+
+AnjutaProjectNode *
+gbf_tree_data_get_node (GbfTreeData *data, IAnjutaProject *project)
+{
+	AnjutaProjectNode *node = NULL;
+	
+	if (data != NULL)
+	{
+		AnjutaProjectGroup *root = NULL;
+		AnjutaProjectGroup *group = NULL;
+		AnjutaProjectTarget *target = NULL;
+
+		root = ianjuta_project_get_root (project, NULL);
+		if ((root != NULL) && (data->group != NULL))
+		{
+			group = anjuta_project_group_get_node_from_file (root, data->group);
+			node = group;
+		}
+
+		if ((group != NULL) && (data->target != NULL))
+		{
+			target = anjuta_project_target_get_node_from_name (group, data->target);
+			node = target;
+		}
+
+		if (((group != NULL) || (target != NULL)) && (data->source != NULL))
+		{
+			node = anjuta_project_source_get_node_from_file (target != NULL ? target : group, data->source);
+		}
+	}
+
+	return node;
+}
+
+gchar *
+gbf_tree_data_get_uri (GbfTreeData *data)
+{
+	if (data->source != NULL)
+	{
+		return g_file_get_uri (data->source);
+	}
+	else if (data->target != NULL)
+	{
+		GFile *target;
+		gchar *uri;
+
+		target = g_file_get_child (data->group, data->target);
+		uri = g_file_get_uri (target);
+		g_object_unref (target);
+		
+		return uri;
+	}
+	else if (data->group != NULL)
+	{
+		return g_file_get_uri (data->group);
+	}
+
+	return NULL;
+}
 
 GbfTreeData *
 gbf_tree_data_new_string (const gchar *string)
 {
-	GbfTreeData *node = g_new0 (GbfTreeData, 1);
+	GbfTreeData *data = g_slice_new0 (GbfTreeData);
 	
-	node->type = GBF_TREE_NODE_STRING;
-	node->name = g_strdup (string);
+	data->type = GBF_TREE_NODE_STRING;
+	data->name = g_strdup (string);
 	
-	return node;
+	return data;
 }
 
 GbfTreeData *
-gbf_tree_data_new_group (IAnjutaProject *project, AnjutaProjectGroup *group)
+gbf_tree_data_new_shortcut (GbfTreeData *src)
 {
-	GbfTreeData *node = g_new0 (GbfTreeData, 1);
-	GFileInfo *ginfo;
+	GbfTreeData *data = g_slice_new0 (GbfTreeData);
 
-	node->type = GBF_TREE_NODE_GROUP;
-	node->id = group;
-	node->uri = g_file_get_uri (anjuta_project_group_get_directory (group));
+	data->type = GBF_TREE_NODE_SHORTCUT;
+	data->name = g_strdup (src->name);
+	data->group = src->group == NULL ? NULL : g_object_ref (src->group);
+	data->target = g_strdup (src->target);
+	data->source = src->source == NULL ? NULL : g_object_ref (src->source);
+	data->is_shortcut = TRUE;
+	data->shortcut = src;
+	src->shortcut = data;
 	
+	return data;
+}
+
+GbfTreeData *
+gbf_tree_data_new_group (AnjutaProjectGroup *group)
+{
+	GbfTreeData *data = g_slice_new0 (GbfTreeData);
+	GFileInfo *ginfo;
+
+	data->type = GBF_TREE_NODE_GROUP;
 	
 	ginfo = g_file_query_info (anjuta_project_group_get_directory (group),
 	    G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
@@ -57,86 +151,88 @@ gbf_tree_data_new_group (IAnjutaProject *project, AnjutaProjectGroup *group)
 	    NULL, NULL);
 	if (ginfo)
 	{
-		node->name = g_strdup (g_file_info_get_display_name (ginfo));
+		data->name = g_strdup (g_file_info_get_display_name (ginfo));
 	        g_object_unref(ginfo);
 	}
 	else
 	{
-		node->name = g_strdup ("?");
+		data->name = g_strdup ("?");
 	}
 
-	return node;
+	data->group = g_object_ref (anjuta_project_group_get_directory (group));
+	
+	return data;
 }
 
 GbfTreeData *
-gbf_tree_data_new_target (IAnjutaProject *project, AnjutaProjectTarget *target)
+gbf_tree_data_new_target (AnjutaProjectTarget *target)
 {
-	GbfTreeData *node = g_new0 (GbfTreeData, 1);
+	GbfTreeData *data = g_slice_new0 (GbfTreeData);
 	AnjutaProjectGroup *group;
 	
-	node->type = GBF_TREE_NODE_TARGET;
-	node->id = target;
+	data->type = GBF_TREE_NODE_TARGET;
+	data->name = g_strdup (anjuta_project_target_get_name (target));
 
 	group = (AnjutaProjectGroup *)anjuta_project_node_parent (target);
-	node->uri = g_file_get_uri (anjuta_project_group_get_directory (group));	
-	
-	node->name = g_strdup (anjuta_project_target_get_name (target));
-	node->mime_type = g_strdup (anjuta_project_target_type_mime (anjuta_project_target_get_type (target)));
+	data->group = g_object_ref (anjuta_project_group_get_directory (group));	
+	data->target = g_strdup (anjuta_project_target_get_name (target));
 	
-	return node;
+	return data;
 }
 
 GbfTreeData *
-gbf_tree_data_new_source (IAnjutaProject *project, AnjutaProjectSource *source)
+gbf_tree_data_new_source (AnjutaProjectSource *source)
 {
-	GbfTreeData *node = g_new0 (GbfTreeData, 1);
+	GbfTreeData *data = g_slice_new0 (GbfTreeData);
 	GFileInfo *ginfo;
+	AnjutaProjectNode *parent;
 	
-	node->type = GBF_TREE_NODE_SOURCE;
-	node->id = source;
-	
-	node->uri = g_file_get_uri (anjuta_project_source_get_file (source));
+	data->type = GBF_TREE_NODE_SOURCE;
 
-	ginfo = g_file_query_info (anjuta_project_source_get_file (source),
+	data->source = g_object_ref (anjuta_project_source_get_file (source));
+	
+	ginfo = g_file_query_info (data->source,
 	    G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
 	    G_FILE_QUERY_INFO_NONE,
 	    NULL, NULL);
 	if (ginfo)
 	{
-		node->name = g_strdup (g_file_info_get_display_name (ginfo));
+		data->name = g_strdup (g_file_info_get_display_name (ginfo));
 	        g_object_unref(ginfo);
 	}
 	else
 	{
-		node->name = g_file_get_basename (anjuta_project_source_get_file (source));
+		data->name = g_file_get_basename (data->source);
 	}
 
-	return node;
-}
+	parent = anjuta_project_node_parent (source);
+	if (anjuta_project_node_get_type (parent) == ANJUTA_PROJECT_GROUP)
+	{
+		data->group = g_object_ref (anjuta_project_group_get_directory (parent));
+	}
+	else
+	{
+		AnjutaProjectGroup *group;
+		
+		group = (AnjutaProjectGroup *)anjuta_project_node_parent (parent);
+		data->group = g_object_ref (anjuta_project_group_get_directory (group));
+		data->target = g_strdup (anjuta_project_target_get_name (parent));
+	}
 
-GbfTreeData *
-gbf_tree_data_copy (GbfTreeData *src)
-{
-	GbfTreeData *node;
-
-	node = g_new (GbfTreeData, 1);
-	node->type = src->type;
-	node->name = g_strdup (src->name);
-	node->id = src->id;
-	node->uri = g_strdup (src->uri);
-	node->is_shortcut = src->is_shortcut;
-	node->mime_type = g_strdup (src->mime_type);
-	
-	return node;
+	return data;
 }
 
 void
-gbf_tree_data_free (GbfTreeData *node)
+gbf_tree_data_free (GbfTreeData *data)
 {
-	if (node) {
-		g_free (node->name);
-		g_free (node->uri);
-		g_free (node->mime_type);
-		g_free (node);
+	if (data)
+	{
+		g_free (data->name);
+		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->properties_dialog) gtk_widget_destroy (data->properties_dialog);
+		g_slice_free (GbfTreeData, data);
 	}
 }
diff --git a/plugins/project-manager/gbf-tree-data.h b/plugins/project-manager/gbf-tree-data.h
index ef57130..07d9b2c 100644
--- a/plugins/project-manager/gbf-tree-data.h
+++ b/plugins/project-manager/gbf-tree-data.h
@@ -1,7 +1,7 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /* gbf-tree-data.h
  *
- * Copyright (C) 2000  JP Rosevear
+ * Copyright (C) 2010  Sébastien Granjoux
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -17,14 +17,13 @@
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
- *
- * Author: JP Rosevear
  */
 
 #ifndef _GBF_TREE_DATA_H_
 #define _GBF_TREE_DATA_H_
 
 #include <glib-object.h>
+#include <gtk/gtk.h>
 #include <libanjuta/interfaces/ianjuta-project.h>
 #include <libanjuta/anjuta-project.h>
 
@@ -37,27 +36,32 @@ typedef enum {
 	GBF_TREE_NODE_GROUP,
 	GBF_TREE_NODE_TARGET,
 	GBF_TREE_NODE_SOURCE,
+	GBF_TREE_NODE_SHORTCUT
 } GbfTreeNodeType;
 
 struct _GbfTreeData
 {
 	GbfTreeNodeType  	type;
-	gchar           	*name;
-	AnjutaProjectNode	*id;
-	gchar           	*uri;
-	gboolean         	is_shortcut;
-	gchar           	*mime_type;
+	gchar           *name;
+	GFile			*group;
+	gchar			*target;
+	GFile			*source;
+	gboolean		is_shortcut;
+	GbfTreeData		*shortcut;
+	GtkWidget		*properties_dialog;
 };
 
-GbfTreeData   *gbf_tree_data_new_string          (const gchar            *string);
-GbfTreeData   *gbf_tree_data_new_group           (IAnjutaProject         *project,
-						  AnjutaProjectGroup     *group);
-GbfTreeData   *gbf_tree_data_new_target          (IAnjutaProject         *project,
-						  AnjutaProjectTarget    *target);
-GbfTreeData   *gbf_tree_data_new_source          (IAnjutaProject         *project,
-						  AnjutaProjectSource    *source);
-GbfTreeData   *gbf_tree_data_copy                (GbfTreeData            *data);
-void           gbf_tree_data_free                (GbfTreeData            *data);
+AnjutaProjectNode *gbf_tree_data_get_node	 (GbfTreeData		 *data,
+                                              IAnjutaProject     *project);
+
+gchar	      *gbf_tree_data_get_uri		 (GbfTreeData            *data);
+
+GbfTreeData   *gbf_tree_data_new_string      (const gchar          *string);
+GbfTreeData   *gbf_tree_data_new_shortcut    (GbfTreeData		   *src);
+GbfTreeData   *gbf_tree_data_new_group       (AnjutaProjectGroup   *group);
+GbfTreeData   *gbf_tree_data_new_target      (AnjutaProjectTarget  *target);
+GbfTreeData   *gbf_tree_data_new_source      (AnjutaProjectSource  *source);
+void           gbf_tree_data_free            (GbfTreeData          *data);
 
 
 G_END_DECLS
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 408a08a..99c1ee1 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -349,118 +349,122 @@ update_operation_begin (ProjectManagerPlugin *plugin)
  *---------------------------------------------------------------------------*/
 
 static void
-properties_dialog_info_free (PmPropertiesDialogInfo *info)
+on_properties_dialog_response (GtkDialog *win,
+							   gint id,
+							   GtkWidget **dialog)
 {
-	gtk_widget_destroy (info->dialog);
-	g_free (info);
+	gtk_widget_destroy (*dialog);
+	*dialog = NULL;
 }
 
-static gint
-compare_properties_widget (PmPropertiesDialogInfo *info, GtkWidget *widget)
+static void
+project_manager_create_properties_dialog (ProjectManagerPlugin *plugin,
+    									  GtkWidget **dialog,
+    								      const gchar *title,
+    									  GtkWidget *properties)
 {
-	return info->dialog == widget ? 0 : 1;
-}
+	*dialog = gtk_dialog_new_with_buttons (title,
+							   GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
+							   GTK_DIALOG_DESTROY_WITH_PARENT,
+							   GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL);
 
-static gint
-compare_properties_id (PmPropertiesDialogInfo *info, PmPropertiesDialogInfo *info1)
-{
-	/* project properties have a NULL id */
-	return (info->type == info1->type) &&
-			((info1->id == NULL) ||
-			 ((info->id != NULL) &&
-			  (info->id == info1->id))) ? 0 : 1;
-}
+	g_signal_connect (*dialog, "response",
+					  G_CALLBACK (on_properties_dialog_response),
+					  dialog);
 
-static void
-on_properties_dialog_response (GtkDialog *win,
-							   gint id,
-							   ProjectManagerPlugin *plugin)
-{
-	GList *prop;
-	
-	prop = g_list_find_custom (plugin->prop_dialogs,
-							   win,
-							   (GCompareFunc)compare_properties_widget);
-	if (prop != NULL)
-	{
-		properties_dialog_info_free ((PmPropertiesDialogInfo *)prop->data);
-		plugin->prop_dialogs = g_list_delete_link (plugin->prop_dialogs, prop);
-	}
+	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG(*dialog))),
+			   properties);
+	gtk_window_set_default_size (GTK_WINDOW (*dialog), 450, -1);
+	gtk_widget_show (*dialog);
 }
 
-/* Display properties dialog. These dialogs are not modal, so keep a list of
- * them to be able to destroy them if the project is closed. This list is
- * useful to put the dialog at the top if the same target is selected while
- * the corresponding dialog already exist instead of creating two times the
- * same dialog */
+/* Display properties dialog. These dialogs are not modal, so a pointer on each
+ * dialog is kept with in node data to be able to destroy them if the node is
+ * removed. It is useful to put the dialog at the top if the same target is
+ * selected while the corresponding dialog already exist instead of creating
+ * two times the same dialog.
+ * The project properties dialog is display if the node iterator is NULL. */
 
 static void
-project_manager_show_properties_dialog (ProjectManagerPlugin *plugin,
-										PmPropertiesType type,
-										AnjutaProjectNode *id)
+project_manager_show_node_properties_dialog (ProjectManagerPlugin *plugin,
+    									GbfTreeData *data)
 {
-	PmPropertiesDialogInfo info;
-	GList* prop;
-		
-	info.type = type;
-	info.id = id; 
-	prop = g_list_find_custom (plugin->prop_dialogs,
-							   &info,
-							   (GCompareFunc)compare_properties_id);
-	if (prop != NULL)
+	if (data == NULL) return;
+
+	if (data->is_shortcut) data = data->shortcut;
+	
+	if (data->properties_dialog != NULL)
 	{
 		/* Show already existing dialog */
-
-		gtk_window_present (GTK_WINDOW (((PmPropertiesDialogInfo *)prop->data)->dialog));
+		gtk_window_present (GTK_WINDOW (data->properties_dialog));
 	}
 	else
 	{
-		/* Create new dialog */
-		GtkWidget *win;
 		GtkWidget *properties = NULL;
-		const char* title = NULL;
-		
-		switch (type)
+		const char *title;
+		AnjutaProjectNode *node;
+
+		switch (data->type)
 		{
-			case PM_PROJECT_PROPERTIES:
-				properties = ianjuta_project_configure (plugin->project, NULL);
-				title = _("Project properties");
-				break;
-			case PM_TARGET_PROPERTIES:		
-				properties = ianjuta_project_configure_node (plugin->project,
-														   id, NULL);
-				title = _("Target properties");
-				break;
-			case PM_GROUP_PROPERTIES:
-				properties = ianjuta_project_configure_node (plugin->project,
-														   id, NULL);
-				title = _("Group properties");
-				break;
+		case GBF_TREE_NODE_GROUP:
+			title = _("Group properties");
+			node = gbf_tree_data_get_node (data, plugin->project);
+			if (node != NULL)
+			{
+				properties = ianjuta_project_configure_node (plugin->project, node, NULL);
+
+				if (properties == NULL)
+				{
+					anjuta_util_dialog_info (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
+								 _("No properties available for this group"));
+				}
+			}
+			break;
+		case GBF_TREE_NODE_TARGET:
+			title = _("Target properties");
+			node = gbf_tree_data_get_node (data, plugin->project);
+			if (node != NULL)
+			{
+				properties = ianjuta_project_configure_node (plugin->project, node, NULL);
+
+				if (properties == NULL)
+				{
+					anjuta_util_dialog_info (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
+							 _("No properties available for this target"));
+				}
+			}
+			break;
+		default:
+			break;
 		}
-			
+
 		if (properties)
 		{
-			win = gtk_dialog_new_with_buttons (title,
-									   GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
-									   GTK_DIALOG_DESTROY_WITH_PARENT,
-									   GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL);
-			info.dialog = win;
-			plugin->prop_dialogs = g_list_prepend (plugin->prop_dialogs, g_memdup (&info, sizeof (info)));
-			g_signal_connect (win, "response",
-							  G_CALLBACK (on_properties_dialog_response),
-							  plugin);
-			
-			gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG(win))),
-					   properties);
-			gtk_window_set_default_size (GTK_WINDOW (win), 450, -1);
-			gtk_widget_show (win);
+			project_manager_create_properties_dialog(plugin,
+			    &data->properties_dialog,
+		    	title,
+		    	properties);
 		}
-		else
-		{
-			anjuta_util_dialog_info (GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell),
-							 _("No properties available for this target"));
-		}
-	}	
+	}
+}
+
+static void
+project_manager_show_project_properties_dialog (ProjectManagerPlugin *plugin)
+{
+	/* Project configuration dialog */
+	
+	if (plugin->properties_dialog != NULL)
+	{
+		/* Show already existing dialog */
+		gtk_window_present (GTK_WINDOW (plugin->properties_dialog));
+	}
+	else
+	{
+		project_manager_create_properties_dialog(plugin,
+		    &plugin->properties_dialog,
+		    _("Project properties"),
+		    ianjuta_project_configure (plugin->project, NULL));
+	}
 }
 
 
@@ -502,7 +506,7 @@ on_refresh (GtkAction *action, ProjectManagerPlugin *plugin)
 static void
 on_properties (GtkAction *action, ProjectManagerPlugin *plugin)
 {
-	project_manager_show_properties_dialog (plugin, PM_PROJECT_PROPERTIES, NULL); 
+	project_manager_show_project_properties_dialog (plugin); 
 }
 
 static void
@@ -564,36 +568,24 @@ on_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
 static void
 on_popup_properties (GtkAction *action, ProjectManagerPlugin *plugin)
 {
-	AnjutaProjectNode *node;
-	
-	node = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   ANJUTA_PROJECT_TARGET);
-	if (node)
-	{
-		project_manager_show_properties_dialog (plugin, PM_TARGET_PROPERTIES, node);
-		return;
-	}
-		
-	node = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   ANJUTA_PROJECT_GROUP);
-	if (node)
+	GbfTreeData *data;
+
+	data = gbf_project_view_get_selected (GBF_PROJECT_VIEW (plugin->view));
+	if (data)
 	{
-		project_manager_show_properties_dialog (plugin, PM_GROUP_PROPERTIES, node);
-		return;
+		project_manager_show_node_properties_dialog (plugin, data);
 	}
-	
-	/* FIXME: */
 }
 
 static void
 on_popup_add_group (GtkAction *action, ProjectManagerPlugin *plugin)
 {
-	AnjutaProjectNode *selected_group;
+	GbfTreeData *selected_group;
 	AnjutaProjectGroup *new_group;
 	
 	update_operation_begin (plugin);
-	selected_group = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-							  					     ANJUTA_PROJECT_GROUP);
+	selected_group = gbf_project_view_get_selected (GBF_PROJECT_VIEW (plugin->view));
+	
 	new_group = gbf_project_util_new_group (plugin->model,
 										   get_plugin_parent_window (plugin),
 										   selected_group, NULL);
@@ -603,12 +595,11 @@ on_popup_add_group (GtkAction *action, ProjectManagerPlugin *plugin)
 static void
 on_popup_add_target (GtkAction *action, ProjectManagerPlugin *plugin)
 {
-	AnjutaProjectGroup *selected_group;
+	GbfTreeData *selected_group;
 	AnjutaProjectTarget *new_target;
 
 	update_operation_begin (plugin);
-	selected_group = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-					 					   			 ANJUTA_PROJECT_GROUP);
+	selected_group = gbf_project_view_get_selected (GBF_PROJECT_VIEW (plugin->view));
 
 	new_target = gbf_project_util_new_target (plugin->model,
 											 get_plugin_parent_window (plugin),
@@ -620,16 +611,15 @@ on_popup_add_target (GtkAction *action, ProjectManagerPlugin *plugin)
 static void
 on_popup_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
 {
-	AnjutaProjectTarget *selected_target;
+	GbfTreeData *selected_target;
 	AnjutaProjectSource *new_source;
 	
 	update_operation_begin (plugin);
-	selected_target = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   			  ANJUTA_PROJECT_TARGET);
+	selected_target = gbf_project_view_get_selected (GBF_PROJECT_VIEW (plugin->view));
 
 	new_source = gbf_project_util_add_source (plugin->model,
 											 get_plugin_parent_window (plugin),
-											 selected_target, NULL, NULL);
+											 selected_target, NULL);
 
 	update_operation_end (plugin, TRUE);
 }
@@ -1355,10 +1345,9 @@ project_manager_unload_gbf (ProjectManagerPlugin *pm_plugin)
 				g_list_free (to_remove);
 		}
 		
-		/* Remove remaining properties dialogs */
-		g_list_foreach (pm_plugin->prop_dialogs, (GFunc)properties_dialog_info_free, NULL);
-		g_list_free (pm_plugin->prop_dialogs);
-		pm_plugin->prop_dialogs = NULL;
+		/* Remove project properties dialogs */
+		if (pm_plugin->properties_dialog != NULL) gtk_widget_destroy (pm_plugin->properties_dialog);
+		pm_plugin->properties_dialog = NULL;
 		
 		/* Release project */
 		g_object_unref (pm_plugin->project);
@@ -1513,7 +1502,7 @@ project_manager_plugin_activate_plugin (AnjutaPlugin *plugin)
 	pm_plugin->scrolledwindow = scrolled_window;
 	pm_plugin->view = view;
 	pm_plugin->model = model;
-	pm_plugin->prop_dialogs = NULL;
+	pm_plugin->properties_dialog = NULL;
 	
 	/* Action groups */
 	pm_plugin->pm_action_group = 
@@ -1862,33 +1851,20 @@ get_node_from_file (AnjutaProjectNode *parent, GFile *file)
 	return NULL;		
 }
 
-static AnjutaProjectNode*
-get_element_id_from_uri (ProjectManagerPlugin *plugin, const gchar *uri)
+static GbfTreeData*
+get_tree_data_from_uri (ProjectManagerPlugin *plugin, const gchar *uri, GbfTreeNodeType type)
 {
-	AnjutaProjectNode *node;
-	GFile *file;
-	
-	if (!uri_is_inside_project (plugin, uri))
-		return NULL;
-
-	file = g_file_new_for_uri (uri);
-	node = ianjuta_project_get_root (plugin->project, NULL);
-	if (g_file_equal (anjuta_project_group_get_directory (node), file))
-	{
-		return node;
-	}
-	else
-	{
-		return get_node_from_file (node, file);
-	}
+	return gbf_project_model_find_uri (plugin->model, uri, type);
 }
 
 static AnjutaProjectTarget*
 get_target_from_uri (ProjectManagerPlugin *plugin, const gchar *uri)
 {
-	AnjutaProjectNode *node;
+	GbfTreeData *data;
+	AnjutaProjectNode *node = NULL;
 
-	node = get_element_id_from_uri (plugin, uri);
+	data = get_tree_data_from_uri (plugin, uri, GBF_TREE_NODE_TARGET);
+	if (data) node = gbf_tree_data_get_node (data, plugin->project);
 
 	if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_TARGET)
 	{
@@ -1905,7 +1881,8 @@ iproject_manager_get_element_type (IAnjutaProjectManager *project_manager,
 								   const gchar *element_uri,
 								   GError **err)
 {
-	AnjutaProjectNode *node;
+	GbfTreeData *data;
+	AnjutaProjectNode *node = NULL;
 	ProjectManagerPlugin *plugin;
 
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
@@ -1913,7 +1890,8 @@ iproject_manager_get_element_type (IAnjutaProjectManager *project_manager,
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 
-	node = get_element_id_from_uri (plugin, element_uri);
+	data = get_tree_data_from_uri (plugin, element_uri, 0);
+	if (data) node = gbf_tree_data_get_node (data, plugin->project);
 
 	return node == NULL ? ANJUTA_PROJECT_UNKNOWN : anjuta_project_node_get_type (node);
 }
@@ -2162,8 +2140,7 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 							 GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	AnjutaProjectNodeType default_location_type;
-	AnjutaProjectNode *location_id = NULL;
+	GbfTreeData *location_data = NULL;
 	AnjutaProjectSource *source_id;
 	gchar* source_uri;
 	
@@ -2173,38 +2150,15 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	update_operation_begin (plugin);
-	if (default_location_uri == NULL)
-	{
-		default_location_type = ANJUTA_PROJECT_UNKNOWN;
-	}
-	else
-	{
-		default_location_type =
-			ianjuta_project_manager_get_element_type (project_manager,
-													  default_location_uri, NULL);
-		location_id = get_element_id_from_uri (plugin, default_location_uri);
-	}
-	if (default_location_type == ANJUTA_PROJECT_GROUP)
-	{
-		source_id = gbf_project_util_add_source (plugin->model,
-											get_plugin_parent_window (plugin),
-												 NULL, location_id,
-												 source_uri_to_add);
-	}
-	else if (default_location_type == ANJUTA_PROJECT_TARGET)
+	if (default_location_uri != NULL)
 	{
-		source_id = gbf_project_util_add_source (plugin->model,
-											 get_plugin_parent_window (plugin),
-												 location_id, NULL,
-												 source_uri_to_add);
-	}
-	else
-	{
-		source_id = gbf_project_util_add_source (plugin->model,
-											 get_plugin_parent_window (plugin),
-												 NULL, NULL,
-												 source_uri_to_add);
+		location_data = get_tree_data_from_uri (plugin, default_location_uri, GBF_TREE_NODE_TARGET);
+		if (location_data == NULL) get_tree_data_from_uri (plugin, default_location_uri, GBF_TREE_NODE_GROUP);
 	}
+	source_id = gbf_project_util_add_source (plugin->model,
+										get_plugin_parent_window (plugin),
+											 location_data,
+											 source_uri_to_add);
 	update_operation_end (plugin, TRUE);
 	
 	source_uri = get_element_uri_from_id(plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
@@ -2221,14 +2175,17 @@ iproject_manager_add_source_quiet (IAnjutaProjectManager *project_manager,
 	ProjectManagerPlugin *plugin;
 	AnjutaProjectSource *source_id;
 	GFile *source_file;
-	AnjutaProjectTarget *target;
+	GbfTreeData *data;
+	AnjutaProjectTarget *target = NULL;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
-	target = get_element_id_from_uri (plugin, location_uri);
+	data = get_tree_data_from_uri (plugin, location_uri, GBF_TREE_NODE_TARGET);
+	if (data == NULL) get_tree_data_from_uri (plugin, location_uri, GBF_TREE_NODE_GROUP);
+	if (data != NULL) target = gbf_tree_data_get_node (data, plugin->project);
 	source_file = g_file_new_for_uri (source_uri_to_add);
 	update_operation_begin (plugin);
 	source_id = ianjuta_project_add_source (plugin->project,
@@ -2248,8 +2205,7 @@ iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
 							 GError **err)
 {
 	ProjectManagerPlugin *plugin;
-	AnjutaProjectNodeType default_location_type;
-	AnjutaProjectNode *location_id = NULL;
+	GbfTreeData *location_data = NULL;
 	GList* source_ids;
 	GList* source_uris = NULL;
 	
@@ -2259,40 +2215,16 @@ iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
 	update_operation_begin (plugin);
-	if (default_location_uri == NULL)
+	if (default_location_uri != NULL)
 	{
-		default_location_type = ANJUTA_PROJECT_UNKNOWN;
-	}
-	else
-	{
-		default_location_type =
-			ianjuta_project_manager_get_element_type (project_manager,
-													  default_location_uri, NULL);
-		location_id = get_element_id_from_uri (plugin, default_location_uri);
-	}
-	if (default_location_type == ANJUTA_PROJECT_GROUP)
-	{
-		source_ids = gbf_project_util_add_source_multi (plugin->model,
-											 get_plugin_parent_window (plugin),
-												 NULL, location_id,
-												 source_add_uris);
-	}
-	else if (default_location_type == ANJUTA_PROJECT_TARGET)
-	{
-		source_ids =
-			gbf_project_util_add_source_multi (plugin->model,
-										   get_plugin_parent_window (plugin),
-										   location_id, NULL,
-										   source_add_uris);
-	}
-	else
-	{
-		source_ids =
-			gbf_project_util_add_source_multi (plugin->model,
-										   get_plugin_parent_window (plugin),
-										   NULL, NULL,
-										   source_add_uris);
+		location_data = get_tree_data_from_uri (plugin, default_location_uri, GBF_TREE_NODE_TARGET);
+		if (location_data == NULL) get_tree_data_from_uri (plugin, default_location_uri, GBF_TREE_NODE_GROUP);
 	}
+
+	source_ids = gbf_project_util_add_source_multi (plugin->model,
+										 get_plugin_parent_window (plugin),
+										 location_data,
+										 source_add_uris);
 	update_operation_end (plugin, TRUE);
 	
 	while (source_ids)
@@ -2316,7 +2248,7 @@ iproject_manager_add_target (IAnjutaProjectManager *project_manager,
 	ProjectManagerPlugin *plugin;
 	gchar *target_uri = NULL;
 	AnjutaProjectTarget *target_id;
-	AnjutaProjectGroup *default_group_id;
+	GbfTreeData *default_group_data;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
@@ -2324,12 +2256,12 @@ iproject_manager_add_target (IAnjutaProjectManager *project_manager,
 	
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
-	default_group_id = get_element_id_from_uri (plugin, default_group_uri);
+	default_group_data = get_tree_data_from_uri (plugin, default_group_uri, GBF_TREE_NODE_GROUP);
 	
 	update_operation_begin (plugin);
 	target_id = gbf_project_util_new_target (plugin->model,
 											 get_plugin_parent_window (plugin),
-											 default_group_id,
+											 default_group_data,
 											 target_name_to_add);
 	update_operation_end (plugin, TRUE);
 	target_uri = get_element_uri_from_id (plugin, target_id, IANJUTA_BUILDER_ROOT_URI);
@@ -2346,19 +2278,19 @@ iproject_manager_add_group (IAnjutaProjectManager *project_manager,
 	ProjectManagerPlugin *plugin;
 	gchar *group_uri = NULL;
 	AnjutaProjectGroup *group_id;
-	AnjutaProjectGroup *default_group_id;
+	GbfTreeData *default_group_data;
 	
 	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), FALSE);
 
-	default_group_id = get_element_id_from_uri (plugin, default_group_uri);
+	default_group_data = get_tree_data_from_uri (plugin, default_group_uri, GBF_TREE_NODE_GROUP);
 	
 	update_operation_begin (plugin);
 	group_id = gbf_project_util_new_group (plugin->model,
 										   get_plugin_parent_window (plugin),
-										   default_group_id,
+										   default_group_data,
 										   group_name_to_add);
 	update_operation_end (plugin, TRUE);
 	group_uri = get_element_uri_from_id (plugin, group_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
diff --git a/plugins/project-manager/plugin.h b/plugins/project-manager/plugin.h
index 1e58763..57169cb 100644
--- a/plugins/project-manager/plugin.h
+++ b/plugins/project-manager/plugin.h
@@ -71,8 +71,8 @@ struct _ProjectManagerPlugin{
 	/* Idle callback id */
 	guint close_project_idle;
 	
-	/* List of non modal properties dialog */
-	GList* prop_dialogs;
+	/* project properties dialog */
+	GtkWidget *properties_dialog;
 };
 
 struct _ProjectManagerPluginClass{



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