[anjuta/newproject] Implement add and remove source for dir project



commit 907a17de3e12779a465da150b2c0b662914bab59
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sat May 8 18:33:17 2010 +0200

    Implement add and remove source for dir project

 libanjuta/interfaces/libanjuta.idl     |    9 -
 plugins/am-project/am-project.c        |    4 +-
 plugins/class-gen/plugin.c             |    5 +-
 plugins/dir-project/dir-project.c      |   25 ++-
 plugins/file-wizard/file.c             |    5 +-
 plugins/mk-project/mk-project.c        |    2 +-
 plugins/project-manager/dialogs.c      |  551 +++++++++++++++++++++++++++++++-
 plugins/project-manager/dialogs.h      |    5 +
 plugins/project-manager/plugin.c       |   88 +++---
 plugins/project-manager/project-util.c |  366 +---------------------
 plugins/project-manager/project.c      |   60 +++-
 plugins/project-manager/project.h      |    8 +-
 12 files changed, 687 insertions(+), 441 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index e125342..fce90e0 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -3065,15 +3065,6 @@ interface IAnjutaProject
 		PROBE_PROJECT_FILES = 200
 	}
 
-	enum Capabilities
-	{
-		CAN_ADD_NONE	= 0,
-		CAN_ADD_GROUP	= 1 << 0,
-		CAN_ADD_TARGET	= 1 << 1,
-		CAN_ADD_SOURCE	= 1 << 2,
-		HAS_PACKAGES	= 1 << 3
-	}
-	
 	/* Signals */
 	
 	/**
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index d17badd..5ad888d 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -3191,9 +3191,7 @@ iproject_configure (IAnjutaProject *obj, GError **err)
 static guint 
 iproject_get_capabilities (IAnjutaProject *obj, GError **err)
 {
-	return (IANJUTA_PROJECT_CAN_ADD_GROUP |
-		IANJUTA_PROJECT_CAN_ADD_TARGET |
-		IANJUTA_PROJECT_CAN_ADD_SOURCE);
+	return 0;
 }
 
 static GList* 
diff --git a/plugins/class-gen/plugin.c b/plugins/class-gen/plugin.c
index 35509c8..0cf733b 100644
--- a/plugins/class-gen/plugin.c
+++ b/plugins/class-gen/plugin.c
@@ -445,8 +445,7 @@ iwizard_activate (IAnjutaWizard *wiz, G_GNUC_UNUSED GError **err)
 	AnjutaClassGenPlugin *cg_plugin;
 	gchar *user_name;
 	gchar *user_email;
-	IAnjutaProjectCapabilities caps =
-		IANJUTA_PROJECT_CAN_ADD_NONE;
+	gint caps = 0;
 	
 	cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (wiz);
 
@@ -479,7 +478,7 @@ iwizard_activate (IAnjutaWizard *wiz, G_GNUC_UNUSED GError **err)
 			caps = ianjuta_project_manager_get_capabilities (manager, NULL);
 	}
 
-	if((caps & IANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE)
+	if((caps & ANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE)
 	{
 		cg_window_set_add_to_project (cg_plugin->window, FALSE);
 		cg_window_enable_add_to_project (cg_plugin->window, FALSE);
diff --git a/plugins/dir-project/dir-project.c b/plugins/dir-project/dir-project.c
index 5876bc6..831953d 100644
--- a/plugins/dir-project/dir-project.c
+++ b/plugins/dir-project/dir-project.c
@@ -336,7 +336,27 @@ project_node_new (DirProject *project, AnjutaProjectNode *parent, AnjutaProjectN
 			}
 			break;
 		case ANJUTA_PROJECT_SOURCE:
-			node = dir_source_new (file);
+			if (file == NULL)
+			{
+				if (name == NULL)
+				{
+					g_set_error (error, IANJUTA_PROJECT_ERROR, 
+							IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+							_("Missing name"));
+				}
+				else
+				{
+					GFile *source_file;
+					
+					source_file = g_file_get_child (anjuta_project_node_get_file (parent), name);
+					node = dir_source_new (source_file);
+					g_object_unref (source_file);
+				}
+			}
+			else
+			{
+				node = dir_source_new (file);
+			}
 			break;
 		case ANJUTA_PROJECT_ROOT:
 			node = dir_root_new (file);
@@ -769,6 +789,7 @@ foreach_node_save (AnjutaProjectNode *node,
 		switch (anjuta_project_node_get_type (node))
 		{
 		case ANJUTA_PROJECT_GROUP:
+		case ANJUTA_PROJECT_SOURCE:
 			ret = g_file_trash (anjuta_project_node_get_file (node), NULL, &err);
 			if (err != NULL)
 			{
@@ -951,7 +972,7 @@ iproject_configure (IAnjutaProject *obj, GError **err)
 static guint 
 iproject_get_capabilities (IAnjutaProject *obj, GError **err)
 {
-	return IANJUTA_PROJECT_CAN_ADD_NONE;
+	return 0;
 }
 
 static GList* 
diff --git a/plugins/file-wizard/file.c b/plugins/file-wizard/file.c
index 1fbf6d3..2cb30bb 100644
--- a/plugins/file-wizard/file.c
+++ b/plugins/file-wizard/file.c
@@ -126,8 +126,7 @@ void
 display_new_file(AnjutaFileWizardPlugin *plugin,
 				 IAnjutaDocumentManager *docman)
 {
-	IAnjutaProjectCapabilities caps =
-		IANJUTA_PROJECT_CAN_ADD_NONE;
+	gint caps = 0;
 	
 	if (!nfg)
 		if (!create_new_file_dialog (docman))
@@ -148,7 +147,7 @@ display_new_file(AnjutaFileWizardPlugin *plugin,
 	                  G_CALLBACK(on_add_to_project_toggled),
 	                  nfg);
 	
-	if ((caps & IANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE) {
+	if ((caps & ANJUTA_PROJECT_CAN_ADD_SOURCE) == FALSE) {
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (nfg->add_to_project),
 									  FALSE);
 		gtk_widget_set_sensitive (nfg->add_to_project, FALSE);
diff --git a/plugins/mk-project/mk-project.c b/plugins/mk-project/mk-project.c
index 4310976..655c0b6 100644
--- a/plugins/mk-project/mk-project.c
+++ b/plugins/mk-project/mk-project.c
@@ -1392,7 +1392,7 @@ iproject_configure (IAnjutaProject *obj, GError **err)
 static guint 
 iproject_get_capabilities (IAnjutaProject *obj, GError **err)
 {
-	return IANJUTA_PROJECT_CAN_ADD_NONE;
+	return 0;
 }
 
 static GList* 
diff --git a/plugins/project-manager/dialogs.c b/plugins/project-manager/dialogs.c
index 59a2ff6..5600829 100644
--- a/plugins/project-manager/dialogs.c
+++ b/plugins/project-manager/dialogs.c
@@ -28,6 +28,9 @@
 
 #include "dialogs.h"
 
+#include "project-model.h"
+#include "project-view.h"
+
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-utils.h>
 
@@ -49,11 +52,261 @@ enum {
 	LIST_COLUMNS_NB
 };
 
+/* Sources list columns in new source dialog */
+enum {
+	COLUMN_FILE,
+	COLUMN_URI,
+	N_COLUMNS
+};
 
 /* Helper functions
  *---------------------------------------------------------------------------*/
 
