[anjuta/newproject] Open a directory as a project



commit dfdc221b024d9690cf212c60033eaa122fdaa9c1
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sun Dec 20 16:11:34 2009 +0100

    Open a directory as a project

 configure.in                                  |    1 +
 plugins/Makefile.am                           |    3 +-
 plugins/dir-project/Makefile.am               |   53 ++
 plugins/dir-project/dir-project-plugin-48.png |  Bin 0 -> 866 bytes
 plugins/dir-project/dir-project.c             |  657 +++++++++++++++++++++++++
 plugins/dir-project/dir-project.h             |  122 +++++
 plugins/dir-project/dir-project.plugin.in     |   11 +
 plugins/dir-project/plugin.c                  |  126 +++++
 plugins/dir-project/plugin.h                  |   47 ++
 plugins/mk-project/plugin.c                   |    6 +-
 plugins/project-manager/gbf-project-model.c   |   24 +-
 plugins/project-manager/gbf-project-util.c    |   22 +-
 plugins/project-manager/gbf-project-view.c    |    2 +-
 plugins/project-manager/gbf-tree-data.c       |    2 +-
 plugins/project-manager/gbf-tree-data.h       |    2 +-
 plugins/project-manager/plugin.c              |   16 +-
 16 files changed, 1075 insertions(+), 19 deletions(-)
---
diff --git a/configure.in b/configure.in
index 00dd6d1..5721780 100644
--- a/configure.in
+++ b/configure.in
@@ -800,6 +800,7 @@ plugins/project-wizard/templates/library/po/Makefile
 plugins/project-wizard/templates/m4/Makefile
 plugins/am-project/Makefile
 plugins/mk-project/Makefile
+plugins/dir-project/Makefile
 plugins/language-support-cpp-java/Makefile
 plugins/language-support-cpp-java/cxxparser/Makefile
 plugins/run-program/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index dd017b6..29ea2af 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -31,6 +31,7 @@ SUBDIRS = . \
 	run-program \
 	starter \
 	am-project \
-	mk-project
+	mk-project \
+	dir-project
 
 -include $(top_srcdir)/git.mk
