debug-manager: use g_spawn_sync() instead of fork() and waitpid()
[anjuta.git] / plugins / class-gen / plugin.c
blob746437dda5b6c1ce0dd670bfa83e8d731c2b5919
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /* plugin.c
3 * Copyright (C) 2005 Massimo Cora'
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include <config.h>
21 #include <gtk/gtk.h>
22 #include <glib/gi18n.h>
23 #include <libanjuta/anjuta-preferences.h>
24 #include <libanjuta/anjuta-debug.h>
25 #include <libanjuta/anjuta-autogen.h>
26 #include <libanjuta/interfaces/ianjuta-wizard.h>
27 #include <libanjuta/interfaces/ianjuta-project-manager.h>
28 #include <libanjuta/interfaces/ianjuta-file-loader.h>
29 #include <libanjuta/interfaces/ianjuta-vcs.h>
30 #include <libanjuta/interfaces/ianjuta-editor.h>
31 #include <libanjuta/interfaces/ianjuta-document-manager.h>
34 #include "plugin.h"
35 /* #include "class_gen.h" */
37 #include "window.h"
39 #define ICON_FILE "anjuta-class-gen-plugin-48.png"
41 /* Common editor preferences */
42 #define ANJUTA_PREF_SCHEMA_PREFIX "org.gnome.anjuta."
44 /* Indentation template variables */
45 #define INDENT_WIDTH_PROPERTY "IndentWidth"
46 #define TAB_WIDTH_PROPERTY "TabWidth"
47 #define USE_TABS_PROPERTY "UseTabs"
49 static gpointer parent_class;
51 static void
52 project_root_added (AnjutaPlugin *plugin,
53 G_GNUC_UNUSED const gchar *name,
54 const GValue *value,
55 G_GNUC_UNUSED gpointer user_data)
57 AnjutaClassGenPlugin *cg_plugin;
58 const gchar *root_uri;
60 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (plugin);
61 root_uri = g_value_get_string (value);
63 if (root_uri)
65 gchar *root_dir = anjuta_util_get_local_path_from_uri (root_uri);
66 if (root_dir)
67 cg_plugin->top_dir = g_strdup(root_dir);
68 else
69 cg_plugin->top_dir = NULL;
70 g_free (root_dir);
72 else
73 cg_plugin->top_dir = NULL;
76 static void
77 project_root_removed (AnjutaPlugin *plugin,
78 G_GNUC_UNUSED const gchar *name,
79 G_GNUC_UNUSED gpointer user_data)
81 AnjutaClassGenPlugin *cg_plugin;
82 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (plugin);
84 if (cg_plugin->top_dir)
85 g_free(cg_plugin->top_dir);
86 cg_plugin->top_dir = NULL;
89 static gboolean
90 activate_plugin (AnjutaPlugin *plugin)
92 AnjutaClassGenPlugin *cg_plugin;
94 DEBUG_PRINT ("%s", "AnjutaClassGenPlugin: Activating ClassGen plugin...");
95 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (plugin);
96 cg_plugin->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
98 g_return_val_if_fail (cg_plugin->prefs != NULL, FALSE);
100 cg_plugin->top_dir = NULL;
102 /* Check if autogen is present */
103 if(!anjuta_check_autogen())
105 anjuta_util_dialog_error(
106 NULL,
107 _("Could not find autogen version 5; please install the "
108 "autogen package. You can get it from "
109 "http://autogen.sourceforge.net."));
111 return FALSE;
114 /* set up project directory watch */
115 cg_plugin->root_watch_id = anjuta_plugin_add_watch (plugin,
116 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
117 project_root_added,
118 project_root_removed, NULL);
120 return TRUE;
123 static gboolean
124 deactivate_plugin (AnjutaPlugin *plugin)
126 AnjutaClassGenPlugin *cg_plugin;
127 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (plugin);
128 DEBUG_PRINT ("%s", "AnjutaClassGenPlugin: Deactivating ClassGen plugin ...");
130 /* Remove watches */
131 anjuta_plugin_remove_watch (plugin, cg_plugin->root_watch_id, TRUE);
133 return TRUE;
136 static void
137 dispose (GObject *obj)
139 G_OBJECT_CLASS (parent_class)->dispose (obj);
142 static void
143 finalize (GObject *obj)
145 AnjutaClassGenPlugin *cg_plugin;
146 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (obj);
147 g_free (cg_plugin->top_dir);
149 if(cg_plugin->window != NULL)
150 g_object_unref(G_OBJECT(cg_plugin->window));
151 if(cg_plugin->generator != NULL)
152 g_object_unref(G_OBJECT(cg_plugin->generator));
154 G_OBJECT_CLASS (parent_class)->finalize (obj);
157 static void
158 class_gen_plugin_class_init (GObjectClass *klass)
160 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
162 parent_class = g_type_class_peek_parent (klass);
164 plugin_class->activate = activate_plugin;
165 plugin_class->deactivate = deactivate_plugin;
166 klass->dispose = dispose;
167 klass->finalize = finalize;
170 static void
171 class_gen_plugin_instance_init (GObject *obj)
173 AnjutaClassGenPlugin *plugin = ANJUTA_PLUGIN_CLASS_GEN (obj);
174 plugin->root_watch_id = 0;
175 plugin->top_dir = NULL;
176 plugin->window = NULL;
177 plugin->generator = NULL;
180 static gboolean
181 cg_plugin_add_to_project (AnjutaClassGenPlugin *plugin,
182 const gchar *header_file,
183 const gchar *source_file,
184 gchar **new_header_file,
185 gchar **new_source_file,
186 GFile *target)
188 IAnjutaProjectManager *manager;
189 GFile *header = NULL;
190 GFile *source;
191 gboolean result;
193 manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
194 IAnjutaProjectManager, NULL);
196 if (manager == NULL)
197 return FALSE;
199 source = ianjuta_project_manager_add_source_quiet (manager, source_file,
200 target, NULL);
201 if (header_file) header = ianjuta_project_manager_add_source_quiet (manager, header_file,
202 target, NULL);
204 result = source != NULL;
205 if (result)
207 *new_source_file = g_file_get_path(source);
208 g_object_unref (source);
209 *new_header_file = NULL;
211 * Check if we're dealing with a programming language not having header
212 * files.
214 if (header_file != NULL)
216 if (header == NULL)
218 result = FALSE;
220 else
222 *new_header_file = g_file_get_path(header);
223 g_object_unref (header);
228 return result;
231 static void
232 cg_plugin_add_to_repository (AnjutaClassGenPlugin *plugin,
233 GFile *header_file,
234 GFile *source_file)
236 IAnjutaVcs *vcs;
237 vcs = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
238 IAnjutaVcs, NULL);
240 if(vcs != NULL)
242 GList* files = NULL;
243 AnjutaAsyncNotify* notify = anjuta_async_notify_new ();
244 if (header_file != NULL) files = g_list_append (files, header_file);
245 files = g_list_append (files, source_file);
246 ianjuta_vcs_add (vcs, files, notify, NULL);
247 g_list_free (files);
251 static void
252 cg_plugin_generator_error_cb (G_GNUC_UNUSED CgGenerator *generator,
253 GError *error,
254 gpointer user_data)
256 AnjutaClassGenPlugin *plugin;
257 plugin = (AnjutaClassGenPlugin *) user_data;
259 anjuta_util_dialog_error (
260 GTK_WINDOW (cg_window_get_dialog (plugin->window)),
261 _("Failed to execute autogen: %s"), error->message);
263 gtk_widget_set_sensitive (
264 GTK_WIDGET (cg_window_get_dialog (plugin->window)), TRUE);
267 static gboolean
268 cg_plugin_load (AnjutaClassGenPlugin *plugin,
269 CgGenerator *generator,
270 const gchar *file,
271 GError **error)
273 IAnjutaDocumentManager *docman;
274 IAnjutaEditor *editor;
275 gchar *name;
276 gchar *contents;
277 gboolean result;
279 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
280 IAnjutaDocumentManager, NULL);
282 if(g_file_get_contents(file, &contents, NULL, error) == FALSE)
283 return FALSE;
285 name = g_path_get_basename (file);
287 result = FALSE;
288 /* The content argument seems not to work */
289 editor = ianjuta_document_manager_add_buffer (docman, name, "", error);
291 if(editor != NULL)
293 ianjuta_editor_append(editor, contents, -1, error);
294 if(!error || *error == NULL)
295 result = TRUE;
298 g_free(contents);
299 g_free(name);
301 return result;
304 static void
305 cg_plugin_generator_created_cb (CgGenerator *generator,
306 gpointer user_data)
308 AnjutaClassGenPlugin *plugin;
309 const gchar *header_file;
310 const gchar *source_file;
311 IAnjutaFileLoader *loader;
313 plugin = (AnjutaClassGenPlugin *) user_data;
314 header_file = cg_generator_get_header_destination (generator);
315 source_file = cg_generator_get_source_destination (generator);
317 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
318 IAnjutaFileLoader, NULL);
320 if (cg_window_get_add_to_project (plugin->window))
322 GFile* header = NULL;
323 GFile* source = g_file_new_for_path (source_file);
324 IAnjutaProjectManager *manager;
326 * Check if we're workign with a programming language that
327 * doesn't need header files. If yes, don't create two tabs,
328 * as the header and source will be the same file.
330 if (header_file == NULL)
332 ianjuta_file_loader_load (loader, source, FALSE, NULL);
334 else
336 header = g_file_new_for_path (header_file);
337 ianjuta_file_loader_load (loader, header, FALSE, NULL);
338 ianjuta_file_loader_load (loader, source, FALSE, NULL);
341 if (cg_window_get_add_to_repository (plugin->window))
343 cg_plugin_add_to_repository (plugin, header, source);
346 manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell, IAnjutaProjectManager, NULL);
347 if (manager)
349 if (header == NULL)
351 g_signal_emit_by_name (G_OBJECT (manager), "element_added", source);
353 else
355 g_signal_emit_by_name (G_OBJECT (manager), "element_added", header);
356 g_signal_emit_by_name (G_OBJECT (manager), "element_added", source);
361 if (header != NULL) g_object_unref (header);
362 g_object_unref (source);
364 else
366 if (header_file == NULL)
368 /* We do not just use ianjuta_file_leader_load here to ensure that
369 * the new documents are flagged as changed and no path is
370 * already set. */
371 cg_plugin_load (plugin, generator, source_file, NULL);
373 else
375 cg_plugin_load (plugin, generator, header_file, NULL);
376 cg_plugin_load (plugin, generator, source_file, NULL);
380 g_object_unref (G_OBJECT (plugin->window));
381 plugin->window = NULL;
384 static void
385 cg_plugin_window_response_cb (G_GNUC_UNUSED GtkDialog *dialog,
386 gint response_id,
387 gpointer user_data)
389 AnjutaClassGenPlugin *plugin;
390 IAnjutaProjectManager *manager;
391 GHashTable *values;
392 GError *error;
393 gchar *name;
395 gchar *header_file;
396 gchar *source_file;
397 gboolean result;
399 plugin = (AnjutaClassGenPlugin *) user_data;
400 error = NULL;
402 if (response_id == GTK_RESPONSE_ACCEPT)
404 if (cg_window_get_add_to_project (plugin->window))
406 GFile *target = cg_window_get_selected_target (plugin->window);
407 result = cg_plugin_add_to_project (
408 plugin, cg_window_get_header_file (plugin->window),
409 cg_window_get_source_file (plugin->window),
410 &header_file, &source_file,
411 target);
413 else
415 header_file = cg_window_get_header_file (plugin->window) != NULL ? g_build_filename (g_get_tmp_dir (),
416 cg_window_get_header_file (plugin->window), NULL) : NULL;
417 source_file = g_build_filename (g_get_tmp_dir (),
418 cg_window_get_source_file (plugin->window), NULL);
420 result = TRUE;
423 if (result == TRUE)
425 GSettings *settings;
426 gboolean flag;
427 gint i;
429 values = cg_window_create_value_heap (plugin->window);
431 manager = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
432 IAnjutaProjectManager, NULL);
434 if (manager != NULL && plugin->top_dir != NULL)
436 /* Use basename of the project's root URI as project name. */
437 name = g_path_get_basename (plugin->top_dir);
438 g_hash_table_insert (values, "ProjectName", name);
440 else
442 name = g_path_get_basename (cg_window_get_source_file(
443 plugin->window));
444 g_hash_table_insert (values, "ProjectName", name);
447 /* Set indentation settings */
448 /* Add use-tabs property */
449 settings = g_settings_new (ANJUTA_PREF_SCHEMA_PREFIX IANJUTA_EDITOR_PREF_SCHEMA);
450 flag = g_settings_get_boolean (settings, IANJUTA_EDITOR_USE_TABS_KEY);
451 g_hash_table_insert (values, USE_TABS_PROPERTY, g_strdup (flag ? "1" : "0"));
453 /* Add tab-width property */
454 i = g_settings_get_int (settings, IANJUTA_EDITOR_TAB_WIDTH_KEY);
455 g_hash_table_insert (values, TAB_WIDTH_PROPERTY, g_strdup_printf("%d", i));
457 /* Add indent-width property */
458 i = g_settings_get_int (settings, IANJUTA_EDITOR_INDENT_WIDTH_KEY);
459 g_hash_table_insert (values, INDENT_WIDTH_PROPERTY, g_strdup_printf("%d", i));
460 g_object_unref (settings);
462 plugin->generator = cg_generator_new (
463 cg_window_get_header_template(plugin->window),
464 cg_window_get_source_template(plugin->window),
465 header_file,
466 source_file);
468 if (cg_generator_run (plugin->generator, values, &error) == FALSE)
470 anjuta_util_dialog_error (
471 GTK_WINDOW (cg_window_get_dialog (plugin->window)),
472 _("Failed to execute autogen: %s"), error->message);
474 g_object_unref (G_OBJECT (plugin->generator));
475 g_error_free (error);
477 else
479 g_signal_connect (G_OBJECT (plugin->generator), "error",
480 G_CALLBACK (cg_plugin_generator_error_cb),
481 plugin);
483 g_signal_connect (G_OBJECT (plugin->generator), "created",
484 G_CALLBACK (cg_plugin_generator_created_cb),
485 plugin);
487 gtk_widget_set_sensitive (
488 GTK_WIDGET (cg_window_get_dialog (plugin->window)), FALSE);
491 g_hash_table_destroy (values);
492 g_free (header_file);
493 g_free (source_file);
496 else
498 g_object_unref (G_OBJECT (plugin->window));
499 plugin->window = NULL;
503 #define PREF_SCHEMA "org.gnome.anjuta"
505 static void
506 iwizard_activate (IAnjutaWizard *wiz, G_GNUC_UNUSED GError **err)
508 /* IAnjutaProjectManager *pm; */
509 AnjutaClassGenPlugin *cg_plugin;
510 gchar *user_name;
511 gchar *user_email;
512 gint caps = 0;
513 gboolean has_project;
515 cg_plugin = ANJUTA_PLUGIN_CLASS_GEN (wiz);
517 if (cg_plugin->window != NULL)
518 g_object_unref (G_OBJECT (cg_plugin->window));
520 cg_plugin->window = cg_window_new ();
522 user_name = g_strdup(g_get_real_name ());
523 /* FIXME: */
524 user_email = anjuta_util_get_user_mail();
526 if (user_name != NULL)
527 cg_window_set_author (cg_plugin->window, user_name);
529 if (user_email != NULL)
530 cg_window_set_email (cg_plugin->window, user_email);
532 g_free(user_name);
533 g_free(user_email);
535 /* Check whether we have a loaded project and it can add sources */
536 if (cg_plugin->top_dir)
538 IAnjutaProjectManager *manager =
539 anjuta_shell_get_interface (ANJUTA_PLUGIN (wiz)->shell,
540 IAnjutaProjectManager, NULL);
541 if (manager)
543 caps = ianjuta_project_manager_get_capabilities (manager, NULL);
544 cg_window_set_project_model (cg_plugin->window, manager);
548 has_project = (caps & ANJUTA_PROJECT_CAN_ADD_SOURCE) ? TRUE : FALSE;
549 cg_window_set_add_to_project (cg_plugin->window, has_project);
550 cg_window_enable_add_to_project (cg_plugin->window, has_project);
552 /* TODO: Check whether the project is in version control, and enable
553 * "add to repository" button respectively. */
555 g_signal_connect (G_OBJECT (cg_window_get_dialog(cg_plugin->window)),
556 "response", G_CALLBACK (cg_plugin_window_response_cb),
557 cg_plugin);
559 gtk_widget_show (GTK_WIDGET (cg_window_get_dialog (cg_plugin->window)));
562 static void
563 iwizard_iface_init (IAnjutaWizardIface *iface)
565 iface->activate = iwizard_activate;
568 ANJUTA_PLUGIN_BEGIN (AnjutaClassGenPlugin, class_gen_plugin);
569 ANJUTA_PLUGIN_ADD_INTERFACE(iwizard, IANJUTA_TYPE_WIZARD);
570 ANJUTA_PLUGIN_END;
572 ANJUTA_SIMPLE_PLUGIN (AnjutaClassGenPlugin, class_gen_plugin);