-/* Private functions
+static GtkBuilder *
+load_interface (const gchar *top_widget)
+{
+    GtkBuilder *xml = gtk_builder_new ();
+    GError* error = NULL;
+
+    if (!gtk_builder_add_from_file (xml, GLADE_FILE, &error))
+    {
+        g_warning ("Couldn't load builder file: %s", error->message);
+        g_error_free (error);
+        return NULL;
+    }
+
+    return xml;
+}
+
+static void
+error_dialog (GtkWindow *parent, const gchar *summary, const gchar *msg, ...)
+{
+    va_list ap;
+    gchar *tmp;
+    GtkWidget *dialog;
+    
+    va_start (ap, msg);
+    tmp = g_strdup_vprintf (msg, ap);
+    va_end (ap);
+    
+    dialog = gtk_message_dialog_new_with_markup (parent,
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_OK,
+						 "<b>%s</b>\n\n%s", summary, tmp);
+    g_free (tmp);
+    
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+}
+
+ 
+/* Private nodes functions
+ *---------------------------------------------------------------------------*/
+
+static gboolean
+nodes_filter_fn (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
+{
+	GbfTreeData *data = NULL;
+	gboolean visible = FALSE;
+	AnjutaProjectNodeType type = (AnjutaProjectNodeType)GPOINTER_TO_INT (user_data);
+	AnjutaProjectNode *parent;
+	AnjutaProjectNode *node;
+	gint need;
+
+	switch (type)
+	{
+	case ANJUTA_PROJECT_GROUP:
+		need = ANJUTA_PROJECT_CAN_ADD_GROUP;
+		break;
+	case ANJUTA_PROJECT_TARGET:
+		need = ANJUTA_PROJECT_CAN_ADD_TARGET;
+		break;
+	case ANJUTA_PROJECT_SOURCE:
+		need = ANJUTA_PROJECT_CAN_ADD_SOURCE;
+		break;
+	case ANJUTA_PROJECT_MODULE:
+		need = ANJUTA_PROJECT_CAN_ADD_MODULE;
+		break;
+	case ANJUTA_PROJECT_PACKAGE:
+		need = ANJUTA_PROJECT_CAN_ADD_PACKAGE;
+		break;
+	default:
+		need = 0;
+		break;
+	}
+	
+	gtk_tree_model_get (model, iter,
+						GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
+	node = gbf_tree_data_get_node (data);
+	if (node != NULL)
+	{
+		if (anjuta_project_node_get_state (node) & need)
+		{
+			/* Current node can be used as parent */
+			visible = TRUE;
+		}
+		else if (anjuta_project_node_get_type (node) == type)
+		{
+			/* Check if node can be used as sibling */
+			parent = anjuta_project_node_parent (node);
+			visible = anjuta_project_node_get_state (parent) & need ? TRUE : FALSE;
+			
+		}
+	}
+
+	return visible;
+}
+
+static void 
+setup_nodes_treeview (GbfProjectModel         *model,
+                       GtkWidget              *view,
+                       AnjutaProjectNodeType  type,
+                       GtkTreeIter            *selected)
+{
+	GtkTreeModel *filter;
+	GtkTreeIter iter_filter;
+	GtkTreePath *path;
+
+	g_return_if_fail (model != NULL);
+	g_return_if_fail (view != NULL && GBF_IS_PROJECT_VIEW (view));
+
+	filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (model), NULL);
+	gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+											nodes_filter_fn,  GINT_TO_POINTER (type), NULL);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (filter));
+	g_object_unref (filter);
+
+	/* select default group */
+	if (selected && gtk_tree_model_filter_convert_child_iter_to_iter (
+			GTK_TREE_MODEL_FILTER (filter), &iter_filter, selected))
+	{
+		path = gtk_tree_model_get_path (filter, &iter_filter);
+		gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
+	}
+	else
+	{
+		GtkTreePath *root_path;
+
+		gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+		root_path = gbf_project_model_get_project_root (model);
+		if (root_path)
+		{
+			path = gtk_tree_model_filter_convert_child_path_to_path (
+						GTK_TREE_MODEL_FILTER (filter), root_path);
+			gtk_tree_path_free (root_path);
+		}
+		else
+		{
+			path = gtk_tree_path_new_first ();
+		}
+	}
+
+	gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
+	gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), path, NULL,
+									TRUE, 0.5, 0.0);
+	gtk_tree_path_free (path);
+}
+
+static void
+entry_changed_cb (GtkEditable *editable, gpointer user_data)
+{
+    GtkWidget *button = user_data;
+    gchar *text;
+
+    if (!button)
+        return;
+
+    text = gtk_editable_get_chars (editable, 0, -1);
+    if (strlen (text) > 0) {
+        gtk_widget_set_sensitive (button, TRUE);
+        gtk_widget_grab_default (button);
+    } else {
+        gtk_widget_set_sensitive (button, FALSE);
+    }
+    g_free (text);
+}
+
+static void
+on_row_changed(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data)
+{
+	GtkWidget* button = GTK_WIDGET(data);
+	if (gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), iter))
+		gtk_widget_set_sensitive(button, TRUE);
+	else
+		gtk_widget_set_sensitive(button, FALSE);
+}
+
+static void
+browse_button_clicked_cb (GtkWidget *widget, gpointer user_data)
+{
+	GtkTreeView *tree = user_data;
+	GtkTreeView *treeview;
+	GtkFileChooserDialog* dialog;
+	GtkTreeModel* model;
+	AnjutaProjectNode *parent;
+	gint result;
+
+	g_return_if_fail (user_data != NULL && GTK_IS_TREE_VIEW (user_data));
+	
+	model = gtk_tree_view_get_model(tree);
+	/*if (gtk_tree_model_get_iter_first(model, &iter))
+	{
+		gtk_tree_model_get(model, &iter, COLUMN_URI, &file, -1);
+		uri = g_strdup(file);
+	}
+	else
+		uri = g_strdup("");*/
+	
+	dialog = GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new (_("Select sourcesâ?¦"),
+						GTK_WINDOW (gtk_widget_get_toplevel (widget)),
+						GTK_FILE_CHOOSER_ACTION_OPEN,
+						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+						GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+						NULL));
+
+	/* Get default directory */
+	treeview = g_object_get_data (G_OBJECT (widget), "treeview");
+	parent = gbf_project_view_find_selected (GBF_PROJECT_VIEW (treeview), ANJUTA_PROJECT_UNKNOWN);
+	if (!(anjuta_project_node_get_state (parent) & ANJUTA_PROJECT_CAN_ADD_SOURCE))
+	{
+		parent = anjuta_project_node_parent (parent);
+	}
+	gtk_file_chooser_set_current_folder_file(GTK_FILE_CHOOSER(dialog),
+			anjuta_project_node_get_file (parent), NULL);
+
+	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
+
+	result = gtk_dialog_run (GTK_DIALOG (dialog));
+	switch (result)
+	{
+	case GTK_RESPONSE_ACCEPT:
+	{
+		GSList* uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER(dialog));
+		GSList* node_uri = uris;
+
+		gtk_list_store_clear (GTK_LIST_STORE (model));
+
+		while (node_uri != NULL)
+		{
+			GtkTreeIter iter;
+			gchar* uri = node_uri->data;
+			gchar* file = g_path_get_basename (uri);
+			gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+			gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_FILE,
+						file, COLUMN_URI, uri, -1);
+			node_uri = g_slist_next (node_uri);
+		}
+		g_slist_free (uris);
+		break;
+	}
+	default:
+		break;
+	} 
+	gtk_widget_destroy (GTK_WIDGET(dialog));
+}
+ 
+/* Private properties functions
  *---------------------------------------------------------------------------*/
 
 static void
