[anjuta] Add a new project backend to open a directory as a project
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta] Add a new project backend to open a directory as a project
- Date: Sat, 2 Jan 2010 15:06:48 +0000 (UTC)
commit 4aebbe5819471519822e7b25fd7276fecc2837ba
Author: Sébastien Granjoux <seb sfo free fr>
Date: Sat Jan 2 16:03:48 2010 +0100
Add a new project backend to open a directory as a project
configure.in | 2 +
plugins/Makefile.am | 1 +
plugins/dir-project/Makefile.am | 58 ++
plugins/dir-project/dir-project-plugin-48.png | Bin 0 -> 866 bytes
plugins/dir-project/dir-project.c | 986 ++++++++++++++++++++
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/dir-project/sources.list | 19 +
plugins/project-import/plugin.c | 60 +-
plugins/project-manager/plugin.c | 59 +-
plugins/project-wizard/templates/Makefile.am | 2 +-
.../project-wizard/templates/directory/Makefile.am | 8 +
.../templates/directory/project.anjuta | 51 +
.../project-wizard/templates/mkfile/project.anjuta | 11 +-
.../templates/terminal/project.anjuta | 9 +-
po/POTFILES.in | 1 +
18 files changed, 1527 insertions(+), 46 deletions(-)
---
diff --git a/configure.in b/configure.in
index 9961c5a..2eade99 100644
--- a/configure.in
+++ b/configure.in
@@ -847,7 +847,9 @@ plugins/project-wizard/templates/gnome-applet/po/Makefile
plugins/project-wizard/templates/library/Makefile
plugins/project-wizard/templates/library/src/Makefile
plugins/project-wizard/templates/library/po/Makefile
+plugins/project-wizard/templates/directory/Makefile
plugins/project-wizard/templates/m4/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 5395330..329fd2b 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -31,6 +31,7 @@ SUBDIRS = . \
run-program \
gbf-am \
gbf-mkfile \
+ dir-project \
starter \
js-debugger \
language-support-js
diff --git a/plugins/dir-project/Makefile.am b/plugins/dir-project/Makefile.am
new file mode 100644
index 0000000..bd35cb6
--- /dev/null
+++ b/plugins/dir-project/Makefile.am
@@ -0,0 +1,58 @@
+# Plugin UI file
+plugin_uidir = $(anjuta_ui_dir)
+plugin_ui_DATA =
+
+# Plugin glade file
+plugin_gladedir = $(anjuta_glade_dir)
+plugin_glade_DATA =
+
+# Plugin data file
+plugin_datadir = $(anjuta_data_dir)
+plugin_data_DATA = sources.list
+
+# 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) \
+ $(plugin_data_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..60c6f3b
--- /dev/null
+++ b/plugins/dir-project/dir-project.c
@@ -0,0 +1,986 @@
+/* -*- 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>
+
+#define SOURCES_FILE PACKAGE_DATA_DIR"/sources.list"
+
+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;
+
+ /* List of source files pattern */
+ GList *sources;
+};
+
+/* 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;
+};
+
+/* A file or directory name part of a path */
+typedef struct _DirMatchString DirMatchString;
+
+struct _DirMatchString
+{
+ gchar *string;
+ gchar *reverse;
+ guint length;
+ GFile *file;
+ gboolean parent;
+};
+
+
+/* A pattern used to match a part of a path */
+typedef struct _DirPattern DirPattern;
+
+struct _DirPattern
+{
+ GList *names;
+ gboolean match;
+ gboolean local;
+ gboolean directory;
+};
+
+/* A list of pattern found in one file */
+typedef struct _DirPatternList DirPatternList;
+
+struct _DirPatternList
+{
+ GList *pattern;
+ GFile *directory;
+};
+
+/* ----- 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 */
+ anjuta_project_node_all_foreach (g_node,
+ foreach_node_destroy, project);
+ }
+}
+
+/* File name objects
+ *---------------------------------------------------------------------------*/
+
+static DirMatchString*
+dir_match_string_new (gchar *string)
+{
+ DirMatchString *str = NULL;
+
+ str = g_slice_new0(DirMatchString);
+ str->length = strlen (string);
+ str->string = string;
+ str->reverse = g_strreverse(g_strdup (string));
+
+ return str;
+}
+
+static void
+dir_match_string_free (DirMatchString *str)
+{
+ g_free (str->string);
+ g_free (str->reverse);
+ if (str->file) g_object_unref (str->file);
+ g_slice_free (DirMatchString, str);
+}
+
+/* Cut a filename is part representing one directory or file name. By example
+ * /home/user/project/foo will be generate a list containing:
+ * foo, project, user, home */
+static GList*
+dir_cut_filename (GFile *file)
+{
+ GList *name_list = NULL;
+
+ g_object_ref (file);
+ do
+ {
+ DirMatchString *str;
+ gchar *name = g_file_get_basename (file);
+
+ if (strcmp(name, G_DIR_SEPARATOR_S) == 0)
+ {
+ g_free (name);
+ g_object_unref (file);
+ break;
+ }
+
+ str = dir_match_string_new (name);
+ str->file = file;
+
+ name_list = g_list_prepend (name_list, str);
+
+ file = g_file_get_parent (file);
+ }
+ while (file != NULL);
+
+ name_list = g_list_reverse (name_list);
+
+ return name_list;
+}
+
+static void
+dir_filename_free (GList *name)
+{
+ g_list_foreach (name, (GFunc)dir_match_string_free, NULL);
+ g_list_free (name);
+}
+
+/* Pattern objects
+ *---------------------------------------------------------------------------*/
+
+/* Create a new pattern matching a directory of a file name in a path */
+
+static DirPattern*
+dir_pattern_new (const gchar *pattern, gboolean reverse)
+{
+ DirPattern *pat = NULL;
+ GString *str = g_string_new (NULL);
+ const char *ptr = pattern;
+
+ pat = g_slice_new0(DirPattern);
+ /* Check if it is a reverse pattern */
+ if (*ptr == '!')
+ {
+ pat->match = reverse ? TRUE : FALSE;
+ ptr++;
+ }
+ else
+ {
+ pat->match = reverse ? FALSE : TRUE;
+ }
+ /* Check if the pattern is local */
+ if (*ptr == '/')
+ {
+ pat->local = TRUE;
+ ptr++;
+ }
+ else
+ {
+ pat->local = FALSE;
+ }
+ pat->names = NULL;
+
+ while (*ptr != '\0')
+ {
+ const gchar *next = strchr (ptr, '/');
+
+ if (next == NULL)
+ {
+ pat->names = g_list_prepend (pat->names, g_pattern_spec_new (ptr));
+ break;
+ }
+ else
+ {
+ if (next != ptr)
+ {
+ g_string_overwrite_len (str, 0, ptr, next - ptr);
+ pat->names = g_list_prepend (pat->names, g_pattern_spec_new (str->str));
+ }
+ ptr = next + 1;
+ }
+ }
+ g_string_free (str, TRUE);
+
+ /* Check if the pattern has to match a directory */
+ pat->directory = (ptr != pattern) && (*(ptr-1) == '/');
+
+ return pat;
+}
+
+static void
+dir_pattern_free (DirPattern *pat)
+{
+ g_list_foreach (pat->names, (GFunc)g_pattern_spec_free, NULL);
+ g_list_free (pat->names);
+
+ g_slice_free (DirPattern, pat);
+}
+
+/* Read a file containing pattern, the syntax is similar to .gitignore file.
+ *
+ * It is not a regular expression, only * and ? are used as joker.
+ * If the name end with / it will match only a directory.
+ * If the name starts with / it must be relative to the project directory, so
+ * by example /.git/ will match only a directory named .git in the project
+ * directory, while CVS/ will match a directory named CVS anywhere in the
+ * project.
+ * If the name starts with ! the meaning is reversed. In a file containing
+ * matching file, if a pattern starting ! matches, it means that the file has
+ * to be removed from the matching list.
+ * All pattern are read in order, so it is possible to match a group of files
+ * and add pattern afterward to remove some of these files.
+ * A name starting with # is a comment.
+ * All spaces at the beginning of a name are ignored.
+ */
+static GList*
+dir_push_pattern_list (GList *stack, GFile *dir, GFile *file, gboolean ignore, GError **error)
+{
+ char *content;
+ char *ptr;
+ DirPatternList *list = NULL;
+
+
+ if (!g_file_load_contents (file, NULL, &content, NULL, NULL, error))
+ {
+ return stack;
+ }
+
+ list = g_slice_new0(DirPatternList);
+ list->pattern = NULL;
+ list->directory = dir;
+
+ for (ptr = content; *ptr != '\0';)
+ {
+ gchar *next;
+
+ next = strchr (ptr, '\n');
+ if (next != NULL) *next = '\0';
+
+ /* Discard space at the beginning */
+ while (isspace (*ptr)) ptr++;
+
+ if ((*ptr != '#') && (ptr != next))
+ {
+ /* Create pattern */
+ DirPattern *pat = NULL;
+
+ if (next != NULL) *next = '\0';
+ pat = dir_pattern_new (ptr, ignore);
+ list->pattern = g_list_prepend (list->pattern, pat);
+ }
+
+ if (next == NULL) break;
+ ptr = next + 1;
+ }
+ g_free (content);
+
+ list->pattern = g_list_reverse (list->pattern);
+
+ return g_list_prepend (stack, list);
+}
+
+static GList *
+dir_pop_pattern_list (GList *stack)
+{
+ DirPatternList *top = (DirPatternList *)stack->data;
+
+ stack = g_list_remove_link (stack, stack);
+
+ g_list_foreach (top->pattern, (GFunc)dir_pattern_free, NULL);
+ g_list_free (top->pattern);
+ g_object_unref (top->directory);
+ g_slice_free (DirPatternList, top);
+
+ return stack;
+}
+
+static gboolean
+dir_pattern_stack_is_match (GList *stack, GFile *file)
+{
+ gboolean match;
+ GList *list;
+ GList *name_list;
+ gboolean directory;
+
+ /* Create name list from file */
+ name_list = dir_cut_filename (file);
+
+ directory = g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) == G_FILE_TYPE_DIRECTORY;
+ /* Include directories by default */
+ match = directory;
+
+ /* Check all valid patterns */
+ for (list = g_list_last (stack); list != NULL; list = g_list_previous (list))
+ {
+ DirPatternList *pat_list = (DirPatternList *)list->data;
+ GList *node;
+
+ /* Mark parent level */
+ for (node = g_list_first (name_list); node != NULL; node = g_list_next (node))
+ {
+ DirMatchString *str = (DirMatchString *)node->data;
+
+ str->parent = g_file_equal (pat_list->directory, str->file);
+ }
+
+ for (node = g_list_first (pat_list->pattern); node != NULL; node = g_list_next (node))
+ {
+ DirPattern *pat = (DirPattern *)node->data;
+ GList *pat_part;
+ GList *name_part;
+ gboolean match_part;
+
+ if (pat->directory && !directory)
+ continue;
+
+ name_part = g_list_first (name_list);
+ for (pat_part = g_list_first (pat->names); pat_part != NULL; pat_part = g_list_next (pat_part))
+ {
+ DirMatchString *part = (DirMatchString *)name_part->data;
+ match_part = g_pattern_match ((GPatternSpec *)pat_part->data, part->length, part->string, part->reverse);
+
+ if (!match_part) break;
+ name_part = g_list_next (name_part);
+ }
+
+ /* Local match are relative to parent directory only */
+ if (match_part && pat->local && (!((DirMatchString *)name_part->data)->parent)) match_part = FALSE;
+
+ if (match_part) match = pat->match;
+ }
+ }
+
+ dir_filename_free (name_list);
+
+ return match;
+}
+
+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);
+
+ /* Check if file is a source */
+ if (!dir_pattern_stack_is_match (project->sources, file)) continue;
+
+ if (g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY)
+ {
+ /* Create a group for 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
+ {
+ /* Create a source for files */
+ 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;
+ GFile *source_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);
+
+ /* 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);
+ project->root_node = group;
+
+ /* Load source pattern */
+ source_file = g_file_new_for_path (SOURCES_FILE);
+ project->sources = dir_push_pattern_list (NULL, g_object_ref (root_file), source_file, FALSE, NULL);
+ g_object_unref (source_file);
+
+ 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;
+
+ /* sources patterns */
+ while (project->sources)
+ {
+ project->sources = dir_pop_pattern_list (project->sources);
+ }
+}
+
+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;
+
+ project->sources = 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..36be02d
--- /dev/null
+++ b/plugins/dir-project/dir-project.plugin.in
@@ -0,0 +1,11 @@
+[Anjuta Plugin]
+_Name=Directory backend
+_Description=Directory project backend, get only source files, use it when other backend fails
+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/dir-project/sources.list b/plugins/dir-project/sources.list
new file mode 100644
index 0000000..50371cf
--- /dev/null
+++ b/plugins/dir-project/sources.list
@@ -0,0 +1,19 @@
+*.c
+*.h
+*.C
+*.cpp
+*.hpp
+*.cxx
+*.c++
+*.cc
+*.java
+*.py
+*.pl
+*.rb
+*.y
+*.l
+*.in
+*.in.in
+*.am
+!CVS/
+!.*/
diff --git a/plugins/project-import/plugin.c b/plugins/project-import/plugin.c
index 44d9c21..1d85652 100644
--- a/plugins/project-import/plugin.c
+++ b/plugins/project-import/plugin.c
@@ -27,7 +27,6 @@
#include <libanjuta/interfaces/ianjuta-file-loader.h>
#include <libanjuta/interfaces/ianjuta-project-backend.h>
#include <libanjuta/interfaces/ianjuta-vcs.h>
-#include <libanjuta/gbf-project.h>
#include <libanjuta/anjuta-async-notify.h>
#include "plugin.h"
@@ -37,6 +36,7 @@
#define AM_PROJECT_FILE PACKAGE_DATA_DIR"/project/terminal/project.anjuta"
#define MKFILE_PROJECT_FILE PACKAGE_DATA_DIR"/project/mkfile/project.anjuta"
+#define DIRECTORY_PROJECT_FILE PACKAGE_DATA_DIR"/project/directory/project.anjuta"
static gpointer parent_class;
@@ -54,6 +54,8 @@ project_import_generate_file (AnjutaProjectImportPlugin* import_plugin, ProjectI
source_file = g_file_new_for_path (AM_PROJECT_FILE);
else if (!strcmp (import_plugin->backend_id, "make"))
source_file = g_file_new_for_path (MKFILE_PROJECT_FILE);
+ else if (!strcmp (import_plugin->backend_id, "directory"))
+ source_file = g_file_new_for_path (DIRECTORY_PROJECT_FILE);
else
{
/* We shouldn't get here, unless someone has upgraded their GBF */
@@ -153,47 +155,61 @@ project_import_import_project (AnjutaProjectImportPlugin *import_plugin, Project
GList *desc;
AnjutaPluginDescription *backend;
gchar *name, *project_file_name;
-
+
+ /* Search for all valid project backend */
plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN(import_plugin)->shell, NULL);
descs = anjuta_plugin_manager_query (plugin_manager,
"Anjuta Plugin",
"Interfaces",
"IAnjutaProjectBackend",
NULL);
- for (desc = g_list_first (descs); desc != NULL; desc = g_list_next (desc)) {
+ for (desc = g_list_first (descs); desc != NULL;) {
IAnjutaProjectBackend *plugin;
gchar *location = NULL;
- GbfProject* proj;
+ GList *next;
backend = (AnjutaPluginDescription *)desc->data;
anjuta_plugin_description_get_string (backend, "Anjuta Plugin", "Location", &location);
plugin = (IAnjutaProjectBackend *)anjuta_plugin_manager_get_plugin_by_id (plugin_manager, location);
g_free (location);
- /* Probe the backend to find out if the project directory is OK */
- /* If probe() returns TRUE then we have a valid backend */
+ next = g_list_next (desc);
- proj= ianjuta_project_backend_new_project (plugin, NULL);
- if (proj)
+ /* Probe the project directory to find if the backend can handle it */
+ if (ianjuta_project_backend_probe (plugin, source_dir, NULL) <= 0)
{
- gchar *path;
-
- path = g_file_get_path (source_dir);
- if (gbf_project_probe (proj, path, NULL))
- {
- /* This is a valid backend for this root directory */
- /* FIXME: Possibility of more than one valid backend? */
- break;
- }
- g_object_unref (proj);
- g_free (path);
+ /* Remove invalid backend */
+ descs = g_list_delete_link (descs, desc);
}
- plugin = NULL;
+
+ desc = next;
+ }
+
+ if (descs == NULL)
+ {
backend = NULL;
}
+ else if (g_list_next (descs) == NULL)
+ {
+ backend = (AnjutaPluginDescription *)descs->data;
+ }
+ else
+ {
+ /* Several backend are possible, ask the user to select one */
+ gchar *path = project_import_dialog_get_name (import_dialog);
+ gchar* message = g_strdup_printf (_("Please select a project backend to open %s."), path);
+
+ g_free (path);
+
+ backend = anjuta_plugin_manager_select (plugin_manager,
+ _("Open With"),
+ message,
+ descs);
+ g_free (message);
+ }
g_list_free (descs);
-
- if (!backend)
+
+ if (backend == NULL)
{
gchar *path = project_import_dialog_get_name (import_dialog);
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index de5b764..408a08a 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1159,9 +1159,9 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
gchar *basename;
const gchar *root_uri;
GError *error = NULL;
- GList *descs = NULL;
GList *desc;
IAnjutaProjectBackend *backend;
+ gint found = 0;
root_uri = pm_plugin->project_root_uri;
@@ -1175,28 +1175,47 @@ project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
DEBUG_PRINT ("loading gbf backendâ?¦\n");
plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN(pm_plugin)->shell, NULL);
- descs = anjuta_plugin_manager_query (plugin_manager,
- "Anjuta Plugin",
- "Interfaces",
- "IAnjutaProjectBackend",
- NULL);
- for (desc = g_list_first (descs); desc != NULL; desc = g_list_next (desc)) {
- AnjutaPluginDescription *backend_desc;
- gchar *location = NULL;
-
- backend_desc = (AnjutaPluginDescription *)desc->data;
- anjuta_plugin_description_get_string (backend_desc, "Anjuta Plugin", "Location", &location);
- backend = (IAnjutaProjectBackend *)anjuta_plugin_manager_get_plugin_by_id (plugin_manager, location);
- g_free (location);
- if (ianjuta_project_backend_probe (backend, dirfile, NULL))
- {
- /* Backend found */
- break;
- }
+ if (!anjuta_plugin_manager_is_active_plugin (plugin_manager, "IAnjutaProjectBackend"))
+ {
+ GList *descs = NULL;
+
+ descs = anjuta_plugin_manager_query (plugin_manager,
+ "Anjuta Plugin",
+ "Interfaces",
+ "IAnjutaProjectBackend",
+ NULL);
backend = NULL;
+ for (desc = g_list_first (descs); desc != NULL; desc = g_list_next (desc)) {
+ AnjutaPluginDescription *backend_desc;
+ gchar *location = NULL;
+ IAnjutaProjectBackend *plugin;
+ gint backend_val;
+
+ backend_desc = (AnjutaPluginDescription *)desc->data;
+ anjuta_plugin_description_get_string (backend_desc, "Anjuta Plugin", "Location", &location);
+ plugin = (IAnjutaProjectBackend *)anjuta_plugin_manager_get_plugin_by_id (plugin_manager, location);
+ g_message ("search plugin %s", location);
+ g_free (location);
+
+ backend_val = ianjuta_project_backend_probe (plugin, dirfile, NULL);
+ if (backend_val > found)
+ {
+ /* Backend found */;
+ backend = plugin;
+ found = backend_val;
+ }
+ }
+ g_list_free (descs);
+ }
+ else
+ {
+ /* A backend is already loaded, use it */
+ backend = IANJUTA_PROJECT_BACKEND (anjuta_shell_get_object (ANJUTA_PLUGIN (pm_plugin)->shell,
+ "IAnjutaProjectBackend", NULL));
+
+ g_object_ref (backend);
}
- g_list_free (descs);
if (!backend)
{
diff --git a/plugins/project-wizard/templates/Makefile.am b/plugins/project-wizard/templates/Makefile.am
index 094cd50..fddc392 100644
--- a/plugins/project-wizard/templates/Makefile.am
+++ b/plugins/project-wizard/templates/Makefile.am
@@ -1,7 +1,7 @@
SUBDIRS = minimal terminal cpp gtk anjuta-plugin \
gtkmm wxwin xlib xlib-dock gcj java gnome-applet\
- python mkfile sdl library licenses m4 js_minimal
+ python mkfile sdl library directory licenses m4 js_minimal
wizard_filesdir = $(anjuta_data_dir)/project
wizard_files_DATA = \
diff --git a/plugins/project-wizard/templates/directory/Makefile.am b/plugins/project-wizard/templates/directory/Makefile.am
new file mode 100644
index 0000000..ffb141a
--- /dev/null
+++ b/plugins/project-wizard/templates/directory/Makefile.am
@@ -0,0 +1,8 @@
+
+wizard_filesdir = $(anjuta_data_dir)/project/directory
+wizard_files_DATA = \
+ project.anjuta
+
+EXTRA_DIST = $(wizard_files_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/project-wizard/templates/directory/project.anjuta b/plugins/project-wizard/templates/directory/project.anjuta
new file mode 100644
index 0000000..dd12c27
--- /dev/null
+++ b/plugins/project-wizard/templates/directory/project.anjuta
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<anjuta>
+ <plugin name="GBF Project Manager"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaProjectManager"/>
+ </plugin>
+ <plugin name="Directory Project Backend"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaProjectBackend"/>
+ <require group="Project"
+ attribute="Supported-Project-Types"
+ value="directory"/>
+ </plugin>
+ <plugin name="Symbol Browser"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaSymbolManager"/>
+ </plugin>
+ <plugin name="Make Build System"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaBuildable"/>
+ <require group="Build"
+ attribute="Supported-Build-Types"
+ value="make"/>
+ </plugin>
+ <plugin name="Task Manager"
+ url="http://anjuta.org/plugins/"
+ mandatory="no">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaTodo"/>
+ </plugin>
+ <plugin name="Debug Manager"
+ url="http://anjuta.org/plugins/"
+ mandatory="no">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaDebugManager"/>
+ </plugin>
+</anjuta>
diff --git a/plugins/project-wizard/templates/mkfile/project.anjuta b/plugins/project-wizard/templates/mkfile/project.anjuta
index 471e6e1..390fe09 100644
--- a/plugins/project-wizard/templates/mkfile/project.anjuta
+++ b/plugins/project-wizard/templates/mkfile/project.anjuta
@@ -6,9 +6,16 @@
<require group="Anjuta Plugin"
attribute="Interfaces"
value="IAnjutaProjectManager"/>
+ </plugin>
+ <plugin name="Makefile Project Backend"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaProjectBackend"/>
<require group="Project"
- attribute="Supported-Project-Types"
- value="make"/>
+ attribute="Supported-Project-Types"
+ value="make"/>
</plugin>
<plugin name="Symbol Browser"
url="http://anjuta.org/plugins/"
diff --git a/plugins/project-wizard/templates/terminal/project.anjuta b/plugins/project-wizard/templates/terminal/project.anjuta
index 2389e4c..68c60e6 100644
--- a/plugins/project-wizard/templates/terminal/project.anjuta
+++ b/plugins/project-wizard/templates/terminal/project.anjuta
@@ -1,11 +1,18 @@
<?xml version="1.0"?>
<anjuta>
- <plugin name="GBF Project Manager"
+ <plugin name="GBF Project Manager"
url="http://anjuta.org/plugins/"
mandatory="yes">
<require group="Anjuta Plugin"
attribute="Interfaces"
value="IAnjutaProjectManager"/>
+ </plugin>
+ <plugin name="AutoTools Project Backend"
+ url="http://anjuta.org/plugins/"
+ mandatory="yes">
+ <require group="Anjuta Plugin"
+ attribute="Interfaces"
+ value="IAnjutaProjectBackend"/>
<require group="Project"
attribute="Supported-Project-Types"
value="automake"/>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 775fffd..99b2b22 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -90,6 +90,7 @@ plugins/gbf-am/gbf-am-properties.c
plugins/gbf-mkfile/gbf-mkfile-config.c
plugins/gbf-mkfile/gbf-mkfile-project.c
plugins/gbf-mkfile/gbf-mkfile-properties.c
+plugins/dir-project/dir-project.c
plugins/gdb/debugger.c
plugins/gdb/plugin.c
plugins/gdb/utilities.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]