1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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.
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>
35 /* #include "class_gen.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
;
52 project_root_added (AnjutaPlugin
*plugin
,
53 G_GNUC_UNUSED
const gchar
*name
,
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
);
65 gchar
*root_dir
= anjuta_util_get_local_path_from_uri (root_uri
);
67 cg_plugin
->top_dir
= g_strdup(root_dir
);
69 cg_plugin
->top_dir
= NULL
;
73 cg_plugin
->top_dir
= NULL
;
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
;
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(
107 _("Could not find autogen version 5; please install the "
108 "autogen package. You can get it from "
109 "http://autogen.sourceforge.net."));
114 /* set up project directory watch */
115 cg_plugin
->root_watch_id
= anjuta_plugin_add_watch (plugin
,
116 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
118 project_root_removed
, NULL
);
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 ...");
131 anjuta_plugin_remove_watch (plugin
, cg_plugin
->root_watch_id
, TRUE
);
137 dispose (GObject
*obj
)
139 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
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
);
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
;
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
;
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
,
188 IAnjutaProjectManager
*manager
;
189 GFile
*header
= NULL
;
193 manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
194 IAnjutaProjectManager
, NULL
);
199 source
= ianjuta_project_manager_add_source_quiet (manager
, source_file
,
201 if (header_file
) header
= ianjuta_project_manager_add_source_quiet (manager
, header_file
,
204 result
= source
!= NULL
;
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
214 if (header_file
!= NULL
)
222 *new_header_file
= g_file_get_path(header
);
223 g_object_unref (header
);
232 cg_plugin_add_to_repository (AnjutaClassGenPlugin
*plugin
,
237 vcs
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
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
);
252 cg_plugin_generator_error_cb (G_GNUC_UNUSED CgGenerator
*generator
,
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
);
268 cg_plugin_load (AnjutaClassGenPlugin
*plugin
,
269 CgGenerator
*generator
,
273 IAnjutaDocumentManager
*docman
;
274 IAnjutaEditor
*editor
;
279 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
280 IAnjutaDocumentManager
, NULL
);
282 if(g_file_get_contents(file
, &contents
, NULL
, error
) == FALSE
)
285 name
= g_path_get_basename (file
);
288 /* The content argument seems not to work */
289 editor
= ianjuta_document_manager_add_buffer (docman
, name
, "", error
);
293 ianjuta_editor_append(editor
, contents
, -1, error
);
294 if(!error
|| *error
== NULL
)
305 cg_plugin_generator_created_cb (CgGenerator
*generator
,
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
);
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
);
351 g_signal_emit_by_name (G_OBJECT (manager
), "element_added", source
);
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
);
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
371 cg_plugin_load (plugin
, generator
, source_file
, NULL
);
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
;
385 cg_plugin_window_response_cb (G_GNUC_UNUSED GtkDialog
*dialog
,
389 AnjutaClassGenPlugin
*plugin
;
390 IAnjutaProjectManager
*manager
;
399 plugin
= (AnjutaClassGenPlugin
*) user_data
;
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
,
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
);
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
);
442 name
= g_path_get_basename (cg_window_get_source_file(
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
),
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
);
479 g_signal_connect (G_OBJECT (plugin
->generator
), "error",
480 G_CALLBACK (cg_plugin_generator_error_cb
),
483 g_signal_connect (G_OBJECT (plugin
->generator
), "created",
484 G_CALLBACK (cg_plugin_generator_created_cb
),
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
);
498 g_object_unref (G_OBJECT (plugin
->window
));
499 plugin
->window
= NULL
;
503 #define PREF_SCHEMA "org.gnome.anjuta"
506 iwizard_activate (IAnjutaWizard
*wiz
, G_GNUC_UNUSED GError
**err
)
508 /* IAnjutaProjectManager *pm; */
509 AnjutaClassGenPlugin
*cg_plugin
;
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 ());
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
);
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
);
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
),
559 gtk_widget_show (GTK_WIDGET (cg_window_get_dialog (cg_plugin
->window
)));
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
);
572 ANJUTA_SIMPLE_PLUGIN (AnjutaClassGenPlugin
, class_gen_plugin
);