@@ -329,3 +582,299 @@ pm_project_create_properties_dialog (IAnjutaProject *project, GtkWidget **dialog
 	return *dialog != NULL;
 }
 
+AnjutaProjectNode*
+anjuta_pm_project_new_group (AnjutaPmProject *project, GtkWindow *parent, GtkTreeIter *selected, const gchar *default_name)
+{
+    GtkBuilder *gui;
+    GtkWidget *dialog, *group_name_entry, *ok_button;
+    GtkWidget *groups_view;
+    gint response;
+    gboolean finished = FALSE;
+    AnjutaProjectNode *new_group = NULL;
+
+    g_return_val_if_fail (project != NULL, NULL);
+    
+    gui = load_interface ("new_group_dialog");
+    g_return_val_if_fail (gui != NULL, NULL);
+    
+    /* get all needed widgets */
+    dialog = GTK_WIDGET (gtk_builder_get_object (gui, "new_group_dialog"));
+    groups_view = GTK_WIDGET (gtk_builder_get_object (gui, "groups_view"));
+    group_name_entry = GTK_WIDGET (gtk_builder_get_object (gui, "group_name_entry"));
+    ok_button = GTK_WIDGET (gtk_builder_get_object (gui, "ok_group_button"));
+    
+    /* set up dialog */
+    if (default_name)
+        gtk_entry_set_text (GTK_ENTRY (group_name_entry),
+                            default_name);
+    g_signal_connect (group_name_entry, "changed",
+                      (GCallback) entry_changed_cb, ok_button);
+    if (default_name)
+        gtk_widget_set_sensitive (ok_button, TRUE);
+    else
+        gtk_widget_set_sensitive (ok_button, FALSE);
+    
+    setup_nodes_treeview (anjuta_pm_project_get_model (project), groups_view, ANJUTA_PROJECT_GROUP, selected);
+    gtk_widget_show (groups_view);
+    
+    if (parent) {
+        gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+    }
+    
+    /* execute dialog */
+    while (!finished) {
+        response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+        switch (response) {
+            case GTK_RESPONSE_OK: 
+            {
+                GError *err = NULL;
+                AnjutaProjectNode *group;
+                gchar *name;
+            
+                name = gtk_editable_get_chars (
+                    GTK_EDITABLE (group_name_entry), 0, -1);
+                
+                group = gbf_project_view_find_selected (GBF_PROJECT_VIEW (groups_view),
+                                                       ANJUTA_PROJECT_GROUP);
+                if (group) {
+                    new_group = anjuta_pm_project_add_group (project, group, NULL, name, &err);
+                    if (err) {
+                        error_dialog (parent, _("Cannot add group"), "%s",
+                                      err->message);
+                        g_error_free (err);
+                    } else {
+			finished = TRUE;
+		    }
+                } else {
+                    error_dialog (parent, _("Cannot add group"),
+				  "%s", _("No parent group selected"));
+                }
+                g_free (name);
+                break;
+            }
+            default:
+                finished = TRUE;
+                break;
+        }
+    }
+    
+    /* destroy stuff */
+    gtk_widget_destroy (dialog);
+    g_object_unref (gui);
+    return new_group;
+}
+
+AnjutaProjectNode*
+anjuta_pm_project_new_source (AnjutaPmProject *project,
+							GtkWindow           *parent,
+							GtkTreeIter         *default_parent,
+							const gchar         *default_uri)
+{
+	GList* new_sources;
+	gchar* uri = NULL;
+	GList* uris = NULL;
+	
+	if (default_uri)
+	{
+		uri = g_strdup (default_uri);
+		uris = g_list_append (NULL, uri);
+	}
+	new_sources = 
+		anjuta_pm_project_new_multiple_source (project, parent,
+										default_parent, uris);
+	g_free (uri);
+	g_list_free (uris);
+	
+	if (new_sources && g_list_length (new_sources))
+	{
+		AnjutaProjectNode *new_source = new_sources->data;
+		g_list_free (new_sources);
+		return new_source;
+	}
+	else
+		return NULL;
+}
+
+GList* 
+anjuta_pm_project_new_multiple_source (AnjutaPmProject *project,
+								GtkWindow           *top_window,
+								GtkTreeIter         *default_parent,
+								GList               *uris_to_add)
+{
+	GtkBuilder *gui;
+	GtkWidget *dialog, *source_file_tree;
+	GtkWidget *ok_button, *browse_button;
+	GtkWidget *targets_view;
+	gint response;
+	gboolean finished = FALSE;
+	GtkListStore* list;
+	GtkCellRenderer* renderer;
+	GtkTreeViewColumn* column_filename;
+	GList* new_sources = NULL;
+	GList* uri_node;
+
+	g_return_val_if_fail (project != NULL, NULL);
+
+	gui = load_interface ("add_source_dialog");
+	g_return_val_if_fail (gui != NULL, NULL);
+
+	/* get all needed widgets */
+	dialog = GTK_WIDGET (gtk_builder_get_object (gui, "add_source_dialog"));
+	targets_view = GTK_WIDGET (gtk_builder_get_object (gui, "targets_view"));
+	source_file_tree = GTK_WIDGET (gtk_builder_get_object (gui, "source_file_tree"));
+	browse_button = GTK_WIDGET (gtk_builder_get_object (gui, "browse_button"));
+	ok_button = GTK_WIDGET (gtk_builder_get_object (gui, "ok_source_button"));
+
+	/* Prepare file tree */
+	list = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (source_file_tree),
+								GTK_TREE_MODEL (list));
+	renderer = gtk_cell_renderer_text_new ();
+	column_filename = gtk_tree_view_column_new_with_attributes ("Files",
+							        renderer,
+							        "text",
+							        COLUMN_FILE,
+							        NULL);
+	gtk_tree_view_column_set_sizing (column_filename,
+				     GTK_TREE_VIEW_COLUMN_FIXED);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (source_file_tree),
+				 column_filename);
+
+	/* set up dialog */
+	uri_node = uris_to_add;
+	while (uri_node) 
+	{
+		GtkTreeIter iter;
+		gchar* filename = g_path_get_basename (uri_node->data);
+		if (!filename)
+			filename = g_strdup (uri_node->data);
+		gtk_list_store_append (list, &iter);
+        gtk_list_store_set (list, &iter, COLUMN_FILE, filename,
+			    COLUMN_URI, g_strdup(uri_node->data), -1);
+		g_free (filename);
+		uri_node = g_list_next (uri_node);
+	}
+	if (!g_list_length (uris_to_add))
+		gtk_widget_set_sensitive (ok_button, FALSE);
+	else
+		gtk_widget_set_sensitive (ok_button, TRUE);
+
+	g_signal_connect (G_OBJECT(list), "row_changed",
+					G_CALLBACK(on_row_changed), ok_button);
+    
+	g_signal_connect (browse_button, "clicked",
+					G_CALLBACK (browse_button_clicked_cb), source_file_tree);
+
+	g_object_set_data_full (G_OBJECT (browse_button), "treeview", targets_view, NULL);
+	/*project_root = g_file_get_uri (anjuta_project_node_get_file (anjuta_pm_project_get_root (project)));
+	g_object_set_data_full (G_OBJECT (browse_button), "root", project_root, g_free);*/
+
+	setup_nodes_treeview (anjuta_pm_project_get_model (project), targets_view, ANJUTA_PROJECT_SOURCE, default_parent);
+	gtk_widget_show (targets_view);
+
+	if (top_window) {
+		gtk_window_set_transient_for (GTK_WINDOW (dialog), top_window);
+	}
+
+	if (default_parent)
+		gtk_widget_grab_focus (source_file_tree);
+	else
+		gtk_widget_grab_focus (targets_view);
+
+	/* execute dialog */
+	while (!finished) {
+		response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+		switch (response)
+		{
+		case GTK_RESPONSE_OK: 
+		{
+			AnjutaProjectNode *parent = NULL;
+			AnjutaProjectNode *sibling = NULL;
+
+			parent = gbf_project_view_find_selected (GBF_PROJECT_VIEW (targets_view),
+							ANJUTA_PROJECT_UNKNOWN);
+
+			/* Check that selected node can be used as a parent or a sibling */
+			if (parent)
+			{
+				if (!(anjuta_project_node_get_state (parent) & ANJUTA_PROJECT_CAN_ADD_SOURCE))
+				{
+					sibling = parent;
+					parent = anjuta_project_node_parent (parent);
+				}
+				if (!(anjuta_project_node_get_state (parent) & ANJUTA_PROJECT_CAN_ADD_SOURCE))
+				{
+					parent = NULL;
+				}
+			}
+			
+			if (parent)
+			{
+				GtkTreeIter iter;
+				GString *err_mesg = g_string_new (NULL);
+
+				if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list),
+								&iter))
+					break;
+				do
+				{
+					GError *err = NULL;
+					AnjutaProjectNode* new_source;
+					gchar* uri;
+
+					gtk_tree_model_get (GTK_TREE_MODEL(list), &iter,
+						COLUMN_URI, &uri, -1);
+
+					new_source = anjuta_pm_project_add_source (project,
+									parent,
+									sibling,
+									uri,
+									&err);
+					if (err) {
+						gchar *str = g_strdup_printf ("%s: %s\n",
+								uri,
+								err->message);
+						g_string_append (err_mesg, str);
+						g_error_free (err);
+						g_free (str);
+					}
+					else
+						new_sources = g_list_append (new_sources,
+								new_source);
+
+					g_free (uri);
+				} while (gtk_tree_model_iter_next (GTK_TREE_MODEL(list),
+								&iter));
+
+				if (err_mesg->str && strlen (err_mesg->str) > 0)
+				{
+					error_dialog (top_window, _("Cannot add source files"),
+							"%s", err_mesg->str);
+				}
+				else {
+					finished = TRUE;
+				}
+				g_string_free (err_mesg, TRUE);
+			}
+			else 
+			{
+				error_dialog (top_window, _("Cannot add source files"),
+						"%s", _("The selected node cannot contains source files."));
+			}
+			break;
+		}
+		default:
+			gtk_list_store_clear (GTK_LIST_STORE (list));
+			finished = TRUE;
+			break;
+		}
+	}
+
+	/* destroy stuff */
+	gtk_widget_destroy (dialog);
+	g_object_unref (gui);
+	
+	return new_sources;
+}
diff --git a/plugins/project-manager/dialogs.h b/plugins/project-manager/dialogs.h
index f2e13a3..a38a72d 100644
--- a/plugins/project-manager/dialogs.h
+++ b/plugins/project-manager/dialogs.h
@@ -24,9 +24,14 @@
 
 #include <gtk/gtk.h>
 #include <libanjuta/interfaces/ianjuta-project.h>
