anjuta r4915 - in trunk: . plugins/git plugins/project-import plugins/subversion



Author: jhs
Date: Thu Apr  2 08:41:03 2009
New Revision: 4915
URL: http://svn.gnome.org/viewvc/anjuta?rev=4915&view=rev

Log:
2009-04-02  Carl-Anton Ingmarsson <ca ingmarsson gmail com>

	* plugins/git/Makefile.am:
	* plugins/git/git-vcs-interface.c (git_ivcs_checkout):
	* plugins/git/git-vcs-interface.h:
	* plugins/subversion/subversion-vcs-interface.c
	(subversion_ivcs_checkout):
	Implement checkout option for git and change it for svn so that it
	works for project-import

	* plugins/project-import/Makefile.am:
	* plugins/project-import/plugin.c (project_import_generate_file),
	(project_import_import_project), (checkout_finished),
	(project_import_checkout_project), (import_dialog_response),
	(finalize), (iwizard_activate), (ifile_open):
	* plugins/project-import/plugin.h:
	* plugins/project-import/project-import-dialog.c
	(vcs_entry_changed), (name_entry_changed), (folder_radio_toggled),
	(vcs_radio_toggled), (project_import_dialog_get_vcs_id),
	(project_import_dialog_get_vcs_uri),
	(project_import_dialog_get_dest_dir),
	(project_import_dialog_get_source_dir),
	(project_import_dialog_get_name), (project_import_dialog_new),
	(project_import_dialog_init), (project_import_dialog_finalize),
	(project_import_dialog_class_init):
	* plugins/project-import/project-import-dialog.h:
	* plugins/project-import/project-import.c:
	* plugins/project-import/project-import.glade:
	* plugins/project-import/project-import.h:
	Remove project import wizard and replace with simpler dialog
	that allows to import directly from a version control system.

Added:
   trunk/plugins/project-import/project-import-dialog.c
   trunk/plugins/project-import/project-import-dialog.h
   trunk/plugins/project-import/project-import.glade
Removed:
   trunk/plugins/project-import/project-import.c
   trunk/plugins/project-import/project-import.h
Modified:
   trunk/ChangeLog
   trunk/plugins/git/Makefile.am
   trunk/plugins/git/git-vcs-interface.c
   trunk/plugins/git/git-vcs-interface.h
   trunk/plugins/project-import/Makefile.am
   trunk/plugins/project-import/plugin.c
   trunk/plugins/project-import/plugin.h
   trunk/plugins/subversion/subversion-vcs-interface.c

Modified: trunk/plugins/git/Makefile.am
==============================================================================
--- trunk/plugins/git/Makefile.am	(original)
+++ trunk/plugins/git/Makefile.am	Thu Apr  2 08:41:03 2009
@@ -179,7 +179,9 @@
 	git-cat-file-menu.c \
 	git-cat-file-menu.h \
 	git-vcs-interface.c \
-	git-vcs-interface.h
+	git-vcs-interface.h \
+	git-clone-command.h \
+	git-clone-command.c
 
 libanjuta_git_la_LDFLAGS = $(ANJUTA_PLUGIN_LDFLAGS)
 

Modified: trunk/plugins/git/git-vcs-interface.c
==============================================================================
--- trunk/plugins/git/git-vcs-interface.c	(original)
+++ trunk/plugins/git/git-vcs-interface.c	Thu Apr  2 08:41:03 2009
@@ -75,7 +75,44 @@
 				   GCancellable *cancel,
 				   AnjutaAsyncNotify *notify, GError **err)
 {
-	/* TODO */
+	GFile *parent;
+	gchar *path, *dir_name;
+	GitCloneCommand *clone_command;
+	Git *plugin;
+
+	parent = g_file_get_parent (dest);
+	path = g_file_get_path (parent);
+	dir_name = g_file_get_basename (dest);
+	
+	clone_command = git_clone_command_new (repository_location, path, dir_name);
+	plugin = ANJUTA_PLUGIN_GIT (obj);
+
+	g_object_unref (parent);
+	g_free (path);
+	g_free (dir_name);
+
+	git_create_message_view (plugin);
+
+	g_signal_connect (G_OBJECT (clone_command), "data-arrived",
+	                  G_CALLBACK (on_git_command_info_arrived),
+	                  plugin);
+
+	if (cancel)
+	{
+		g_signal_connect_swapped (G_OBJECT (cancel), "cancelled",
+		                          G_CALLBACK (anjuta_command_cancel),
+		                          clone_command);
+	}
+
+	if (notify)
+	{
+		g_signal_connect_swapped (G_OBJECT (clone_command), 
+		                          "command-finished",
+		                          G_CALLBACK (anjuta_async_notify_notify_finished),
+		                          notify);
+	}
+
+	anjuta_command_start (ANJUTA_COMMAND (clone_command));
 }
 
 static void

