* plugins/project-import/project-import.c:
[anjuta-git-plugin.git] / plugins / project-import / project-import.c
blobbea8a27178c94cbc8dca24f619c7a11ece93ae91
1 /*
2 * project-import.c (c) 2005 Johannes Schmid
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Library General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #include "project-import.h"
19 #include <gnome.h>
20 #include <libgnomevfs/gnome-vfs.h>
21 #include <libanjuta/interfaces/ianjuta-file-loader.h>
23 #include <config.h>
25 #include <gbf/gbf-backend.h>
27 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-project-import.glade"
28 #define AM_PROJECT_FILE PACKAGE_DATA_DIR"/project/terminal/project.anjuta"
29 #define MKFILE_PROJECT_FILE PACKAGE_DATA_DIR"/project/mkfile/project.anjuta"
31 static GObjectClass *parent_class = NULL;
33 static void
34 on_import_cancel (GnomeDruid* druid, ProjectImport* pi)
36 g_object_unref (G_OBJECT(pi));
39 static gboolean
40 on_import_key_press_event(GtkWidget *widget, GdkEventKey *event,
41 ProjectImport* pi)
43 if (event->keyval == GDK_Escape)
45 g_object_unref(G_OBJECT(pi));
46 return TRUE;
48 return FALSE;
51 static gboolean
52 on_import_next(GnomeDruidPage* page, GtkWidget* druid, ProjectImport* pi)
54 GSList* l;
55 GbfBackend* backend = NULL;
56 GbfProject* proj;
58 const gchar* name = gtk_entry_get_text(GTK_ENTRY(pi->import_name));
59 gchar* path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(pi->import_path));
61 if (!name || !path || !strlen(name) || !strlen(path))
63 g_free (path);
64 return TRUE;
67 gbf_backend_init();
69 for (l = gbf_backend_get_backends (); l; l = l->next) {
70 backend = l->data;
71 if (!backend)
73 g_warning("Backend appears empty!");
74 continue;
77 /* Probe the backend to find out if the project directory is OK */
78 /* If probe() returns TRUE then we have a valid backend */
80 proj = gbf_backend_new_project(backend->id);
81 if (proj)
83 if (gbf_project_probe(proj, path, NULL))
85 /* This is a valid backend for this root directory */
86 /* FIXME: Possibility of more than one valid backend? */
87 g_object_unref(proj);
88 break;
90 g_object_unref(proj);
92 backend = NULL;
95 if (!backend)
97 gchar* message_text =
98 g_strdup_printf(_("Could not find a valid project backend for the "
99 "directory given (%s). Please select a different "
100 "directory, or try upgrading to a newer version of "
101 "the Gnome Build Framework."), path);
103 GtkDialog* message =
104 GTK_DIALOG(gtk_message_dialog_new(GTK_WINDOW(pi->window),
105 GTK_DIALOG_DESTROY_WITH_PARENT,
106 GTK_MESSAGE_ERROR,
107 GTK_BUTTONS_CLOSE,
108 message_text));
110 g_free(message_text);
112 gtk_dialog_run(message);
113 gtk_widget_destroy(GTK_WIDGET(message));
114 g_free (path);
115 return TRUE;
118 gchar* summary;
120 summary = g_strdup_printf(_("Project name: %s\n"
121 "Project type: %s\n"
122 "Project path: %s\n"),
123 name, backend->name, path);
124 gnome_druid_page_edge_set_text(GNOME_DRUID_PAGE_EDGE(pi->import_finish),
125 summary);
127 g_free(summary);
129 if (pi->backend_id)
130 g_free(pi->backend_id);
131 pi->backend_id = g_strdup(backend->id);
132 g_free (path);
134 return FALSE;
137 static gboolean
138 on_import_finish (GnomeDruidPage* page, GtkWidget* druid, ProjectImport* pi)
140 const gchar* name = gtk_entry_get_text (GTK_ENTRY(pi->import_name));
141 gchar* path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(pi->import_path));
143 gchar* project_file = g_strconcat (path, "/", name, ".", "anjuta", NULL);
145 IAnjutaFileLoader* loader;
147 if (!project_import_generate_file (pi, project_file))
149 g_free (project_file);
150 g_free (path);
151 return TRUE;
154 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (pi->plugin)->shell,
155 IAnjutaFileLoader, NULL);
156 if (!loader)
158 g_warning("No IAnjutaFileLoader interface! Cannot open project file!");
159 g_object_unref (G_OBJECT (pi));
160 g_free (project_file);
161 return FALSE;
163 ianjuta_file_loader_load (loader, project_file, FALSE, NULL);
164 g_object_unref (G_OBJECT (pi));
165 g_free (project_file);
166 g_free (path);
167 return FALSE;
170 static void
171 project_import_init(ProjectImport *pi)
173 GladeXML* gxml = glade_xml_new(GLADE_FILE, "import_window", NULL);
174 GtkWidget* import_page;
176 pi->window = glade_xml_get_widget(gxml, "import_window");
177 pi->druid = glade_xml_get_widget(gxml, "import_druid");
178 pi->import_name = glade_xml_get_widget(gxml, "import_name");
179 pi->import_path = glade_xml_get_widget(gxml, "import_path");
180 pi->import_finish = glade_xml_get_widget(gxml, "import_finish");
182 pi->backend_id = NULL;
184 import_page = glade_xml_get_widget(gxml, "import_page");
185 g_signal_connect(G_OBJECT(import_page), "next",
186 G_CALLBACK(on_import_next), pi);
187 g_signal_connect(G_OBJECT(pi->import_finish), "finish",
188 G_CALLBACK(on_import_finish), pi);
189 g_signal_connect(G_OBJECT(pi->druid), "cancel",
190 G_CALLBACK(on_import_cancel), pi);
191 g_signal_connect(G_OBJECT(pi->druid), "key-press-event",
192 G_CALLBACK(on_import_key_press_event), pi);
194 g_object_unref(G_OBJECT(gxml));
195 gtk_widget_show_all(pi->window);
198 static void
199 project_import_finalize(GObject *object)
201 ProjectImport *cobj;
202 cobj = PROJECT_IMPORT(object);
204 if (cobj->backend_id)
205 g_free(cobj->backend_id);
207 gtk_widget_destroy(cobj->window);
209 /* Deactivate plugin once wizard is finished */
210 if (anjuta_plugin_is_active(cobj->plugin))
211 anjuta_plugin_deactivate (cobj->plugin);
212 G_OBJECT_CLASS(parent_class)->finalize(object);
215 static void
216 project_import_class_init(ProjectImportClass *klass)
218 GObjectClass *object_class = G_OBJECT_CLASS(klass);
220 parent_class = g_type_class_peek_parent(klass);
221 object_class->finalize = project_import_finalize;
224 GType
225 project_import_get_type()
227 static GType type = 0;
229 if(type == 0) {
230 static const GTypeInfo our_info = {
231 sizeof (ProjectImportClass),
232 NULL,
233 NULL,
234 (GClassInitFunc)project_import_class_init,
235 NULL,
236 NULL,
237 sizeof (ProjectImport),
239 (GInstanceInitFunc)project_import_init,
242 type = g_type_register_static(G_TYPE_OBJECT,
243 "ProjectImport", &our_info, 0);
246 return type;
249 ProjectImport *
250 project_import_new(AnjutaPlugin* plugin)
252 ProjectImport *obj;
254 obj = PROJECT_IMPORT(g_object_new(PROJECT_IMPORT_TYPE, NULL));
256 obj->plugin = plugin;
257 gtk_window_set_transient_for (GTK_WINDOW (obj->window),
258 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
260 return obj;
263 void
264 project_import_set_name (ProjectImport *pi, const gchar *name)
266 g_return_if_fail (IS_PROJECT_IMPORT (pi));
267 g_return_if_fail (name != NULL);
269 gtk_entry_set_text (GTK_ENTRY (pi->import_name), name);
272 void
273 project_import_set_directory (ProjectImport *pi, const gchar *directory)
275 g_return_if_fail (IS_PROJECT_IMPORT (pi));
276 g_return_if_fail (directory != NULL);
278 gchar* uri = gnome_vfs_make_uri_from_input (directory);
279 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (pi->import_path), uri);
280 g_free (uri);
283 gboolean
284 project_import_generate_file(ProjectImport* pi, const gchar* prjfile)
286 /* Of course we could do some more intelligent stuff here
287 and check which plugins are really needed but for now we just
288 take a default project file. */
290 GnomeVFSURI* source_uri;
291 if (!strcmp (pi->backend_id, "gbf-am:GbfAmProject"))
292 source_uri = gnome_vfs_uri_new(AM_PROJECT_FILE);
293 else if (!strcmp (pi->backend_id, "gbf-mkfile:GbfMkfileProject"))
294 source_uri = gnome_vfs_uri_new(MKFILE_PROJECT_FILE);
295 else
297 /* We shouldn't get here, unless someone has upgraded their GBF */
298 /* but not Anjuta. */
300 GtkWidget *dlg;
302 dlg = gtk_message_dialog_new(GTK_WINDOW(pi->window),
303 GTK_DIALOG_DESTROY_WITH_PARENT,
304 GTK_MESSAGE_ERROR,
305 GTK_BUTTONS_CLOSE,
306 _("Generation of project file failed. Cannot "
307 "find an appropriate project template to "
308 "use. Please make sure your version of "
309 "Anjuta is up to date."));
311 gtk_dialog_run(GTK_DIALOG(dlg));
312 gtk_widget_destroy (dlg);
313 return FALSE;
316 GnomeVFSURI* dest_uri = gnome_vfs_uri_new(prjfile);
318 GnomeVFSResult error = gnome_vfs_xfer_uri (source_uri,
319 dest_uri,
320 GNOME_VFS_XFER_DEFAULT,
321 GNOME_VFS_XFER_ERROR_MODE_ABORT,
322 GNOME_VFS_XFER_OVERWRITE_MODE_ABORT,
323 NULL,
324 NULL);
325 /* Handle already existing file */
326 if (error == GNOME_VFS_ERROR_FILE_EXISTS)
328 if (anjuta_util_dialog_boolean_question (GTK_WINDOW (pi->window),
329 _("A file named \"%s\" already exists. "
330 "Do you want to replace it?"), prjfile))
332 error = gnome_vfs_xfer_uri (source_uri,
333 dest_uri,
334 GNOME_VFS_XFER_DEFAULT,
335 GNOME_VFS_XFER_ERROR_MODE_ABORT,
336 GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
337 NULL,
338 NULL);
342 /* Update file time if possible */
343 if (error == GNOME_VFS_OK)
345 GnomeVFSFileInfo *file_info;
347 file_info = gnome_vfs_file_info_new ();
348 file_info->ctime = time (NULL);
349 file_info->mtime = file_info->ctime;
350 file_info->atime = file_info->ctime;
352 gnome_vfs_set_file_info_uri (dest_uri,
353 file_info,
354 GNOME_VFS_SET_FILE_INFO_TIME);
356 gnome_vfs_file_info_unref (file_info);
359 gnome_vfs_uri_unref (source_uri);
360 gnome_vfs_uri_unref (dest_uri);
362 switch (error)
364 case GNOME_VFS_OK:
365 break;
366 case GNOME_VFS_ERROR_FILE_EXISTS:
367 return FALSE;
368 default:
369 anjuta_util_dialog_error (GTK_WINDOW (pi->window),
370 _("A file named \"%s\" cannot be written: %s. "
371 "Check if you have write access to the project directory."),
372 prjfile, gnome_vfs_result_to_string (error));
374 return FALSE;
377 return TRUE;