+#include "project.h"
 
 G_BEGIN_DECLS
 
+AnjutaProjectNode* anjuta_pm_project_new_group (AnjutaPmProject *project, GtkWindow *parent, GtkTreeIter *default_parent, const gchar *name);
+AnjutaProjectNode* anjuta_pm_project_new_source (AnjutaPmProject *project, GtkWindow *parent, GtkTreeIter *default_parent, const gchar *name);
+GList* anjuta_pm_project_new_multiple_source (AnjutaPmProject *project, GtkWindow *parent, GtkTreeIter *default_parent, GList *name);
+
 gboolean pm_project_create_properties_dialog (IAnjutaProject *project, GtkWidget **dialog, GtkWindow *parent, AnjutaProjectNode *node);
 
 G_END_DECLS
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 2f936d7..446482b 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -34,6 +34,7 @@
 #include <libanjuta/anjuta-project.h>
 
 #include "project-util.h"
+#include "dialogs.h"
 
 #include "plugin.h"
 
@@ -565,7 +566,7 @@ on_popup_add_group (GtkAction *action, ProjectManagerPlugin *plugin)
 	update_operation_begin (plugin);
 	gbf_project_view_get_first_selected (GBF_PROJECT_VIEW (plugin->view), &selected_group);
 	
-	new_group = gbf_project_util_new_group (plugin->project,
+	new_group = anjuta_pm_project_new_group (plugin->project,
 										   get_plugin_parent_window (plugin),
 										   &selected_group, NULL);
 	update_operation_end (plugin, TRUE);
@@ -596,7 +597,7 @@ on_popup_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
 	update_operation_begin (plugin);
 	gbf_project_view_get_first_selected (GBF_PROJECT_VIEW (plugin->view), &selected_target);
 
-	new_source = gbf_project_util_add_source (plugin->project,
+	new_source = anjuta_pm_project_new_source (plugin->project,
 											 get_plugin_parent_window (plugin),
 											 &selected_target, NULL);
 
@@ -942,6 +943,7 @@ update_ui (ProjectManagerPlugin *plugin)
 	AnjutaUI *ui;
 	gint j;
 	GList *item;
+	gint caps;
 	gint main_caps;
 	gint popup_caps;
 	
@@ -950,37 +952,33 @@ update_ui (ProjectManagerPlugin *plugin)
 	popup_caps = 0x000;
 	
 	/* Check for supported node */
-	if (anjuta_pm_project_is_open (plugin->project))
+	caps = anjuta_pm_project_get_capabilities (plugin->project);
+	if (caps != 0)
 	{
-		for (item = anjuta_pm_project_get_node_info (plugin->project); item != NULL; item = g_list_next (item))
+		if (caps & ANJUTA_PROJECT_CAN_ADD_GROUP)
 		{
-			AnjutaProjectNodeInfo *info = (AnjutaProjectNodeInfo *)item->data;
-
-			switch (info->type & ANJUTA_PROJECT_TYPE_MASK)
-			{
-			case ANJUTA_PROJECT_GROUP:
-				main_caps |= 0x2;
-				popup_caps |= 0x21;
-				break;
-			case ANJUTA_PROJECT_TARGET:
-				main_caps |= 0x4;
-				popup_caps |= 0x2;
-				break;
-			case ANJUTA_PROJECT_SOURCE:
-				main_caps |= 0x8;
-				popup_caps |= 0x24;
-				break;
-			case ANJUTA_PROJECT_MODULE:
-				main_caps |= 0x10;
-				popup_caps |= 0x8;
-				break;
-			case ANJUTA_PROJECT_PACKAGE:
-				main_caps |= 0x20;
-				popup_caps |= 0x10;
-				break;
-			default:
-				break;
-			}
+			main_caps |= 0x2;
+			popup_caps |= 0x21;
+		}
+		if (caps & ANJUTA_PROJECT_CAN_ADD_TARGET)
+		{
+			main_caps |= 0x4;
+			popup_caps |= 0x2;
+		}
+		if (caps & ANJUTA_PROJECT_CAN_ADD_SOURCE)
+		{
+			main_caps |= 0x8;
+			popup_caps |= 0x24;
+		}
+		if (caps & ANJUTA_PROJECT_CAN_ADD_MODULE)
+		{
+			main_caps |= 0x10;
+			popup_caps |= 0x8;
+		}
+		if (caps & ANJUTA_PROJECT_CAN_ADD_PACKAGE)
+		{
+			main_caps |= 0x20;
+			popup_caps |= 0x10;
 		}
 		/* Keep properties and refresh if a project is opened */
 		main_caps |= 0x0C0;
@@ -1020,13 +1018,25 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 	AnjutaUI *ui;
 	GtkAction *action;
 	AnjutaProjectNode *node;
-	gint state;
+	gint state = 0;
 	GFile *selected_file;
 	
 	ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
 	node = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
 										   ANJUTA_PROJECT_UNKNOWN);
-	state = node != NULL ? anjuta_project_node_get_state (node) : 0;
+
+	if (node != NULL)
+	{
+		AnjutaProjectNode *parent;
+		
+		state = anjuta_project_node_get_state (node);
+		/* Allow to select a sibling instead of a parent node */
+		parent = anjuta_project_node_parent (node);
+		if (parent != NULL)
+		{
+			state |= anjuta_project_node_get_state (parent);
+		}
+	}
 
 	/* Popup menu */
 	action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
@@ -2016,14 +2026,13 @@ iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
 	return NULL;
 }
 
-static IAnjutaProjectCapabilities
+static gint
 iproject_manager_get_capabilities (IAnjutaProjectManager *project_manager,
 								   GError **err)
 {
 	ProjectManagerPlugin *plugin;
 	
-	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
-						  IANJUTA_PROJECT_CAN_ADD_NONE);
+	g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), 0);
 	
 	plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
 	return anjuta_pm_project_get_capabilities (plugin->project);