Modified: trunk/plugins/git/git-vcs-interface.h
==============================================================================
--- trunk/plugins/git/git-vcs-interface.h	(original)
+++ trunk/plugins/git/git-vcs-interface.h	Thu Apr  2 08:41:03 2009
@@ -32,6 +32,7 @@
 #include "git-diff-command.h"
 #include "git-status-command.h"
 #include "git-remove-command.h"
+#include "git-clone-command.h"
 
 #include "git-ui-utils.h"
 

Modified: trunk/plugins/project-import/Makefile.am
==============================================================================
--- trunk/plugins/project-import/Makefile.am	(original)
+++ trunk/plugins/project-import/Makefile.am	Thu Apr  2 08:41:03 2009
@@ -1,3 +1,6 @@
+# Plugin glade file
+wizard_gladedir = $(anjuta_glade_dir)
+wizard_glade_DATA = project-import.glade
 
 # Plugin pixmaps
 wizard_pixmapsdir = $(anjuta_image_dir)
@@ -32,10 +35,11 @@
 libanjuta_project_import_la_SOURCES= \
 	plugin.c \
 	plugin.h \
-	project-import.c \
-	project-import.h 
+	project-import-dialog.h \
+	project-import-dialog.c
 
 EXTRA_DIST = \
 	$(plugin_in_files) \
 	$(wizard_pixmaps_DATA) \
+	$(project_import_DATA) \
 	$(wizard_plugin_DATA)

Modified: trunk/plugins/project-import/plugin.c
==============================================================================
--- trunk/plugins/project-import/plugin.c	(original)
+++ trunk/plugins/project-import/plugin.c	Thu Apr  2 08:41:03 2009
@@ -24,15 +24,358 @@
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/interfaces/ianjuta-wizard.h>
 #include <libanjuta/interfaces/ianjuta-file.h>
+#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"
-#include "project-import.h"
+#include "project-import-dialog.h"
 
 #define ICON_FILE "anjuta-project-import-plugin-48.png"
 
+#define AM_PROJECT_FILE PACKAGE_DATA_DIR"/project/terminal/project.anjuta"
+#define MKFILE_PROJECT_FILE PACKAGE_DATA_DIR"/project/mkfile/project.anjuta"
+
 static gpointer parent_class;
 
 static gboolean