diff --git a/plugins/dir-project/Makefile.am b/plugins/dir-project/Makefile.am
new file mode 100644
index 0000000..9d80ba7
--- /dev/null
+++ b/plugins/dir-project/Makefile.am
@@ -0,0 +1,53 @@
+# Plugin UI file
+plugin_uidir = $(anjuta_ui_dir)
+plugin_ui_DATA = 
+
+# Plugin glade file
+plugin_gladedir = $(anjuta_glade_dir)
+plugin_glade_DATA =
+
+# Plugin icon file
+plugin_pixmapsdir = $(anjuta_image_dir)
+plugin_pixmaps_DATA = dir-project-plugin-48.png
+
+# Plugin description file
+plugin_in_files = dir-project.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugindir = $(anjuta_plugin_dir)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+AM_CPPFLAGS = 					\
+	$(WARN_CFLAGS) \
+	$(DEPRECATED_FLAGS) \
+	$(GIO_CFLAGS) \
+	$(LIBANJUTA_CFLAGS) \
+	-DG_LOG_DOMAIN=\"dir-project\"
+
+plugin_LTLIBRARIES = \
+	libdir-project.la
+
+libdir_project_la_SOURCES = \
+	plugin.c \
+	plugin.h \
+	dir-project.c \
+	dir-project.h
+
+libdir_project_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
+
+libdir_project_la_LIBADD = \
+	$(GIO_LIBS) \
+	$(LIBANJUTA_LIBS)
+
+
+EXTRA_DIST = \
+	$(plugin_in_files) \
+	$(plugin_DATA) \
+	$(plugin_ui_DATA) \
+	$(plugin_pixmaps_DATA) \
+	$(plugin_glade_DATA)
+
+DISTCLEANFILES = \
+	$(plugin_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/dir-project/dir-project-plugin-48.png b/plugins/dir-project/dir-project-plugin-48.png
new file mode 100644
index 0000000..49beafd
Binary files /dev/null and b/plugins/dir-project/dir-project-plugin-48.png differ
diff --git a/plugins/dir-project/dir-project.c b/plugins/dir-project/dir-project.c
new file mode 100644
index 0000000..77c0ac0
--- /dev/null
+++ b/plugins/dir-project/dir-project.c
@@ -0,0 +1,657 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-project.c
+ *
+ * Copyright (C) 2009  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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dir-project.h"
+
+#include <libanjuta/interfaces/ianjuta-project.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/anjuta-utils.h>
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <glib.h>
+
+struct _DirProject {
+	GObject         parent;
+
+	GFile			*root_file;
+
+	AnjutaProjectGroup        *root_node;
+	
+	/* shortcut hash tables, mapping id -> GNode from the tree above */
+	GHashTable		*groups;
+	
+	/* project files monitors */
+	GHashTable      *monitors;
+};
+
+/* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
+#define DIR_NODE_DATA(node)  ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
+#define DIR_GROUP_DATA(node)  ((node) != NULL ? (DirGroupData *)((node)->data) : NULL)
+#define DIR_TARGET_DATA(node)  ((node) != NULL ? (DirTargetData *)((node)->data) : NULL)
+#define DIR_SOURCE_DATA(node)  ((node) != NULL ? (DirSourceData *)((node)->data) : NULL)
+
+
+typedef struct _DirGroupData DirGroupData;
+
+struct _DirGroupData {
+	AnjutaProjectGroupData base;
+};
+
+typedef struct _DirTargetData DirTargetData;
+
+struct _DirTargetData {
+	AnjutaProjectTargetData base;
+};
+
+typedef struct _DirSourceData DirSourceData;
+
+struct _DirSourceData {
+	AnjutaProjectSourceData base;
+};
+
+
+/* ----- Standard GObject types and variables ----- */
+
+enum {
+	PROP_0,
+	PROP_PROJECT_DIR
+};
+
+static GObject *parent_class;
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+error_set (GError **error, gint code, const gchar *message)
+{
+        if (error != NULL) {
+                if (*error != NULL) {
+                        gchar *tmp;
+
+                        /* error already created, just change the code
+                         * and prepend the string */
+                        (*error)->code = code;
+                        tmp = (*error)->message;
+                        (*error)->message = g_strconcat (message, "\n\n", tmp, NULL);
+                        g_free (tmp);
+
+                } else {
+                        *error = g_error_new_literal (IANJUTA_PROJECT_ERROR,
+                                                      code,
+                                                      message);
+                }
+        }
+}
+
+/*
+ * File monitoring support --------------------------------
+ * FIXME: review these
+ */
+static void
+monitor_cb (GFileMonitor *monitor,
+			GFile *file,
+			GFile *other_file,
+			GFileMonitorEvent event_type,
+			gpointer data)
+{
+	DirProject *project = data;
+
+	g_return_if_fail (project != NULL && DIR_IS_PROJECT (project));
+
+	switch (event_type) {
+		case G_FILE_MONITOR_EVENT_CHANGED:
+		case G_FILE_MONITOR_EVENT_DELETED:
+			/* monitor will be removed here... is this safe? */
+			dir_project_reload (project, NULL);
+			g_signal_emit_by_name (G_OBJECT (project), "project-updated");
+			break;
+		default:
+			break;
+	}
+}
+
+
+static void
+monitor_add (DirProject *project, GFile *file)
+{
+	GFileMonitor *monitor = NULL;
+	
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (project->monitors != NULL);
+	
+	if (file == NULL)
+		return;
+	
+	monitor = g_hash_table_lookup (project->monitors, file);
+	if (!monitor) {
+		gboolean exists;
+		
+		/* FIXME clarify if uri is uri, path or both */
+		exists = g_file_query_exists (file, NULL);
+		
+		if (exists) {
+			monitor = g_file_monitor_file (file, 
+						       G_FILE_MONITOR_NONE,
+						       NULL,
+						       NULL);
+			if (monitor != NULL)
+			{
+				g_signal_connect (G_OBJECT (monitor),
+						  "changed",
+						  G_CALLBACK (monitor_cb),
+						  project);
+				g_hash_table_insert (project->monitors,
+						     g_object_ref (file),
+						     monitor);
+			}
+		}
+	}
+}
+
+static void
+monitors_remove (DirProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	if (project->monitors)
+		g_hash_table_destroy (project->monitors);
+	project->monitors = NULL;
+}
+
+static void
+group_hash_foreach_monitor (gpointer key,
+			    gpointer value,
+			    gpointer user_data)
+{
+	DirGroup *group_node = value;
+	DirProject *project = user_data;
+
+	monitor_add (project, DIR_GROUP_DATA(group_node)->base.directory);
+}
+
+static void
+monitors_setup (DirProject *project)
+{
+	g_return_if_fail (project != NULL);
+
+	monitors_remove (project);
+	
+	/* setup monitors hash */
+	project->monitors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+						   (GDestroyNotify) g_file_monitor_cancel);
+
+	monitor_add (project, project->root_file);
+	
+	if (project->groups)
+		g_hash_table_foreach (project->groups, group_hash_foreach_monitor, project);
+}
+
+static DirGroup*
+dir_group_new (GFile *file)
+{
+    DirGroupData *group = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	
+	group = g_slice_new0(DirGroupData); 
+	group->base.node.type = ANJUTA_PROJECT_GROUP;
+	group->base.directory = g_object_ref (file);
+
+    return g_node_new (group);
+}
+
+static void
+dir_group_free (DirGroup *node)
+{
+    DirGroupData *group = (DirGroupData *)node->data;
+	
+	if (group->base.directory) g_object_unref (group->base.directory);
+    g_slice_free (DirGroupData, group);
+
+	g_node_destroy (node);
+}
+
+/* Target objects
+ *---------------------------------------------------------------------------*/
+
+static DirTarget*
+dir_target_new (const gchar *name, AnjutaProjectTargetType type)
+{
+    DirTargetData *target = NULL;
+
+	target = g_slice_new0(DirTargetData); 
+	target->base.node.type = ANJUTA_PROJECT_TARGET;
+	target->base.name = g_strdup (name);
+	target->base.type = type;
+
+    return g_node_new (target);
+}
+
+static void
+dir_target_free (DirTarget *node)
+{
+    DirTargetData *target = DIR_TARGET_DATA (node);
+	
+    g_free (target->base.name);
+    g_slice_free (DirTargetData, target);
+
+	g_node_destroy (node);
+}
+
+/* Source objects
+ *---------------------------------------------------------------------------*/
+
+static DirSource*
+dir_source_new (GFile *file)
+{
+    DirSourceData *source = NULL;
+
+	source = g_slice_new0(DirSourceData); 
+	source->base.node.type = ANJUTA_PROJECT_SOURCE;
+	source->base.file = g_object_ref (file);
+
+    return g_node_new (source);
+}
+
+static void
+dir_source_free (DirSource *node)
+{
+    DirSourceData *source = DIR_SOURCE_DATA (node);
+	
+    g_object_unref (source->base.file);
+    g_slice_free (DirSourceData, source);
+
+	g_node_destroy (node);
+}
+
+
+static void
+foreach_node_destroy (AnjutaProjectNode    *g_node,
+		      gpointer  data)
+{
+	switch (DIR_NODE_DATA (g_node)->type) {
+		case ANJUTA_PROJECT_GROUP:
+			dir_group_free (g_node);
+			break;
+		case ANJUTA_PROJECT_TARGET:
+			dir_target_free (g_node);
+			break;
+		case ANJUTA_PROJECT_SOURCE:
+			dir_source_free (g_node);
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+}
+
+static void
+project_node_destroy (DirProject *project, AnjutaProjectNode *g_node)
+{
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (DIR_IS_PROJECT (project));
+	
+	if (g_node) {
+		/* free each node's data first */
+		g_message ("destroy for each node %p project %p", g_node, project);
+		anjuta_project_node_all_foreach (g_node,
+				 foreach_node_destroy, project);
+		g_message ("destroy node %p", g_node);
+	}
+}
+
+static gboolean
+dir_project_list_directory (DirProject *project, DirGroup* parent, GError **error) 
+{
+	gboolean ok;
+	GFileEnumerator *enumerator;
+
+	enumerator = g_file_enumerate_children (DIR_GROUP_DATA (parent)->base.directory,
+	    G_FILE_ATTRIBUTE_STANDARD_NAME,
+	    G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+	    NULL,
+	    error);
+
+	ok = enumerator != NULL;
+	if (ok)
+	{
+		GFileInfo *info;
+		
+		while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL)
+		{
+			const gchar *name;
+			GFile *file;
+
+			name = g_file_info_get_name (info);
+			file = g_file_get_child (DIR_GROUP_DATA (parent)->base.directory, name);
+			g_object_unref (info);
+
+			if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY)
+			{
+				DirGroup *group;
+				
+				group = dir_group_new (file);
+				g_hash_table_insert (project->groups, g_file_get_uri (file), group);
+				anjuta_project_node_append (parent, group);
+				ok = dir_project_list_directory (project, group, error);
+				if (!ok) break;
+			}
+			else
+			{
+				DirSource *source;
+
+				source = dir_source_new (file);
+				anjuta_project_node_append (parent, source);
+			}
+		}
+        g_file_enumerator_close (enumerator, NULL, NULL);
+        g_object_unref (enumerator);
+	}
+
+	return ok;
+}
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+dir_project_reload (DirProject *project, GError **error) 
+{
+	GFile *root_file;
+	DirGroup *group;
+	gboolean ok = TRUE;
+
+	/* Unload current project */
+	root_file = g_object_ref (project->root_file);
+	dir_project_unload (project);
+	project->root_file = root_file;
+	DEBUG_PRINT ("reload project %p root file %p", project, project->root_file);
+	g_message ("reload project %p", project);
+
+	/* shortcut hash tables */
+	project->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+	if (g_file_query_file_type (root_file, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+
+		return FALSE;
+	}
+
+	group = dir_group_new (root_file);
+	g_hash_table_insert (project->groups, g_file_get_uri (root_file), group);
+	g_message ("project create root node %p", project->root_node);
+	project->root_node = group;
+
+	dir_project_list_directory (project, group, NULL);
+	
+	monitors_setup (project);
+	
+	return ok;
+}
+
+gboolean
+dir_project_load (DirProject  *project,
+    GFile *directory,
+	GError     **error)
+{
+	g_return_val_if_fail (directory != NULL, FALSE);
+
+	project->root_file = g_object_ref (directory);
+	if (!dir_project_reload (project, error))
+	{
+		g_object_unref (project->root_file);
+		project->root_file = NULL;
+	}
+
+	return project->root_file != NULL;
+}
+
+void
+dir_project_unload (DirProject *project)
+{
+	monitors_remove (project);
+	
+	/* project data */
+	project_node_destroy (project, project->root_node);
+	project->root_node = NULL;
+
+	if (project->root_file) g_object_unref (project->root_file);
+	project->root_file = NULL;
+
+	/* shortcut hash tables */
+	if (project->groups) g_hash_table_destroy (project->groups);
+	project->groups = NULL;
+}
+
+gint
+dir_project_probe (GFile *file,
+	    GError     **error)
+{
+	gint probe;
+
+	probe = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY;
+	if (!probe)
+	{
+		g_set_error (error, IANJUTA_PROJECT_ERROR, 
+		             IANJUTA_PROJECT_ERROR_DOESNT_EXIST,
+			   _("Project doesn't exist or invalid path"));
+	}
+
+	return probe ? IANJUTA_PROJECT_PROBE_FILES : 0;
+}
+
+static DirGroup* 
+dir_project_add_group (DirProject  *project,
+		DirGroup *parent,
+		const gchar *name,
+		GError     **error)
+{
+	return NULL;
+}
+
+static DirTarget*
+dir_project_add_target (DirProject  *project,
+		 DirGroup *parent,
+		 const gchar *name,
+		 AnjutaProjectTargetType type,
+		 GError     **error)
+{
+	return NULL;
+}
+
+static DirSource* 
+dir_project_add_source (DirProject  *project,
+		 DirTarget *target,
+		 GFile *file,
+		 GError     **error)
+{
+	return NULL;
+}
+
+static GList *
+dir_project_get_target_types (DirProject *project, GError **error)
+{
+	static AnjutaProjectTargetInformation unknown_type = {N_("Unknown"), ANJUTA_TARGET_UNKNOWN,"text/plain"};
+
+	return g_list_prepend (NULL, &unknown_type);
+}
+
+static DirGroup *
+dir_project_get_root (DirProject *project)
+{
+	return project->root_node;
+}
+
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+DirProject *
+dir_project_new (void)
+{
+	return DIR_PROJECT (g_object_new (DIR_TYPE_PROJECT, NULL));
+}
+
+
+/* Implement IAnjutaProject
+ *---------------------------------------------------------------------------*/
+
+static AnjutaProjectGroup* 
+iproject_add_group (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name, GError **err)
+{
+	return dir_project_add_group (DIR_PROJECT (obj), parent, name, err);
+}
+
+static AnjutaProjectSource* 
+iproject_add_source (IAnjutaProject *obj, AnjutaProjectGroup *parent,  GFile *file, GError **err)
+{
+	return dir_project_add_source (DIR_PROJECT (obj), parent, file, err);
+}
+
+static AnjutaProjectTarget* 
+iproject_add_target (IAnjutaProject *obj, AnjutaProjectGroup *parent,  const gchar *name,  AnjutaProjectTargetType type, GError **err)
+{
+	return dir_project_add_target (DIR_PROJECT (obj), parent, name, type, err);
+}
+
+static GtkWidget* 
+iproject_configure (IAnjutaProject *obj, GError **err)
+{
+	return NULL;
+}
+
+static guint 
+iproject_get_capabilities (IAnjutaProject *obj, GError **err)
+{
+	return IANJUTA_PROJECT_CAN_ADD_NONE;
+}
+
+static GList* 
+iproject_get_packages (IAnjutaProject *obj, GError **err)
+{
+	return NULL;
+}
+
+static AnjutaProjectGroup* 
+iproject_get_root (IAnjutaProject *obj, GError **err)
+{
+	return dir_project_get_root (DIR_PROJECT (obj));
+}
+
+static GList* 
+iproject_get_target_types (IAnjutaProject *obj, GError **err)
+{
+	return dir_project_get_target_types (DIR_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_load (IAnjutaProject *obj, GFile *file, GError **err)
+{
+	return dir_project_load (DIR_PROJECT (obj), file, err);
+}
+
+static gboolean
+iproject_refresh (IAnjutaProject *obj, GError **err)
+{
+	return dir_project_reload (DIR_PROJECT (obj), err);
+}
+
+static gboolean
+iproject_remove_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+{
+	return TRUE;
+}
+
+static void
+iproject_iface_init(IAnjutaProjectIface* iface)
+{
+	iface->add_group = iproject_add_group;
+	iface->add_source = iproject_add_source;
+	iface->add_target = iproject_add_target;
+	iface->configure = iproject_configure;
+	iface->get_capabilities = iproject_get_capabilities;
+	iface->get_packages = iproject_get_packages;
+	iface->get_root = iproject_get_root;
+	iface->get_target_types = iproject_get_target_types;
+	iface->load = iproject_load;
+	iface->refresh = iproject_refresh;
+	iface->remove_node = iproject_remove_node;
+}
+
+/* GbfProject implementation
+ *---------------------------------------------------------------------------*/
+
+static void
+dir_project_dispose (GObject *object)
+{
+	g_return_if_fail (DIR_IS_PROJECT (object));
+
+	dir_project_unload (DIR_PROJECT (object));
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);	
+}
+
+static void
+dir_project_instance_init (DirProject *project)
+{
+	g_return_if_fail (project != NULL);
+	g_return_if_fail (DIR_IS_PROJECT (project));
+	
+	/* project data */
+	project->root_file = NULL;
+	project->root_node = NULL;
+
+	project->monitors = NULL;
+	project->groups = NULL;
+}
+
+static void
+dir_project_class_init (DirProjectClass *klass)
+{
+	GObjectClass *object_class;
+	
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->dispose = dir_project_dispose;
+}
+
+ANJUTA_TYPE_BEGIN(DirProject, dir_project, G_TYPE_OBJECT);
+ANJUTA_TYPE_ADD_INTERFACE(iproject, IANJUTA_TYPE_PROJECT);
+ANJUTA_TYPE_END;
diff --git a/plugins/dir-project/dir-project.h b/plugins/dir-project/dir-project.h
new file mode 100644
index 0000000..b7202df
--- /dev/null
+++ b/plugins/dir-project/dir-project.h
@@ -0,0 +1,122 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
+/* am-project.h
+ *
+ * Copyright (C) 2009  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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DIR_PROJECT_H_
+#define _DIR_PROJECT_H_
+
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-project.h>
+
+G_BEGIN_DECLS
+
+#define DIR_TYPE_PROJECT			(dir_project_get_type ())
+#define DIR_PROJECT(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), DIR_TYPE_PROJECT, DirProject))
+#define DIR_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), DIR_TYPE_PROJECT, DirProjectClass))
+#define DIR_IS_PROJECT(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), DIR_TYPE_PROJECT))
+#define DIR_IS_PROJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), DIR_TYPE_PROJECT))
+
+#define DIR_GROUP(obj)		((DirGroup *)obj)
+#define DIR_TARGET(obj)		((DirTarget *)obj)
+#define DIR_SOURCE(obj)		((DirSource *)obj)
+
+
+typedef struct _DirProject        DirProject;
+typedef struct _DirProjectClass   DirProjectClass;
+
+struct _DirProjectClass {
+	GObjectClass parent_class;
+};
+
+typedef AnjutaProjectGroup DirGroup;
+typedef AnjutaProjectTarget DirTarget;
+typedef AnjutaProjectSource DirSource;
+
+
+GType         dir_project_get_type (void);
+DirProject   *dir_project_new      (void);
+
+gint dir_project_probe (GFile *directory, GError     **error);
+
+gboolean dir_project_load (DirProject *project, GFile *directory, GError **error);
+gboolean dir_project_reload (DirProject *project, GError **error);
+void dir_project_unload (DirProject *project);
+
+#if 0
+AmpGroup *amp_project_get_root (AmpProject *project);
+AmpGroup *amp_project_get_group (AmpProject *project, const gchar *id);
+AmpTarget *amp_project_get_target (AmpProject *project, const gchar *id);
+AmpSource *amp_project_get_source (AmpProject *project, const gchar *id);
+gboolean amp_project_get_token_location (AmpProject *project, AnjutaTokenFileLocation *location, AnjutaToken *token);
+
+gboolean amp_project_move (AmpProject *project, const gchar *path);
+gboolean amp_project_save (AmpProject *project, GError **error);
+
+gchar * amp_project_get_uri (AmpProject *project);
+GFile* amp_project_get_file (AmpProject *project);
+
+AmpGroup* amp_project_add_group (AmpProject  *project, AmpGroup *parent, const gchar *name, GError **error);
+AmpGroup* amp_project_add_sibling_group (AmpProject  *project, AmpGroup *parent, const gchar *name, gboolean after, AmpGroup *sibling, GError **error);
+void amp_project_remove_group (AmpProject  *project, AmpGroup *group, GError **error);
+
+AmpTarget* amp_project_add_target (AmpProject  *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, GError **error);
+AmpTarget* amp_project_add_sibling_target (AmpProject  *project, AmpGroup *parent, const gchar *name, AnjutaProjectTargetType type, gboolean after, AmpTarget *sibling, GError **error);
+void amp_project_remove_target (AmpProject  *project, AmpTarget *target, GError **error);
+
+AmpSource* amp_project_add_source (AmpProject  *project, AmpTarget *parent, GFile *file, GError **error);
+AmpSource* amp_project_add_sibling_source (AmpProject  *project, AmpTarget *parent, GFile *file, gboolean after, AmpSource *sibling, GError **error);
+void amp_project_remove_source (AmpProject  *project, AmpSource *source, GError **error);
+
+
+GList *amp_project_get_config_modules (AmpProject *project, GError **error);
+GList *amp_project_get_config_packages  (AmpProject *project, const gchar* module, GError **error);
+
+GList *amp_project_get_target_types (AmpProject *project, GError **error);
+
+gchar* amp_project_get_property (AmpProject *project, AmpPropertyType type);
+gboolean amp_project_set_property (AmpProject *project, AmpPropertyType type, const gchar* value);
+
+gchar * amp_project_get_node_id (AmpProject *project, const gchar *path);
+
+AnjutaProjectNode *amp_node_parent (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_first_child (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_last_child (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_next_sibling (AnjutaProjectNode *node);
+AnjutaProjectNode *amp_node_prev_sibling (AnjutaProjectNode *node);
+AnjutaProjectNodeType amp_node_get_type (AnjutaProjectNode *node);
+void amp_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data);
+
+GFile *amp_group_get_directory (AmpGroup *group);
+GFile *amp_group_get_makefile (AmpGroup *group);
+gchar *amp_group_get_id (AmpGroup *group);
+
+const gchar *amp_target_get_name (AmpTarget *target);
+AnjutaProjectTargetType amp_target_get_type (AmpTarget *target);
+gchar *amp_target_get_id (AmpTarget *target);
+
+void amp_source_free (AmpSource *node);
+gchar *amp_source_get_id (AmpSource *source);
+GFile *amp_source_get_file (AmpSource *source);
+#endif
+
+G_END_DECLS
+
+#endif /* _DIR_PROJECT_H_ */
diff --git a/plugins/dir-project/dir-project.plugin.in b/plugins/dir-project/dir-project.plugin.in
new file mode 100644
index 0000000..52f46c1
--- /dev/null
+++ b/plugins/dir-project/dir-project.plugin.in
@@ -0,0 +1,11 @@
+[Anjuta Plugin]
+_Name=Directory backend
+_Description=Directory backend for project manager
+Location=dir-project:DirProjectPlugin
+Icon=dir-project-plugin-48.png
+Interfaces=IAnjutaProjectBackend
+Dependencies=anjuta-project-manager:ProjectManagerPlugin
+UserActivatable=no
+
+[Project]
+Supported-Project-Types=directory
diff --git a/plugins/dir-project/plugin.c b/plugins/dir-project/plugin.c
new file mode 100644
index 0000000..ab9d8d6
--- /dev/null
+++ b/plugins/dir-project/plugin.c
@@ -0,0 +1,126 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    plugin.c
+    Copyright (C) 2009 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 published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <config.h>
+#include <libanjuta/anjuta-debug.h>
+#include <libanjuta/gbf-project.h>
+#include <libanjuta/interfaces/ianjuta-project-backend.h>
+
+#include "plugin.h"
+#include "dir-project.h"
+
+
+#define ICON_FILE "dir-project-plugin-48.png"
+
+/* AnjutaPlugin functions
+ *---------------------------------------------------------------------------*/
+
+static gboolean
+activate_plugin (AnjutaPlugin *plugin)
+{
+	DEBUG_PRINT ("DirProjectPlugin: Activating Anjuta directory backend Plugin ...");
+	
+	return TRUE;
+}
+
+static gboolean
+deactivate_plugin (AnjutaPlugin *plugin)
+{
+	DEBUG_PRINT ("DirProjectPlugin: Deacctivating Anjuta directory backend Plugin ...");
+	return TRUE;
+}
+
+
+/* IAnjutaProjectBackend implementation
+ *---------------------------------------------------------------------------*/
+
+static IAnjutaProject*
+iproject_backend_new_project (IAnjutaProjectBackend* backend, GError** err)
+{
+	IAnjutaProject *project;
+	DEBUG_PRINT("create new directory project");	
+	project = (IAnjutaProject *)(g_object_new (DIR_TYPE_PROJECT, NULL));
+		
+	return project;
+}
+
+static gint
+iproject_backend_probe (IAnjutaProjectBackend* backend, GFile *directory, GError** err)
+{
+	DEBUG_PRINT("probe directory project");
+	
+	return dir_project_probe (directory, err);
+}
+
+static void
+iproject_backend_iface_init(IAnjutaProjectBackendIface *iface)
+{
+	iface->new_project = iproject_backend_new_project;
+	iface->probe = iproject_backend_probe;
+}
+
+/* GObject functions
+ *---------------------------------------------------------------------------*/
+
+/* Used in dispose and finalize */
+static gpointer parent_class;
+
+static void
+dir_project_plugin_instance_init (GObject *obj)
+{
+}
+
+/* dispose is used to unref object created with instance_init */
+
+static void
+dispose (GObject *obj)
+{
+	G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+/* finalize used to free object created with instance init */
+
+static void
+finalize (GObject *obj)
+{
+	G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+dir_project_plugin_class_init (GObjectClass *klass) 
+{
+	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	plugin_class->activate = activate_plugin;
+	plugin_class->deactivate = deactivate_plugin;
+	klass->dispose = dispose;
+	klass->finalize = finalize;
+}
+
+/* AnjutaPlugin declaration
+ *---------------------------------------------------------------------------*/
+
+ANJUTA_PLUGIN_BEGIN (DirProjectPlugin, dir_project_plugin);
+ANJUTA_PLUGIN_ADD_INTERFACE (iproject_backend, IANJUTA_TYPE_PROJECT_BACKEND);
+ANJUTA_PLUGIN_END;
+
+ANJUTA_SIMPLE_PLUGIN (DirProjectPlugin, dir_project_plugin);
diff --git a/plugins/dir-project/plugin.h b/plugins/dir-project/plugin.h
new file mode 100644
index 0000000..87d4943
--- /dev/null
+++ b/plugins/dir-project/plugin.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+    plugin.h
+    Copyright (C) 2009 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 published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef __PLUGIN_H__
+#define __PLUGIN_H__
+
+#include <libanjuta/anjuta-plugin.h>
+
+extern GType dir_project_plugin_get_type (GTypeModule *module);
+#define ANJUTA_TYPE_PLUGIN_DIR_PROJECT         (dir_project_plugin_get_type (NULL))
+#define ANJUTA_PLUGIN_DIR_PROJECT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), ANJUTA_TYPE_PLUGIN_DIR_PROJECT, DirProjectPlugin))
+#define ANJUTA_PLUGIN_DIR_PROJECT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), ANJUTA_TYPE_PLUGIN_DIR_PROJECT, DirProjectPluginClass))
+#define ANJUTA_IS_PLUGIN_DIR_PROJECT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), ANJUTA_TYPE_PLUGIN_DIR_PROJECT))
+#define ANJUTA_IS_PLUGIN_DIR_PROJECT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), ANJUTA_TYPE_PLUGIN_DIR_PROJECT))
+#define ANJUTA_PLUGIN_DIR_PROJECT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ANJUTA_TYPE_PLUGIN_DIR_PROJECT, DirProjectPluginClass))
+
+typedef struct _DirProjectPlugin DirProjectPlugin;
+typedef struct _DirProjectPluginClass DirProjectPluginClass;
+
+struct _DirProjectPlugin 
+{
+	AnjutaPlugin parent;
+};
+
+struct _DirProjectPluginClass
+{
+	AnjutaPluginClass parent_class;
+};
+
+#endif
diff --git a/plugins/mk-project/plugin.c b/plugins/mk-project/plugin.c
index f4db9b4..3591173 100644
--- a/plugins/mk-project/plugin.c
+++ b/plugins/mk-project/plugin.c
@@ -56,7 +56,7 @@ iproject_backend_new_project (IAnjutaProjectBackend* backend, GError** err)
 {
 	IAnjutaProject *project;
 	DEBUG_PRINT("create new mkp project");	
-	project = (IAnjutaProject *)(g_object_new (MKP_TYPE_PROJECT, NULL));
+	project = (IAnjutaProject *)(g_object_new (MKP_TYPE_PROJECT, NULL));	
 		
 	return project;
 }
@@ -65,7 +65,7 @@ static gint
 iproject_backend_probe (IAnjutaProjectBackend* backend, GFile *directory, GError** err)
 {
 	DEBUG_PRINT("probe mkp project");
-
+	
 	return mkp_project_probe (directory, err);
 }
 
@@ -104,7 +104,7 @@ finalize (GObject *obj)
 }
 
 static void
-mkp_plugin_class_init (GObjectClass *klass) 
+mkp_plugin_class_init (GObjectClass *klass)
 {
 	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
 
diff --git a/plugins/project-manager/gbf-project-model.c b/plugins/project-manager/gbf-project-model.c
index 6b6569a..46679c1 100644
--- a/plugins/project-manager/gbf-project-model.c
+++ b/plugins/project-manager/gbf-project-model.c
@@ -328,7 +328,8 @@ add_source (GbfProjectModel    	      *model,
 {
 	GtkTreeIter iter;
 	GbfTreeData *data;
-	
+
+	g_message ("add source");
 	if ((!source) || (anjuta_project_node_get_type (source) != ANJUTA_PROJECT_SOURCE))
 		return;
 	
@@ -555,6 +556,10 @@ add_target_group (GbfProjectModel 	*model,
 	/* ... and targets */
 	for (node = anjuta_project_node_first_child (group); node; node = anjuta_project_node_next_sibling (node))
 		add_target (model, node, &iter);
+	
+	/* ... and sources */
+	for (node = anjuta_project_node_first_child (group); node; node = anjuta_project_node_next_sibling (node))
+		add_source (model, node, &iter);
 }
 
 static void
@@ -565,6 +570,7 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
 	GList *node;
 	GList *groups;
 	GList *targets;
+	GList *sources;
 
 	if ((!group) || (anjuta_project_node_get_type (group) != ANJUTA_PROJECT_GROUP))
 		return;
@@ -574,6 +580,8 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
 	/* update group data. nothing to do here */
 	groups = gbf_project_util_all_child (group, ANJUTA_PROJECT_GROUP);
 	targets = gbf_project_util_all_child (group, ANJUTA_PROJECT_TARGET);
+	sources = gbf_project_util_all_child (group, ANJUTA_PROJECT_SOURCE);
+	g_message ("update group %p", sources);
 
 	/* walk the tree group */
 	/* group can be NULL, but we iterate anyway to remove any
@@ -626,8 +634,14 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
 					}
 					gtk_tree_path_free (shortcut);
 				}
+			} else if (data->type == GBF_TREE_NODE_SOURCE) {
+				if ((data->id) && (node = g_list_find (sources, data->id))) {
+					sources = g_list_delete_link (sources, node);
+				} else {
+					remove_child = TRUE;
+				}
 			}
-			
+		
 			gbf_tree_data_free (data);
 			if (remove_child)
 				valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
@@ -637,12 +651,16 @@ update_group (GbfProjectModel *model, AnjutaProjectGroup *group, GtkTreeIter *it
 	}
 
 	if (group) {
-		/* add the remaining targets and groups */
+		/* add the remaining sources, targets and groups */
 		for (node = groups; node; node = node->next)
 			add_target_group (model, node->data, iter);
 		
 		for (node = targets; node; node = node->next)
 			add_target (model, node->data, iter);
+
+		g_message ("add sources %p", sources);
+		for (node = sources; node; node = g_list_next (node))
+			add_source (model, node->data, iter);
 	}
 }
 
diff --git a/plugins/project-manager/gbf-project-util.c b/plugins/project-manager/gbf-project-util.c
index 651b68a..f4a1e57 100644
--- a/plugins/project-manager/gbf-project-util.c
+++ b/plugins/project-manager/gbf-project-util.c
@@ -824,7 +824,27 @@ gbf_project_util_node_all (AnjutaProjectNode *parent, AnjutaProjectNodeType type
     {
         if (anjuta_project_node_get_type (node) == type)
         {
-            list = g_list_prepend (list, node);
+            gchar *uri = NULL;
+            
+	    switch (anjuta_project_node_get_type (node))
+            {
+            case ANJUTA_PROJECT_GROUP:
+                uri = g_file_get_uri (anjuta_project_group_get_directory (node));
+                break;
+            case ANJUTA_PROJECT_TARGET:
+                uri = anjuta_project_target_get_name (node);
+                break;
+            case ANJUTA_PROJECT_SOURCE:
+                uri = g_file_get_uri (anjuta_project_source_get_file (node));
+                break;
+            default:
+		break;
+            }
+
+            if (uri != NULL)
+            {
+                list = g_list_prepend (list, uri);
+            }
         }
         if (anjuta_project_node_get_type (node) == ANJUTA_PROJECT_GROUP)
         {
diff --git a/plugins/project-manager/gbf-project-view.c b/plugins/project-manager/gbf-project-view.c
index 3e487ca..462cd1e 100644
--- a/plugins/project-manager/gbf-project-view.c
+++ b/plugins/project-manager/gbf-project-view.c
@@ -174,7 +174,7 @@ set_pixbuf (GtkTreeViewColumn *tree_column,
 	g_return_if_fail (data != NULL);
 	
 	switch (data->type) {
-		case GBF_TREE_NODE_TARGET_SOURCE:
+		case GBF_TREE_NODE_SOURCE:
 		{
 			pixbuf = get_icon (data->uri);
 			break;
diff --git a/plugins/project-manager/gbf-tree-data.c b/plugins/project-manager/gbf-tree-data.c
index c1f916a..f04c0b1 100644
--- a/plugins/project-manager/gbf-tree-data.c
+++ b/plugins/project-manager/gbf-tree-data.c
@@ -98,7 +98,7 @@ gbf_tree_data_new_source (IAnjutaProject *project, AnjutaProjectSource *source)
 	GbfTreeData *node = g_new0 (GbfTreeData, 1);
 	GFileInfo *ginfo;
 	
-	node->type = GBF_TREE_NODE_TARGET_SOURCE;
+	node->type = GBF_TREE_NODE_SOURCE;
 	node->id = source;
 	
 	node->uri = g_file_get_uri (anjuta_project_source_get_file (source));
diff --git a/plugins/project-manager/gbf-tree-data.h b/plugins/project-manager/gbf-tree-data.h
index afbb09f..c34c3b9 100644
--- a/plugins/project-manager/gbf-tree-data.h
+++ b/plugins/project-manager/gbf-tree-data.h
@@ -38,7 +38,7 @@ typedef enum {
 	GBF_TREE_NODE_STRING,
 	GBF_TREE_NODE_GROUP,
 	GBF_TREE_NODE_TARGET,
-	GBF_TREE_NODE_TARGET_SOURCE,
+	GBF_TREE_NODE_SOURCE,
 } GbfTreeNodeType;
 
 struct _GbfTreeData
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index 8360ec5..171e6ac 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -666,7 +666,7 @@ confirm_removal (ProjectManagerPlugin *plugin, GbfTreeData *data)
 			question = _("Are you sure you want to remove the following target from the project?\n\n");
 			mesg = _("Target: %s");
 			break;
-		case GBF_TREE_NODE_TARGET_SOURCE:
+		case GBF_TREE_NODE_SOURCE:
 			question = _("Are you sure you want to remove the following source file from the project?\n\n");
 			mesg = _("Source: %s\n\nThe source file will not be deleted from the file system.");
 			break;
@@ -688,7 +688,7 @@ on_popup_remove (GtkAction *action, ProjectManagerPlugin *plugin)
 	GbfTreeData *data;
 	
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   GBF_TREE_NODE_TARGET_SOURCE);
+										   GBF_TREE_NODE_SOURCE);
 	if (data == NULL)
 	{
 		data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
@@ -958,8 +958,8 @@ on_treeview_selection_changed (GtkTreeSelection *sel,
 	if (plugin->project)
 		caps = ianjuta_project_get_capabilities (plugin->project, NULL);
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   GBF_TREE_NODE_TARGET_SOURCE);
-	if (data && data->type == GBF_TREE_NODE_TARGET_SOURCE)
+										   GBF_TREE_NODE_SOURCE);
+	if (data && data->type == GBF_TREE_NODE_SOURCE)
 	{
 		if (caps & IANJUTA_PROJECT_CAN_ADD_SOURCE)
 		{
@@ -2062,8 +2062,8 @@ iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
 	g_return_val_if_fail (IANJUTA_IS_PROJECT (plugin->project), NULL);
 	
 	data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-										   GBF_TREE_NODE_TARGET_SOURCE);
-	if (data && data->type == GBF_TREE_NODE_TARGET_SOURCE)
+										   GBF_TREE_NODE_SOURCE);
+	if (data && data->type == GBF_TREE_NODE_SOURCE)
 	{
 		uri = g_strdup (data->uri);
 		gbf_tree_data_free (data);
@@ -2119,8 +2119,8 @@ iproject_manager_get_selected_id (IAnjutaProjectManager *project_manager,
 		element_type == ANJUTA_PROJECT_SOURCE)
 	{
 		data = gbf_project_view_find_selected (GBF_PROJECT_VIEW (plugin->view),
-		                                       GBF_TREE_NODE_TARGET_SOURCE);
-		if (data && data->type == GBF_TREE_NODE_TARGET_SOURCE)
+		                                       GBF_TREE_NODE_SOURCE);
+		if (data && data->type == GBF_TREE_NODE_SOURCE)
 			node = data->id;
 
 		if (data)



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