@@ -2050,7 +2059,7 @@ iproject_manager_add_source (IAnjutaProjectManager *project_manager,
 	{
 		iter = get_tree_iter_from_file (plugin, &target_iter, default_target_file, GBF_TREE_NODE_TARGET);
 	}
-	source_id = gbf_project_util_add_source (plugin->project,
+	source_id = anjuta_pm_project_new_source (plugin->project,
 										     get_plugin_parent_window (plugin),
 											 iter,
 											 source_uri_to_add);
@@ -2081,6 +2090,7 @@ iproject_manager_add_source_quiet (IAnjutaProjectManager *project_manager,
 	update_operation_begin (plugin);
 	source_id = anjuta_pm_project_add_source (plugin->project,
 	    								target,
+										NULL,
 	    								source_file,
 										err);
 	update_operation_end (plugin, TRUE);
@@ -2111,7 +2121,7 @@ iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
 		iter = get_tree_iter_from_file (plugin, &target_iter, default_target_file, GBF_TREE_NODE_TARGET);
 	}
 
-	source_ids = gbf_project_util_add_source_multi (plugin->project,
+	source_ids = anjuta_pm_project_new_multiple_source (plugin->project,
 										 get_plugin_parent_window (plugin),
 										 iter,
 										 source_add_uris);
@@ -2183,7 +2193,7 @@ iproject_manager_add_group (IAnjutaProjectManager *project_manager,
 	}
 	
 	update_operation_begin (plugin);
-	group_id = gbf_project_util_new_group (plugin->project,
+	group_id = anjuta_pm_project_new_group (plugin->project,
 										   get_plugin_parent_window (plugin),
 										   iter,
 										   group_name_to_add);
diff --git a/plugins/project-manager/project-util.c b/plugins/project-manager/project-util.c
index 732f00a..e096a08 100644
--- a/plugins/project-manager/project-util.c
+++ b/plugins/project-manager/project-util.c
@@ -122,6 +122,7 @@ setup_groups_treeview (AnjutaPmProject *project,
     gtk_tree_path_free (path);
 }
 
+
 static void
 error_dialog (GtkWindow *parent, const gchar *summary, const gchar *msg, ...)
 {
@@ -163,92 +164,6 @@ entry_changed_cb (GtkEditable *editable, gpointer user_data)
     g_free (text);
 }
 
-AnjutaProjectNode*
-gbf_project_util_new_group (AnjutaPmProject *project,
-                            GtkWindow          *parent,
-                            GtkTreeIter        *default_group,
-                            const gchar        *default_group_name_to_add)
-{
-    GtkBuilder *gui;
-    GtkWidget *dialog, *group_name_entry, *ok_button;
-    GtkWidget *groups_view;
-    gint response;
-    gboolean finished = FALSE;
-    AnjutaProjectNode *new_group = NULL;
-
-    g_return_val_if_fail (project != NULL, NULL);
-    
-    gui = load_interface ("new_group_dialog");
-    g_return_val_if_fail (gui != NULL, NULL);
-    
-    /* get all needed widgets */
-    dialog = GTK_WIDGET (gtk_builder_get_object (gui, "new_group_dialog"));
-    groups_view = GTK_WIDGET (gtk_builder_get_object (gui, "groups_view"));
-    group_name_entry = GTK_WIDGET (gtk_builder_get_object (gui, "group_name_entry"));
-    ok_button = GTK_WIDGET (gtk_builder_get_object (gui, "ok_group_button"));
-    
-    /* set up dialog */
-    if (default_group_name_to_add)
-        gtk_entry_set_text (GTK_ENTRY (group_name_entry),
-                            default_group_name_to_add);
-    g_signal_connect (group_name_entry, "changed",
-                      (GCallback) entry_changed_cb, ok_button);
-    if (default_group_name_to_add)
-        gtk_widget_set_sensitive (ok_button, TRUE);
-    else
-        gtk_widget_set_sensitive (ok_button, FALSE);
-    
-    setup_groups_treeview (project, groups_view, default_group);
-    gtk_widget_show (groups_view);
-    
-    if (parent) {
-        gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
-    }
-    
-    /* execute dialog */
-    while (!finished) {
-        response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-        switch (response) {
-            case GTK_RESPONSE_OK: 
-            {
-                GError *err = NULL;
-                AnjutaProjectNode *group;
-                gchar *name;
-            
-                name = gtk_editable_get_chars (
-                    GTK_EDITABLE (group_name_entry), 0, -1);
-                
-                group = gbf_project_view_find_selected (GBF_PROJECT_VIEW (groups_view),
-                                                       ANJUTA_PROJECT_GROUP);
-                if (group) {
-                    new_group = anjuta_pm_project_add_group (project, group, name, &err);
-                    if (err) {
-                        error_dialog (parent, _("Cannot add group"), "%s",
-                                      err->message);
-                        g_error_free (err);
-                    } else {
-			finished = TRUE;
-		    }
-                } else {
-                    error_dialog (parent, _("Cannot add group"),
-				  "%s", _("No parent group selected"));
-                }
-                g_free (name);
-                break;
-            }
-            default:
-                finished = TRUE;
-                break;
-        }
-    }
-    
-    /* destroy stuff */
-    gtk_widget_destroy (dialog);
-    g_object_unref (gui);
-    return new_group;
-}
-
 enum {
     TARGET_TYPE_TYPE = 0,
     TARGET_TYPE_NAME,
@@ -400,7 +315,7 @@ gbf_project_util_new_target (AnjutaPmProject *project,
                 }
                 
                 if (group && type) {
-                    new_target = anjuta_pm_project_add_target (project, group, name, type, &err);
+                    new_target = anjuta_pm_project_add_target (project, group, NULL, name, type, &err);
                     if (err) {
                         error_dialog (parent, _("Cannot add target"), "%s",
                                       err->message);
@@ -542,283 +457,6 @@ setup_modules_treeview (AnjutaPmProject *project,
     gtk_tree_path_free (path);
 }
 
-static void
-browse_button_clicked_cb (GtkWidget *widget, gpointer user_data)
-{
-    GtkTreeView *tree = user_data;
-    gchar *file, *uri;
-	GFile *gio_file, *tmp;
-    GtkFileChooserDialog* dialog;
-	GtkTreeModel* model;
-    GtkTreeIter iter;
-    gint result;
-    
-    g_return_if_fail (user_data != NULL && GTK_IS_TREE_VIEW (user_data));
-	
-	model = gtk_tree_view_get_model(tree);
-	if (gtk_tree_model_get_iter_first(model, &iter))
-	{
-		gtk_tree_model_get(model, &iter, COLUMN_URI, &file, -1);
-		uri = g_strdup(file);
-	}
-	else
-		uri = g_strdup("");
-	
-    dialog = GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new (_("Select sourcesâ?¦"),
-				      GTK_WINDOW (gtk_widget_get_toplevel (widget)),
-				      GTK_FILE_CHOOSER_ACTION_OPEN,
-				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-				      NULL));
-	/* FIXME: this is somewhat UGLY */
-	gio_file = g_file_new_for_uri (uri);
-	tmp = g_file_get_parent (gio_file);
-    g_free (uri);
-	uri = NULL;
-	if (tmp && g_file_query_exists (tmp, NULL))
-	{
-	    uri = g_file_get_uri (tmp);
-	}
-
-    
-    gtk_file_chooser_set_current_folder_uri(GTK_FILE_CHOOSER(dialog),
-    	uri ? uri : g_object_get_data (G_OBJECT (widget), "root"));
-    gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog), TRUE);
-    g_free (uri);
-
-    result = gtk_dialog_run (GTK_DIALOG (dialog));
-    switch (result)
-    {
-	case GTK_RESPONSE_ACCEPT:
-	{
-	    GSList* uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER(dialog));
-	    GSList* node_uri = uris;
-
-	    gtk_list_store_clear (GTK_LIST_STORE (model));
-
-	    while (node_uri != NULL)
-	    {
-		GtkTreeIter iter;
-		gchar* uri = node_uri->data;
-		gchar* file = g_path_get_basename (uri);
-		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_FILE,
-				    file, COLUMN_URI, uri, -1);
-		node_uri = g_slist_next (node_uri);
-	    }
-	    g_slist_free (uris);
-	    break;
-	}
-	default:
-	    break;
-    } 
-    gtk_widget_destroy (GTK_WIDGET(dialog));
-}
-
-static void
-on_row_changed(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data)
-{
-	GtkWidget* button = GTK_WIDGET(data);
-	if (gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), iter))
-		gtk_widget_set_sensitive(button, TRUE);
-	else
-		gtk_widget_set_sensitive(button, FALSE);
-}
-
-AnjutaProjectNode*
-gbf_project_util_add_source (AnjutaPmProject *project,
-                             GtkWindow           *parent,
-                             GtkTreeIter         *default_target,
-                             const gchar         *default_uri)
-{
-        GList* new_sources;
-	gchar* uri = NULL;
-	GList* uris = NULL;
-        
-        if (default_uri) {
-            uri = g_strdup (default_uri);
-            uris = g_list_append (NULL, uri);
-        }
-	new_sources = 
-		gbf_project_util_add_source_multi (project, parent,
-                                                   default_target, uris);
-	g_free (uri);
-        g_list_free (uris);
-	
-	if (new_sources && g_list_length (new_sources))
-	{
-		AnjutaProjectNode *new_source = new_sources->data;
-		g_list_free (new_sources);
-		return new_source;
-	}
-	else
-		return NULL;
-}
-
-GList* 
-gbf_project_util_add_source_multi (AnjutaPmProject *project,
-				   GtkWindow           *parent,
-                                   GtkTreeIter         *default_target,
-				   GList               *uris_to_add)
-{
-    GtkBuilder *gui;
-    GtkWidget *dialog, *source_file_tree;
-    GtkWidget *ok_button, *browse_button;
-    GtkWidget *targets_view;
-    gint response;
-    gboolean finished = FALSE;
-    gchar *project_root;
-    GtkListStore* list;
-    GtkCellRenderer* renderer;
-    GtkTreeViewColumn* column_filename;
-    GList* new_sources = NULL;
-    GList* uri_node;
-    
-    g_return_val_if_fail (project != NULL, NULL);
-    
-    gui = load_interface ("add_source_dialog");
-    g_return_val_if_fail (gui != NULL, NULL);
-    
-    /* get all needed widgets */
-    dialog = GTK_WIDGET (gtk_builder_get_object (gui, "add_source_dialog"));
-    targets_view = GTK_WIDGET (gtk_builder_get_object (gui, "targets_view"));
-    source_file_tree = GTK_WIDGET (gtk_builder_get_object (gui, "source_file_tree"));
-    browse_button = GTK_WIDGET (gtk_builder_get_object (gui, "browse_button"));
-    ok_button = GTK_WIDGET (gtk_builder_get_object (gui, "ok_source_button"));
-
-    /* Prepare file tree */
-    list = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
-    gtk_tree_view_set_model (GTK_TREE_VIEW (source_file_tree),
-			     GTK_TREE_MODEL (list));
-    renderer = gtk_cell_renderer_text_new ();
-    column_filename = gtk_tree_view_column_new_with_attributes ("Files",
-							        renderer,
-							        "text",
-							        COLUMN_FILE,
-							        NULL);
-    gtk_tree_view_column_set_sizing (column_filename,
-				     GTK_TREE_VIEW_COLUMN_FIXED);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (source_file_tree),
-				 column_filename);
-    
-    /* set up dialog */
-   uri_node = uris_to_add;
-   while (uri_node) 
-   {
-        GtkTreeIter iter;
-        gchar* filename = g_path_get_basename (uri_node->data);
-        if (!filename)
-        	filename = g_strdup (uri_node->data);
-        gtk_list_store_append (list, &iter);
-        gtk_list_store_set (list, &iter, COLUMN_FILE, filename,
-			    COLUMN_URI, g_strdup(uri_node->data), -1);
-	g_free (filename);
-    	uri_node = g_list_next (uri_node);
-    }
-    if (!g_list_length (uris_to_add))
-	gtk_widget_set_sensitive (ok_button, FALSE);
-    else
-	gtk_widget_set_sensitive (ok_button, TRUE);
-
-    g_signal_connect (G_OBJECT(list), "row_changed",
-		      G_CALLBACK(on_row_changed), ok_button);
-    
-    g_signal_connect (browse_button, "clicked",
-                      G_CALLBACK (browse_button_clicked_cb), source_file_tree);
-    
-    g_object_get (project, "project-dir", &project_root, NULL);
-    g_object_set_data_full (G_OBJECT (browse_button), "root",
-                            project_root, g_free);
-    
-    setup_targets_treeview (project, targets_view, default_target);
-    gtk_widget_show (targets_view);
-    
-    if (parent) {
-        gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
-    }
-
-    if (default_target)
-        gtk_widget_grab_focus (source_file_tree);
-    else
-        gtk_widget_grab_focus (targets_view);
-    
-    /* execute dialog */
-    while (!finished) {
-        response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-        switch (response) {
-            case GTK_RESPONSE_OK: 
-            {
-                AnjutaProjectNode *target;
-            
-                target = gbf_project_view_find_selected (GBF_PROJECT_VIEW (targets_view),
-                                                         ANJUTA_PROJECT_TARGET);
-		if (target) {
-		    GtkTreeIter iter;
-		    GString *err_mesg = g_string_new (NULL);
-		    
-		    if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list),
-							&iter))
-			break;
-		    do
-		    {
-			GError *err = NULL;
-			AnjutaProjectNode* new_source;
-			gchar* uri;
-                        GFile* source_file;
-
-			gtk_tree_model_get (GTK_TREE_MODEL(list), &iter,
-					    COLUMN_URI, &uri, -1);
-
-                        source_file = g_file_new_for_uri (uri);
-			new_source = anjuta_pm_project_add_source (project,
-							     target,
-							     source_file,
-							     &err);
-                        g_object_unref (source_file);
-			if (err) {
-			    gchar *str = g_strdup_printf ("%s: %s\n",
-							  uri,
-							  err->message);
-			    g_string_append (err_mesg, str);
-			    g_error_free (err);
-			    g_free (str);
-			}
-			else
-			    new_sources = g_list_append (new_sources,
-							 new_source);
-			
-			g_free (uri);
-		    } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(list),
-						       &iter));
-		    
-		    if (err_mesg->str && strlen (err_mesg->str) > 0) {
-			error_dialog (parent, _("Cannot add source files"),
-				      "%s", err_mesg->str);
-		    } else {
-			finished = TRUE;
-		    }
-		    g_string_free (err_mesg, TRUE);
-                } else {
-                    error_dialog (parent, _("Cannot add source files"),
-				  "%s", _("No target has been selected"));
-                }
-                
-                break;
-            }
-            default:
-		gtk_list_store_clear (GTK_LIST_STORE (list));
-                finished = TRUE;
-                break;
-        }
-    }
-    
-    /* destroy stuff */
-    gtk_widget_destroy (dialog);
-    g_object_unref (gui);
-    return new_sources;
-}
-
 GList *
 gbf_project_util_all_child (AnjutaProjectNode *parent, AnjutaProjectNodeType type)
 {
diff --git a/plugins/project-manager/project.c b/plugins/project-manager/project.c
index cd0a0c4..25a3639 100644
--- a/plugins/project-manager/project.c
+++ b/plugins/project-manager/project.c
@@ -536,6 +536,7 @@ static gboolean
 pm_command_add_setup (AnjutaPmProject *project, PmJob *job)
 {
 	AnjutaProjectNode *parent;
+	AnjutaProjectNode *sibling;
 	
 	g_return_val_if_fail (job != NULL, FALSE);
 	g_return_val_if_fail (job->node != NULL, FALSE);
@@ -543,8 +544,10 @@ pm_command_add_setup (AnjutaPmProject *project, PmJob *job)
 	/* Add new node in project tree.
 	 * It is safe to do it here because the worker thread is waiting */
 	parent = anjuta_project_node_parent (job->node);
+	sibling = job->node->prev;
 	job->node->parent = NULL;
-	anjuta_project_node_insert_before (parent, NULL, job->node);
+	job->node->prev = NULL;
+	anjuta_project_node_insert_before (parent, sibling, job->node);
 	
 	return TRUE;
 }
@@ -817,13 +820,41 @@ anjuta_pm_project_refresh (AnjutaPmProject *project, GError **error)
 	return TRUE;
 }
 