+project_import_generate_file (AnjutaProjectImportPlugin* import_plugin, ProjectImportDialog *import_dialog,
+                              GFile *project_file)
+{
+	/* Of course we could do some more intelligent stuff here
+	and check which plugins are really needed but for now we just
+	take a default project file. */
+	
+	GFile* source_file;
+	
+	if (!strcmp (import_plugin->backend_id, "automake"))
+		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
+	{
+		/* We shouldn't get here, unless someone has upgraded their GBF */
+		/* but not Anjuta.                                              */
+		
+		/* show the dialog since it may be hidden */
+		gtk_widget_show (GTK_WIDGET (import_dialog));
+
+		anjuta_util_dialog_error (GTK_WINDOW (import_dialog),
+		                          _("Generation of project file failed. Cannot "
+		                            "find an appropriate project template to "
+		                            "use. Please make sure your version of "
+		                            "Anjuta is up to date."));
+		return FALSE;
+	}
+	
+	GError* error = NULL;
+
+	if (!g_file_copy (source_file, project_file, 
+			G_FILE_COPY_NONE,
+			NULL,
+			NULL,
+			NULL,
+			&error))
+	{
+		if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_EXISTS)
+		{
+			gchar *prjfile = g_file_get_parse_name (project_file);
+			if (anjuta_util_dialog_boolean_question (GTK_WINDOW (ANJUTA_PLUGIN(import_plugin)->shell),
+					_("A file named \"%s\" already exists. "
+					  "Do you want to replace it?"), prjfile))
+			{
+				g_error_free (error);
+				error = NULL;
+				g_file_copy (source_file, project_file,
+						G_FILE_COPY_OVERWRITE,
+						NULL,
+						NULL,
+						NULL,
+						&error);
+			}
+			g_free (prjfile);
+		}
+	}
+
+	g_object_unref (source_file);
+
+	if (!error)
+	{
+		time_t ctime = time(NULL);
+		GFileInfo* file_info = g_file_info_new();
+		g_file_info_set_attribute_uint64(file_info, 
+				"time::modified",
+				ctime);
+		g_file_info_set_attribute_uint64(file_info, 
+				"time::created",
+				ctime);
+		g_file_info_set_attribute_uint64(file_info, 
+				"time::access",
+				ctime);
+		g_file_set_attributes_from_info (project_file, 
+				file_info,
+				G_FILE_QUERY_INFO_NONE,
+				NULL, NULL);
+
+		g_object_unref (G_OBJECT(file_info));;
+	}
+	else
+	{
+		gchar *prjfile;
+
+		prjfile = g_file_get_parse_name (project_file);
+		
+		/* show the dialog since it may be hidden */
+		gtk_widget_show (GTK_WIDGET (import_dialog));
+		
+		anjuta_util_dialog_error (GTK_WINDOW (import_dialog),
+				_("A file named \"%s\" cannot be written: %s.  "
+				  "Check if you have write access to the project directory."),
+				  prjfile, error->message);
+
+		g_free (prjfile);
+		
+		return FALSE;
+
+	}
+
+	return TRUE;
+}
+
+static gboolean
+project_import_import_project (AnjutaProjectImportPlugin *import_plugin, ProjectImportDialog *import_dialog,
+                               GFile *source_dir)
+{
+	AnjutaPluginManager *plugin_manager;
+	GList *descs = NULL;
+	GList *desc;
+	AnjutaPluginDescription *backend;
+	gchar *name, *project_file_name;
+	
+	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)) {
+		IAnjutaProjectBackend *plugin;
+		gchar *location = NULL;
+		GbfProject* proj;	
+		
+		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 */
+		
+		proj= ianjuta_project_backend_new_project (plugin, NULL);
+		if (proj)
+		{
+			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);
+		}
+		plugin = NULL;
+		backend = NULL;
+	}
+	g_list_free (descs);
+	
+	if (!backend)
+	{
+		gchar *path = project_import_dialog_get_name (import_dialog);
+
+		/* show the dialog since it may be hidden */
+		gtk_widget_show (GTK_WIDGET (import_dialog));
+
+		anjuta_util_dialog_error (GTK_WINDOW (import_dialog),
+		                          _("Could not find a valid project backend for the "
+		                            "directory given (%s). Please select a different "
+		                            "directory, or try upgrading to a newer version of "
+		                            "Anjuta."), path);
+
+		g_free (path);
+
+		return FALSE;
+	}
+
+	if (!anjuta_plugin_description_get_string (backend, "Project", "Supported-Project-Types", &import_plugin->backend_id))
+	{
+		import_plugin->backend_id = g_strdup ("unknown");
+	}
+
+	name = project_import_dialog_get_name (import_dialog);
+	project_file_name = g_strconcat (name, ".", "anjuta", NULL);
+	GFile *project_file = g_file_get_child (source_dir, project_file_name);
+
+	g_free (name);
+	g_free (project_file_name);
+	
+	IAnjutaFileLoader* loader;
+	
+	if (!project_import_generate_file (import_plugin, import_dialog, project_file))
+	{
+		g_object_unref (project_file);
+		return FALSE;
+	}
+	
+	loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (import_plugin)->shell,
+	                                     IAnjutaFileLoader, NULL);
+	if (!loader)
+	{
+		g_warning("No IAnjutaFileLoader interface! Cannot open project file!");
+		g_object_unref (project_file);
+		return TRUE;
+	}
+	
+	ianjuta_file_loader_load (loader, project_file, FALSE, NULL);
+
+	g_object_unref (project_file);
+	
+	return TRUE;
+}
+
+typedef struct
+{
+	AnjutaProjectImportPlugin *import_plugin;
+	ProjectImportDialog *import_dialog;
+	GFile *checkout_dir;
+} CheckoutData;
+
+static void
+checkout_finished (AnjutaAsyncNotify *async_notify, gpointer user_data)
+{
+	CheckoutData *ch = (CheckoutData *)user_data;
+	GError *err;
+
+	err = NULL;
+	anjuta_async_notify_get_error (async_notify, &err);
+	if (err)
+	{
+		gchar *vcs_uri;
+
+		/* show the dialog since it's hidden */
+		gtk_widget_show (GTK_WIDGET (ch->import_dialog));
+		
+		vcs_uri = project_import_dialog_get_vcs_uri (ch->import_dialog);
+		anjuta_util_dialog_error (GTK_WINDOW (ch->import_dialog),
+		                          _("Couldn't checkout the supplied uri "
+		                          "\"%s\", the error returned was: \"%s\""),
+		                          vcs_uri, err->message);
+
+		g_free (vcs_uri);
+		g_error_free (err);
+
+		goto cleanup;
+	}
+
+	project_import_import_project (ch->import_plugin, ch->import_dialog, ch->checkout_dir);
+
+cleanup:
+	g_object_unref (ch->checkout_dir);
+	g_slice_free (CheckoutData, ch);
+}
+
+static void
+project_import_checkout_project (AnjutaProjectImportPlugin *import_plugin,
+                                 ProjectImportDialog *import_dialog)
+{
+	CheckoutData *ch_data;
+	AnjutaAsyncNotify *async_notify;
+	gchar *vcs_uri, *plugin_id, *name;
+	GFile *dest_dir, *checkout_dir;
+	AnjutaPluginManager *plugin_manager;
+	IAnjutaVcs *ivcs;
+	GError *err;
+
+	name = project_import_dialog_get_name (import_dialog);
+	dest_dir = project_import_dialog_get_dest_dir (import_dialog);
+	checkout_dir = g_file_get_child (dest_dir, name);
+
+	g_object_unref (dest_dir);
+	g_free (name);
+	
+	ch_data = g_slice_new (CheckoutData);
+	ch_data->import_plugin = import_plugin;
+	ch_data->import_dialog = import_dialog;
+	ch_data->checkout_dir = checkout_dir;
+	
+	async_notify = anjuta_async_notify_new ();
+	g_signal_connect (async_notify, "finished", G_CALLBACK (checkout_finished),
+	                  ch_data);
+
+	vcs_uri = project_import_dialog_get_vcs_uri (import_dialog);
+	plugin_id = project_import_dialog_get_vcs_id (import_dialog);
+
+	plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (import_plugin)->shell, NULL);
+	ivcs = IANJUTA_VCS (anjuta_plugin_manager_get_plugin_by_id (plugin_manager, plugin_id));
+
+	err = NULL;
+	ianjuta_vcs_checkout (ivcs, vcs_uri, checkout_dir, NULL, async_notify, &err);
+	if (err)
+	{
+		anjuta_util_dialog_error (GTK_WINDOW (import_dialog),
+		                          _("Couldn't checkout the supplied uri "
+		                            "\"%s\", the error returned was: \"%s\""),
+		                          vcs_uri, err->message);
+
+		g_error_free (err);
+		
+		goto cleanup;
+	}
+
+	/* hide the import dialog */
+	gtk_widget_hide (GTK_WIDGET (import_dialog));
+
+cleanup:
+	g_free (vcs_uri);
+	g_free (plugin_id);
+}
+
+static void
+import_dialog_response (GtkDialog *dialog, gint response_id, gpointer user_data)
+{
+	AnjutaProjectImportPlugin *import_plugin = (AnjutaProjectImportPlugin *)user_data;
+	ProjectImportDialog *import_dialog = PROJECT_IMPORT_DIALOG (dialog);
+	
+	switch (response_id)
+	{
+		case GTK_RESPONSE_ACCEPT:
+		{
+			GFile *source_dir;
+
+			source_dir = project_import_dialog_get_source_dir (import_dialog);
+			if (source_dir)
+			{
+				if (project_import_import_project (import_plugin, import_dialog, source_dir))
+					gtk_widget_destroy (GTK_WIDGET (import_dialog));
+				
+				g_object_unref (source_dir);
+			}
+			else
+				project_import_checkout_project (import_plugin, import_dialog);
+
+			break;
+
+		}
+		case GTK_RESPONSE_REJECT:
+			gtk_widget_destroy (GTK_WIDGET (dialog));
+	}
+}
+
+static gboolean
 activate_plugin (AnjutaPlugin *plugin)
 {
 	AnjutaProjectImportPlugin *iplugin;
@@ -62,6 +405,11 @@
 static void
 finalize (GObject *obj)
 {
+	AnjutaProjectImportPlugin *import_plugin = (AnjutaProjectImportPlugin *)obj;
+
+	if (import_plugin->backend_id)
+		g_free (import_plugin->backend_id);
+	
 	G_OBJECT_CLASS (parent_class)->finalize (obj);
 }
 
@@ -88,9 +436,15 @@
 iwizard_activate (IAnjutaWizard *wiz, GError **err)
 {
 	AnjutaProjectImportPlugin* plugin = ANJUTA_PLUGIN_PROJECT_IMPORT (wiz);
-	ProjectImport* pi;
-	
-	pi = project_import_new(ANJUTA_PLUGIN(plugin));
+	AnjutaPluginManager *plugin_manager;
+	ProjectImportDialog* pi;
+
+	plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell, NULL);
+
+	pi = project_import_dialog_new(plugin_manager, NULL, NULL);
+	g_signal_connect (pi, "response", G_CALLBACK (import_dialog_response), plugin);
+
+	gtk_widget_show (GTK_WIDGET (pi));
 }
 
 static void
