[anjuta/newproject] Open a directory as a project
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta/newproject] Open a directory as a project
- Date: Mon, 21 Dec 2009 10:26:56 +0000 (UTC)
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]