-IAnjutaProjectCapabilities
+gint
 anjuta_pm_project_get_capabilities (AnjutaPmProject *project)
 {
-	IAnjutaProjectCapabilities caps = IANJUTA_PROJECT_CAN_ADD_NONE;
+	gint caps = 0;
 
 	if (project->project != NULL)
-		caps = ianjuta_project_get_capabilities (project->project, NULL);
+	{
+		GList *item;
+
+		for (item = anjuta_pm_project_get_node_info (project); item != NULL; item = g_list_next (item))
+		{
+			AnjutaProjectNodeInfo *info = (AnjutaProjectNodeInfo *)item->data;
+
+			switch (info->type & ANJUTA_PROJECT_TYPE_MASK)
+			{
+			case ANJUTA_PROJECT_GROUP:
+				caps |= ANJUTA_PROJECT_CAN_ADD_GROUP;
+				break;
+			case ANJUTA_PROJECT_TARGET:
+				caps |= ANJUTA_PROJECT_CAN_ADD_TARGET;
+				break;
+			case ANJUTA_PROJECT_SOURCE:
+				caps |= ANJUTA_PROJECT_CAN_ADD_SOURCE;
+				break;
+			case ANJUTA_PROJECT_MODULE:
+				caps |= ANJUTA_PROJECT_CAN_ADD_MODULE;
+				break;
+			case ANJUTA_PROJECT_PACKAGE:
+				caps |= ANJUTA_PROJECT_CAN_ADD_PACKAGE;
+				break;
+			default:
+				break;
+			}
+		}
+	}
 
 	return caps;
 }