@@ -102,22 +456,30 @@
 static void
 ifile_open (IAnjutaFile *ifile, GFile* file, GError **err)
 {
-	gchar *dir, *ext, *project_name;
-	ProjectImport* pi;
+	gchar *ext, *project_name;
+	GFile *dir;
+	ProjectImportDialog* pi;
 	AnjutaProjectImportPlugin* plugin = ANJUTA_PLUGIN_PROJECT_IMPORT (ifile);
 	gchar* uri = g_file_get_uri (file);
+	AnjutaPluginManager *plugin_manager;
 	
 	g_return_if_fail (uri != NULL && strlen (uri) > 0);
 	
-	dir = g_path_get_dirname (uri);
+	dir = g_file_get_parent (file);
 	project_name = g_path_get_basename (uri);
 	ext = strrchr (project_name, '.');
 	if (ext)
 		*ext = '\0';
+
+	plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (plugin)->shell, NULL);
+	
+	pi = project_import_dialog_new (plugin_manager, project_name, dir);
+	g_signal_connect (pi, "response", G_CALLBACK (import_dialog_response), plugin);
+
+	gtk_widget_show (GTK_WIDGET (pi));
 	
-	pi = project_import_new(ANJUTA_PLUGIN(plugin));
-	project_import_set_name (pi, project_name);
-	project_import_set_directory (pi, dir);
+	g_object_unref (dir);
+	g_free (project_name);
 	g_free (uri);
 }
 