@@ -851,36 +882,41 @@ anjuta_pm_project_get_packages (AnjutaPmProject *project)
 }
 
 AnjutaProjectNode *
-anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *group, const gchar *name, GError **error)
+anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, GError **error)
 {
 	AnjutaProjectNode *node;
 	
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	node = ianjuta_project_new_node (project->project, group, ANJUTA_PROJECT_GROUP, NULL, name, error);
+	node = ianjuta_project_new_node (project->project, parent, ANJUTA_PROJECT_GROUP, NULL, name, error);
+	node->parent = parent;
+	node->prev = sibling;
 	pm_project_push_command (project, ADD, node);
 
 	return node;
 }
 
 AnjutaProjectNode *
-anjuta_pm_project_add_target (AnjutaPmProject *project, AnjutaProjectNode *group, const gchar *name, AnjutaProjectNodeType type, GError **error)
+anjuta_pm_project_add_target (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, AnjutaProjectNodeType type, GError **error)
 {
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	return ianjuta_project_add_target (project->project, group, name, type, error);
+	return ianjuta_project_add_target (project->project, parent, name, type, error);
 }
 
 AnjutaProjectNode *
-anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *target, GFile *file, GError **error)
+anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, GError **error)
 {
-	AnjutaProjectNode *source;
+	AnjutaProjectNode *node;
 
 	g_return_val_if_fail (project->project != NULL, NULL);
 	
-	source = ianjuta_project_add_source (project->project, target, file, error);
+	node = ianjuta_project_new_node (project->project, parent, ANJUTA_PROJECT_SOURCE, NULL, name, error);
+	node->parent = parent;
+	node->prev = sibling;
+	pm_project_push_command (project, ADD, node);
 
-	return source;
+	return node;
 }
 
 gboolean