Modified: trunk/plugins/project-import/plugin.h
==============================================================================
--- trunk/plugins/project-import/plugin.h	(original)
+++ trunk/plugins/project-import/plugin.h	Thu Apr  2 08:41:03 2009
@@ -40,6 +40,7 @@
 {
 	AnjutaPlugin parent;
 	AnjutaPreferences *prefs;
+	gchar *backend_id;
 };
 
 struct _AnjutaProjectImportPluginClass

Added: trunk/plugins/project-import/project-import-dialog.c
==============================================================================
--- (empty file)
+++ trunk/plugins/project-import/project-import-dialog.c	Thu Apr  2 08:41:03 2009
@@ -0,0 +1,297 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) Carl-Anton Ingmarsson 2009 <ca ingmarsson gmail com>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "project-import-dialog.h"
+#include <glib/gi18n.h>
+
+#define BUILDER_FILE PACKAGE_DATA_DIR"/glade/project-import.glade"
+
+G_DEFINE_TYPE (ProjectImportDialog, project_import_dialog, GTK_TYPE_DIALOG);
+
+typedef struct _ProjectImportDialogPrivate ProjectImportDialogPrivate;
+
+struct _ProjectImportDialogPrivate {
+	GtkEntry *name_entry;
+	GtkWidget *source_dir_button;
+	GtkWidget *vcs_entry;
+	GtkWidget *dest_dir_button;
+	GtkWidget *import_button;
+	GtkWidget *folder_radio;
+	GtkWidget *vcs_combo;
+	GtkListStore *vcs_store;
+};
+
+#define GET_PRIVATE(o) \
+	(G_TYPE_INSTANCE_GET_PRIVATE ((o), PROJECT_IMPORT_TYPE_DIALOG, ProjectImportDialogPrivate))
+
+static void
+vcs_entry_changed (GtkEditable *editable, gpointer user_data)
+{
+	ProjectImportDialog *project_import = (ProjectImportDialog *)user_data;
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (project_import);
+
+	if (gtk_entry_get_text_length (GTK_ENTRY (editable)))
+	{
+		if (gtk_entry_get_text_length (priv->name_entry))
+		{
+			gtk_widget_set_sensitive (priv->import_button, TRUE);
+		}
+	}
+	else
+		gtk_widget_set_sensitive (priv->import_button, FALSE);
+}
+
+static void
+name_entry_changed (GtkEditable *editable, gpointer user_data)
+{
+	ProjectImportDialog *project_import = (ProjectImportDialog *)user_data;
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (project_import);
+
+	if (gtk_entry_get_text_length (GTK_ENTRY (editable)))
+	{
+		if ((gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->folder_radio)) ||
+		     gtk_entry_get_text_length (GTK_ENTRY (priv->vcs_entry))))
+		{
+			gtk_widget_set_sensitive (priv->import_button, TRUE);
+		}
+	}
+	else
+		gtk_widget_set_sensitive (priv->import_button, FALSE);
+}
+
+static void
+folder_radio_toggled (GtkToggleButton *button, gpointer user_data)
+{
+	ProjectImportDialog *project_import = (ProjectImportDialog *)user_data;
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (project_import);
+
+	gtk_widget_set_sensitive (priv->source_dir_button, TRUE);
+	gtk_widget_set_sensitive (priv->vcs_entry, FALSE);
+	gtk_widget_set_sensitive (priv->dest_dir_button, FALSE);
+	gtk_widget_set_sensitive (priv->vcs_combo, FALSE);
+	
+	if (gtk_entry_get_text_length (priv->name_entry))
+	{
+		gtk_widget_set_sensitive (priv->import_button, TRUE);
+	}
+	else
+		gtk_widget_set_sensitive (priv->import_button, FALSE);
+}
+
+static void
+vcs_radio_toggled (GtkToggleButton *button, gpointer user_data)
+{
+	ProjectImportDialog *project_import = (ProjectImportDialog *)user_data;
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (project_import);
+
+	gtk_widget_set_sensitive (priv->vcs_entry, TRUE);
+	gtk_widget_set_sensitive (priv->dest_dir_button, TRUE);
+	gtk_widget_set_sensitive (priv->vcs_combo, TRUE);
+	gtk_widget_set_sensitive (priv->source_dir_button, FALSE);
+	
+	if ((gtk_entry_get_text_length (GTK_ENTRY (priv->vcs_entry))
+	    && gtk_entry_get_text (priv->name_entry)))
+	{
+		gtk_widget_set_sensitive (priv->import_button, TRUE);
+	}
+	else
+		gtk_widget_set_sensitive (priv->import_button, FALSE);
+}
+
+gchar *
+project_import_dialog_get_vcs_id (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (import_dialog);
+	GtkTreeIter iter;
+	gchar *vcs_id;
+
+	g_assert (PROJECT_IS_IMPORT_DIALOG (import_dialog));
+	
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->folder_radio)))
+		return NULL;
+
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->vcs_combo), &iter);
+	gtk_tree_model_get (GTK_TREE_MODEL (priv->vcs_store), &iter, 1, &vcs_id, -1);
+
+	return vcs_id;
+}
+
+gchar *
+project_import_dialog_get_vcs_uri (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (import_dialog);
+
+	g_assert (PROJECT_IS_IMPORT_DIALOG (import_dialog));
+	
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->folder_radio)))
+		return NULL;
+	
+	return g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->vcs_entry)));
+}
+
+GFile *
+project_import_dialog_get_dest_dir (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (import_dialog);
+
+	g_assert (PROJECT_IS_IMPORT_DIALOG (import_dialog));
+	
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->folder_radio)))
+		return NULL;
+	
+	return gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dest_dir_button));
+}
+
+GFile *
+project_import_dialog_get_source_dir (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (import_dialog);
+
+	g_assert (PROJECT_IS_IMPORT_DIALOG (import_dialog));
+	
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->folder_radio)))
+		return NULL;
+	
+	return gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->source_dir_button));
+}
+
+gchar *
+project_import_dialog_get_name (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv = GET_PRIVATE (import_dialog);
+
+	g_assert (PROJECT_IS_IMPORT_DIALOG (import_dialog));
+
+	return g_strdup (gtk_entry_get_text (priv->name_entry));
+}
+
+ProjectImportDialog *
+project_import_dialog_new (AnjutaPluginManager *plugin_manager, const gchar *name, GFile *dir)
+{
+	ProjectImportDialog *import_dialog;
+	ProjectImportDialogPrivate *priv;
+	GList *plugin_descs, *l_iter;
+
+	import_dialog = g_object_new (PROJECT_IMPORT_TYPE_DIALOG, NULL);
+	priv = GET_PRIVATE (import_dialog);
+
+	if (name)
+		gtk_entry_set_text (priv->name_entry, name);
+	if (dir)
+		gtk_file_chooser_set_file (GTK_FILE_CHOOSER (priv->source_dir_button), dir, NULL);
+
+	plugin_descs = anjuta_plugin_manager_query (plugin_manager,
+	                                            "Anjuta Plugin",
+	                                            "Interfaces",
+	                                            "IAnjutaVcs",
+	                                            NULL);
+	for (l_iter = plugin_descs; l_iter; l_iter = l_iter->next)
+	{
+		gchar *vcs_name, *plugin_id;
+		GtkTreeIter iter;
+		
+		anjuta_plugin_description_get_string (l_iter->data, "Vcs", "System",
+		                                      &vcs_name);
+		anjuta_plugin_description_get_string (l_iter->data, "Anjuta Plugin", "Location",
+		                                      &plugin_id);
+
+		gtk_list_store_append (priv->vcs_store, &iter);
+		gtk_list_store_set (priv->vcs_store, &iter, 0, vcs_name, 1, plugin_id, -1);
+
+		g_free (vcs_name);
+		g_free (plugin_id);
+
+		gtk_combo_box_set_active (GTK_COMBO_BOX (priv->vcs_combo), 0);
+	}
+	
+	g_list_free (plugin_descs);
+
+	return import_dialog;
+}
+
+static void
+project_import_dialog_init (ProjectImportDialog *import_dialog)
+{
+	ProjectImportDialogPrivate *priv;
+	GtkBuilder *builder;
+	gchar *object_ids[] = {"top_level", "vcs_store", NULL};
+	GtkWidget *image;
+
+	priv = GET_PRIVATE (import_dialog);
+	
+	builder = gtk_builder_new ();
+	gtk_builder_add_objects_from_file (builder, BUILDER_FILE, object_ids, NULL);
+
+	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (import_dialog))),
+	                   GTK_WIDGET (gtk_builder_get_object (builder, "top_level")));
+
+	priv->name_entry =  GTK_ENTRY (gtk_builder_get_object (builder, "name_entry"));
+	priv->source_dir_button = GTK_WIDGET (gtk_builder_get_object (builder, "source_dir_button"));
+	priv->vcs_entry = GTK_WIDGET (gtk_builder_get_object (builder, "vcs_entry"));
+	priv->dest_dir_button = GTK_WIDGET (gtk_builder_get_object (builder, "dest_dir_button"));
+	priv->folder_radio = GTK_WIDGET (gtk_builder_get_object (builder, "folder_radio"));
+	priv->vcs_combo = GTK_WIDGET (gtk_builder_get_object (builder, "vcs_combo"));
+	priv->vcs_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "vcs_store"));
+
+	g_signal_connect (priv->name_entry, "changed", G_CALLBACK (name_entry_changed),
+	                  import_dialog);
+	g_signal_connect (priv->vcs_entry, "changed", G_CALLBACK (vcs_entry_changed),
+	                  import_dialog);
+	
+	g_signal_connect (priv->folder_radio, "toggled",
+	                  G_CALLBACK (folder_radio_toggled), import_dialog);
+	g_signal_connect (gtk_builder_get_object (builder, "vcs_radio"), "toggled",
+	                  G_CALLBACK (vcs_radio_toggled), import_dialog);
+
+	g_object_unref (builder);
+
+	gtk_window_set_title (GTK_WINDOW (import_dialog), _("Import project"));
+
+	gtk_dialog_add_button (GTK_DIALOG (import_dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+	priv->import_button = gtk_dialog_add_button (GTK_DIALOG (import_dialog), _("Import"), GTK_RESPONSE_ACCEPT);
+	image = gtk_image_new_from_stock (GTK_STOCK_CONVERT, GTK_ICON_SIZE_BUTTON);
+	gtk_button_set_image (GTK_BUTTON (priv->import_button), image);
+	gtk_widget_set_sensitive (priv->import_button, FALSE);
+}
+
+static void
+project_import_dialog_finalize (GObject *object)
+{
+	/* TODO: Add deinitalization code here */
+
+	G_OBJECT_CLASS (project_import_dialog_parent_class)->finalize (object);
+}
+
+static void
+project_import_dialog_class_init (ProjectImportDialogClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtkDialogClass* parent_class = GTK_DIALOG_CLASS (klass);
+
+	object_class->finalize = project_import_dialog_finalize;
+
+	g_type_class_add_private (klass, sizeof (ProjectImportDialogPrivate));
+}
+

Added: trunk/plugins/project-import/project-import-dialog.h
==============================================================================
--- (empty file)
+++ trunk/plugins/project-import/project-import-dialog.h	Thu Apr  2 08:41:03 2009
@@ -0,0 +1,69 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) Carl-Anton Ingmarsson 2009 <ca ingmarsson gmail com>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _PROJECT_IMPORT_DIALOG_H_
+#define _PROJECT_IMPORT_DIALOG_H_
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#include <libanjuta/anjuta-plugin.h>
+
+G_BEGIN_DECLS
+
+#define PROJECT_IMPORT_TYPE_DIALOG             (project_import_dialog_get_type ())
+#define PROJECT_IMPORT_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), PROJECT_IMPORT_TYPE_DIALOG, ProjectImportDialog))
+#define PROJECT_IMPORT_DIALOG_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), PROJECT_IMPORT_TYPE_DIALOG, ProjectImportDialogClass))
+#define PROJECT_IS_IMPORT_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PROJECT_IMPORT_TYPE_DIALOG))
+#define PROJECT_IS_IMPORT_DIALOG_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), PROJECT_IMPORT_TYPE_DIALOG))
+#define PROJECT_IMPORT_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), PROJECT_IMPORT_TYPE_DIALOG, ProjectImportDialogClass))
+
+typedef struct _ProjectImportDialogClass ProjectImportDialogClass;
+typedef struct _ProjectImportDialog ProjectImportDialog;
+
+struct _ProjectImportDialogClass
+{
+	GtkDialogClass parent_class;
+};
+
+struct _ProjectImportDialog
+{
+	GtkDialog parent_instance;
+};
+
+GType project_import_dialog_get_type (void) G_GNUC_CONST;
+
+ProjectImportDialog *project_import_dialog_new (AnjutaPluginManager *plugin_manager, const gchar *name, GFile *dir);
+
+gchar *project_import_dialog_get_name (ProjectImportDialog *import_dialog);
+
+GFile *project_import_dialog_get_source_dir (ProjectImportDialog *import_dialog);
+
+GFile *project_import_dialog_get_dest_dir (ProjectImportDialog *import_dialog);
+gchar * project_import_dialog_get_vcs_uri (ProjectImportDialog *import_dialog);
+gchar *project_import_dialog_get_vcs_id (ProjectImportDialog *import_dialog);
+
+G_END_DECLS
+
+#endif /* _PROJECT_IMPORT_DIALOG_H_ */