diff --git a/plugins/project-manager/project.h b/plugins/project-manager/project.h
index 8434892..f44989a 100644
--- a/plugins/project-manager/project.h
+++ b/plugins/project-manager/project.h
@@ -86,14 +86,14 @@ gboolean anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError *
 gboolean anjuta_pm_project_unload (AnjutaPmProject *project, GError **error);
 gboolean anjuta_pm_project_refresh (AnjutaPmProject *project, GError **error);
 
-IAnjutaProjectCapabilities anjuta_pm_project_get_capabilities (AnjutaPmProject *project);
+gint anjuta_pm_project_get_capabilities (AnjutaPmProject *project);
 GList *anjuta_pm_project_get_node_info (AnjutaPmProject *project);
 
 GList *anjuta_pm_project_get_packages (AnjutaPmProject *project);
 
-AnjutaProjectNode *anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *group, const gchar *name, GError **error);
-AnjutaProjectNode *anjuta_pm_project_add_target (AnjutaPmProject *project, AnjutaProjectNode *group, const gchar *name, AnjutaProjectNodeType type, GError **error);
-AnjutaProjectNode *anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *target, GFile *file, GError **error);
+AnjutaProjectNode *anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, GError **error);
+AnjutaProjectNode *anjuta_pm_project_add_target (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, AnjutaProjectNodeType type, GError **error);
+AnjutaProjectNode *anjuta_pm_project_add_source (AnjutaPmProject *project, AnjutaProjectNode *parent, AnjutaProjectNode *sibling, const gchar *name, GError **error);
 AnjutaProjectNode *anjuta_pm_project_get_root (AnjutaPmProject *project);
 gboolean anjuta_pm_project_remove (AnjutaPmProject *project, AnjutaProjectNode *node, GError **error);
 gboolean anjuta_pm_project_remove_data (AnjutaPmProject *project, GbfTreeData *data, GError **error);



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