Added: trunk/plugins/project-import/project-import.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/project-import/project-import.glade	Thu Apr  2 08:41:03 2009
@@ -0,0 +1,276 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.14"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkWindow" id="window1">
+    <child>
+      <object class="GtkAlignment" id="top_level">
+        <property name="visible">True</property>
+        <property name="top_padding">12</property>
+        <property name="bottom_padding">12</property>
+        <property name="left_padding">12</property>
+        <property name="right_padding">12</property>
+        <child>
+          <object class="GtkVBox" id="vbox">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkFrame" id="frame3">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment6">
+                    <property name="visible">True</property>
+                    <property name="top_padding">6</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkEntry" id="name_entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x2022;</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label7">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Project name&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame" id="frame4">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment7">
+                    <property name="visible">True</property>
+                    <property name="top_padding">6</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox1">
+                        <property name="visible">True</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkFrame" id="frame7">
+                            <property name="visible">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment13">
+                                <property name="visible">True</property>
+                                <property name="bottom_padding">6</property>
+                                <property name="left_padding">12</property>
+                                <property name="right_padding">6</property>
+                                <child>
+                                  <object class="GtkFileChooserButton" id="source_dir_button">
+                                    <property name="visible">True</property>
+                                    <property name="action">select-folder</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child type="label">
+                              <object class="GtkHBox" id="hbox8">
+                                <property name="visible">True</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkRadioButton" id="folder_radio">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="label14">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Import from folder</property>
+                                  </object>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFrame" id="frame9">
+                            <property name="visible">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">none</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment16">
+                                <property name="visible">True</property>
+                                <property name="bottom_padding">6</property>
+                                <property name="left_padding">12</property>
+                                <property name="right_padding">6</property>
+                                <child>
+                                  <object class="GtkTable" id="table4">
+                                    <property name="visible">True</property>
+                                    <property name="n_rows">2</property>
+                                    <property name="n_columns">3</property>
+                                    <property name="column_spacing">6</property>
+                                    <property name="row_spacing">6</property>
+                                    <child>
+                                      <object class="GtkLabel" id="label23">
+                                        <property name="visible">True</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">Location:</property>
+                                      </object>
+                                      <packing>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkLabel" id="label24">
+                                        <property name="visible">True</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">Destination:</property>
+                                      </object>
+                                      <packing>
+                                        <property name="top_attach">1</property>
+                                        <property name="bottom_attach">2</property>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options"></property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkFileChooserButton" id="dest_dir_button">
+                                        <property name="visible">True</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="action">select-folder</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                        <property name="top_attach">1</property>
+                                        <property name="bottom_attach">2</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkEntry" id="vcs_entry">
+                                        <property name="visible">True</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="invisible_char">&#x2022;</property>
+                                        <property name="width_chars">60</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="right_attach">2</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkComboBox" id="vcs_combo">
+                                        <property name="visible">True</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="model">vcs_store</property>
+                                        <signal name="changed" handler="on_vcs_combo_changed"/>
+                                        <child>
+                                          <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                                          <attributes>
+                                            <attribute name="text">0</attribute>
+                                          </attributes>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">2</property>
+                                        <property name="right_attach">3</property>
+                                        <property name="x_options">GTK_FILL</property>
+                                        <property name="y_options">GTK_FILL</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <placeholder/>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child type="label">
+                              <object class="GtkHBox" id="hbox10">
+                                <property name="visible">True</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkRadioButton" id="vcs_radio">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="draw_indicator">True</property>
+                                    <property name="group">folder_radio</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="label22">
+                                    <property name="visible">True</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Import from version control system</property>
+                                  </object>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Import options&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkListStore" id="vcs_store">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+      <!-- column-name gchararray2 -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+</interface>

Modified: trunk/plugins/subversion/subversion-vcs-interface.c
==============================================================================
--- trunk/plugins/subversion/subversion-vcs-interface.c	(original)
+++ trunk/plugins/subversion/subversion-vcs-interface.c	Thu Apr  2 08:41:03 2009
@@ -67,9 +67,22 @@
 						  GCancellable *cancel,
 						  AnjutaAsyncNotify *notify, GError **err)
 {
+	GError *error;
 	gchar *path;
 	SvnCheckoutCommand *checkout_command;
 	Subversion *plugin;
+
+	error = NULL;
+	g_file_make_directory (dest, NULL, &error);
+	if (error)
+	{
+		if (error->code != G_IO_ERROR_EXISTS)
+		{
+			g_propagate_error (err, error);
+			return;
+		}
+		g_error_free (error);
+	}
 	
 	path = g_file_get_path (dest);
 	checkout_command = svn_checkout_command_new (repository_location, path);



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