symbol-db: code cleaning: removed dyn queries.
[anjuta.git] / src / anjuta-app.c
blobe44bf3ad467336e46423ae3f1c34622173bc5f14
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta.c Copyright (C) 2003 Naba Kumar <naba@gnome.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc., 59
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <sys/wait.h>
30 #include <gtk/gtk.h>
32 #include <gdl/gdl.h>
34 #include <libanjuta/anjuta-shell.h>
35 #include <libanjuta/anjuta-ui.h>
36 #include <libanjuta/anjuta-utils.h>
37 #include <libanjuta/resources.h>
38 #include <libanjuta/anjuta-plugin-manager.h>
39 #include <libanjuta/anjuta-debug.h>
41 #include "anjuta-app.h"
42 #include "anjuta-actions.h"
43 #include "about.h"
45 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta.xml"
46 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/preferences.ui"
47 #define ICON_FILE "anjuta-preferences-general-48.png"
49 static void anjuta_app_layout_load (AnjutaApp *app,
50 const gchar *layout_filename,
51 const gchar *name);
52 static void anjuta_app_layout_save (AnjutaApp *app,
53 const gchar *layout_filename,
54 const gchar *name);
56 static gpointer parent_class = NULL;
57 static GtkToolbarStyle style = -1;
59 static void
60 menu_item_select_cb (GtkMenuItem *proxy,
61 AnjutaApp *app)
63 GtkAction *action;
64 char *message;
66 action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (proxy));
67 g_return_if_fail (action != NULL);
69 g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
70 if (message)
72 anjuta_status_push (app->status, "%s", message);
73 g_free (message);
77 static void
78 menu_item_deselect_cb (GtkMenuItem *proxy,
79 AnjutaApp *app)
81 anjuta_status_pop (app->status);
85 static void
86 connect_proxy_cb (GtkUIManager *manager,
87 GtkAction *action,
88 GtkWidget *proxy,
89 AnjutaApp *app)
91 if (GTK_IS_MENU_ITEM (proxy))
93 g_signal_connect (proxy, "select",
94 G_CALLBACK (menu_item_select_cb), app);
95 g_signal_connect (proxy, "deselect",
96 G_CALLBACK (menu_item_deselect_cb), app);
100 static void
101 disconnect_proxy_cb (GtkUIManager *manager,
102 GtkAction *action,
103 GtkWidget *proxy,
104 AnjutaApp *app)
106 if (GTK_IS_MENU_ITEM (proxy))
108 g_signal_handlers_disconnect_by_func
109 (proxy, G_CALLBACK (menu_item_select_cb), app);
110 g_signal_handlers_disconnect_by_func
111 (proxy, G_CALLBACK (menu_item_deselect_cb), app);
115 static void
116 anjuta_app_iconify_dockable_widget (AnjutaShell *shell, GtkWidget *widget,
117 GError **error)
119 AnjutaApp *app = NULL;
120 GtkWidget *dock_item = NULL;
122 /* Argumments assertions */
123 g_return_if_fail (ANJUTA_IS_APP (shell));
124 g_return_if_fail (GTK_IS_WIDGET (widget));
126 app = ANJUTA_APP (shell);
127 g_return_if_fail (app->widgets != NULL);
129 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
130 g_return_if_fail (dock_item != NULL);
132 /* Iconify the dockable item */
133 gdl_dock_item_iconify_item (GDL_DOCK_ITEM (dock_item));
136 static void
137 anjuta_app_hide_dockable_widget (AnjutaShell *shell, GtkWidget *widget,
138 GError **error)
140 AnjutaApp *app = NULL;
141 GtkWidget *dock_item = NULL;
143 /* Argumments assertions */
144 g_return_if_fail (ANJUTA_IS_APP (shell));
145 g_return_if_fail (GTK_IS_WIDGET (widget));
147 app = ANJUTA_APP (shell);
148 g_return_if_fail (app->widgets != NULL);
150 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
151 g_return_if_fail (dock_item != NULL);
153 /* Hide the dockable item */
154 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dock_item));
157 static void
158 anjuta_app_show_dockable_widget (AnjutaShell *shell, GtkWidget* widget,
159 GError **error)
161 AnjutaApp *app = NULL;
162 GtkWidget *dock_item = NULL;
164 /* Argumments assertions */
165 g_return_if_fail (ANJUTA_IS_APP (shell));
166 g_return_if_fail (GTK_IS_WIDGET (widget));
168 app = ANJUTA_APP (shell);
169 g_return_if_fail (app->widgets != NULL);
171 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
172 g_return_if_fail (dock_item != NULL);
174 /* Show the dockable item */
175 gdl_dock_item_show_item(GDL_DOCK_ITEM (dock_item));
178 static void
179 anjuta_app_maximize_widget (AnjutaShell *shell,
180 const char *widget_name,
181 GError **error)
183 AnjutaApp *app = NULL;
184 GtkWidget *dock_item = NULL;
185 gpointer value, key;
186 GtkWidget *widget = NULL;
187 GHashTableIter iter;
189 /* AnjutaApp assertions */
190 g_return_if_fail (ANJUTA_IS_APP (shell));
191 app = ANJUTA_APP (shell);
193 /* If app->maximized is TRUE then another widget is already maximized.
194 Restoring the UI for a new maximization. */
195 if(app->maximized)
196 gdl_dock_layout_load_layout (app->layout_manager, "back-up");
198 /* Back-up the layout so it can be restored */
199 gdl_dock_layout_save_layout(app->layout_manager, "back-up");
201 /* Mark the app as maximized (the other widgets except center are hidden) */
202 app->maximized = TRUE;
204 /* Hide all DockItem's except the ones positioned in the center */
205 g_hash_table_iter_init (&iter, app->widgets);
206 while (g_hash_table_iter_next (&iter, &key, &value))
208 if (value == NULL)
209 continue;
211 /* If it's the widget requesting maximization then continue */
212 if(!g_strcmp0((gchar*)key, widget_name))
213 continue;
215 /* Widget assertions */
216 widget = GTK_WIDGET (value);
217 if(!GTK_IS_WIDGET (widget))
218 continue;
220 /* DockItem assertions */
221 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
222 if(dock_item == NULL || !GDL_IS_DOCK_ITEM (dock_item))
223 continue;
225 /* Hide the item */
226 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dock_item));
230 static void
231 anjuta_app_unmaximize (AnjutaShell *shell,
232 GError **error)
234 AnjutaApp *app = NULL;
236 /* AnjutaApp assertions */
237 g_return_if_fail (ANJUTA_IS_APP (shell));
238 app = ANJUTA_APP (shell);
240 /* If not maximized then the operation doesn't make sence. */
241 g_return_if_fail (app->maximized);
243 /* Load the backed-up layout */
244 gdl_dock_layout_load_layout (app->layout_manager, "back-up");
245 gdl_dock_layout_delete_layout (app->layout_manager, "back-up");
247 /* Un-mark maximized */
248 app->maximized = FALSE;
251 static void
252 on_toolbar_style_changed (AnjutaPreferences* prefs,
253 const gchar* key,
254 const gchar* tb_style,
255 gpointer user_data)
257 AnjutaApp* app = ANJUTA_APP (user_data);
259 if (tb_style)
261 if (strcasecmp (tb_style, "Default") == 0)
262 style = -1;
263 else if (strcasecmp (tb_style, "Both") == 0)
264 style = GTK_TOOLBAR_BOTH;
265 else if (strcasecmp (tb_style, "Horiz") == 0)
266 style = GTK_TOOLBAR_BOTH_HORIZ;
267 else if (strcasecmp (tb_style, "Icons") == 0)
268 style = GTK_TOOLBAR_ICONS;
269 else if (strcasecmp (tb_style, "Text") == 0)
270 style = GTK_TOOLBAR_TEXT;
272 DEBUG_PRINT ("Toolbar style: %s", tb_style);
275 if (style != -1)
277 gtk_toolbar_set_style (GTK_TOOLBAR (app->toolbar), style);
279 else
281 gtk_toolbar_unset_style (GTK_TOOLBAR (app->toolbar));
285 static void
286 on_gdl_style_changed (AnjutaPreferences* prefs,
287 const gchar* key,
288 const gchar* pr_style,
289 gpointer user_data)
291 AnjutaApp* app = ANJUTA_APP (user_data);
292 GdlSwitcherStyle style = GDL_SWITCHER_STYLE_BOTH;
294 if (pr_style)
296 if (strcasecmp (pr_style, "Text") == 0)
297 style = GDL_SWITCHER_STYLE_TEXT;
298 else if (strcasecmp (pr_style, "Icon") == 0)
299 style = GDL_SWITCHER_STYLE_ICON;
300 else if (strcasecmp (pr_style, "Both") == 0)
301 style = GDL_SWITCHER_STYLE_BOTH;
302 else if (strcasecmp (pr_style, "Toolbar") == 0)
303 style = GDL_SWITCHER_STYLE_TOOLBAR;
304 else if (strcasecmp (pr_style, "Tabs") == 0)
305 style = GDL_SWITCHER_STYLE_TABS;
307 DEBUG_PRINT ("Switcher style: %s", pr_style);
309 g_object_set (G_OBJECT(app->layout_manager->master), "switcher-style",
310 style, NULL);
313 static void
314 on_toggle_widget_view (GtkCheckMenuItem *menuitem, GtkWidget *dockitem)
316 gboolean state;
317 state = gtk_check_menu_item_get_active (menuitem);
318 if (state)
319 gdl_dock_item_show_item (GDL_DOCK_ITEM (dockitem));
320 else
321 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dockitem));
324 static void
325 on_update_widget_view_menuitem (gpointer key, gpointer wid, gpointer data)
327 GtkCheckMenuItem *menuitem;
328 GdlDockItem *dockitem;
330 dockitem = g_object_get_data (G_OBJECT (wid), "dockitem");
331 menuitem = g_object_get_data (G_OBJECT (wid), "menuitem");
333 g_signal_handlers_block_by_func (menuitem,
334 G_CALLBACK (on_toggle_widget_view),
335 dockitem);
337 if (GDL_DOCK_OBJECT_ATTACHED (dockitem))
338 gtk_check_menu_item_set_active (menuitem, TRUE);
339 else
340 gtk_check_menu_item_set_active (menuitem, FALSE);
342 g_signal_handlers_unblock_by_func (menuitem,
343 G_CALLBACK (on_toggle_widget_view),
344 dockitem);
347 static void
348 on_layout_dirty_notify (GObject *object, GParamSpec *pspec, gpointer user_data)
350 if (!strcmp (pspec->name, "dirty")) {
351 gboolean dirty;
352 g_object_get (object, "dirty", &dirty, NULL);
353 if (dirty) {
354 /* Update UI toggle buttons */
355 g_hash_table_foreach (ANJUTA_APP (user_data)->widgets,
356 on_update_widget_view_menuitem,
357 NULL);
362 static void
363 on_layout_locked_notify (GdlDockMaster *master, GParamSpec *pspec,
364 AnjutaApp *app)
366 AnjutaUI *ui;
367 GtkAction *action;
368 gint locked;
370 ui = app->ui;
371 action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
372 "ActionViewLockLayout");
374 g_object_get (master, "locked", &locked, NULL);
375 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
376 (locked == 1));
379 static void
380 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
381 AnjutaSession *session, AnjutaApp *app)
383 gchar *geometry, *layout_file;
384 GdkWindowState state;
386 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
387 return;
389 /* Save geometry */
390 state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (app)));
391 if (state & GDK_WINDOW_STATE_MAXIMIZED) {
392 anjuta_session_set_int (session, "Anjuta", "Maximized", 1);
394 if (state & GDK_WINDOW_STATE_FULLSCREEN) {
395 anjuta_session_set_int (session, "Anjuta", "Fullscreen", 1);
398 /* Save geometry only if window is not maximized or fullscreened */
399 if (!(state & GDK_WINDOW_STATE_MAXIMIZED) ||
400 !(state & GDK_WINDOW_STATE_FULLSCREEN))
402 geometry = anjuta_app_get_geometry (app);
403 if (geometry)
404 anjuta_session_set_string (session, "Anjuta", "Geometry",
405 geometry);
406 g_free (geometry);
409 /* Save layout */
410 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
411 "dock-layout.xml", NULL);
412 anjuta_app_layout_save (app, layout_file, NULL);
413 g_free (layout_file);
416 static void
417 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
418 AnjutaSession *session, AnjutaApp *app)
420 /* We load layout at last so that all plugins would have loaded by now */
421 if (phase == ANJUTA_SESSION_PHASE_LAST)
423 gchar *geometry;
424 gchar *layout_file;
426 /* Restore geometry */
427 geometry = anjuta_session_get_string (session, "Anjuta", "Geometry");
428 anjuta_app_set_geometry (app, geometry);
430 /* Restore window state */
431 if (anjuta_session_get_int (session, "Anjuta", "Fullscreen"))
433 /* bug #304495 */
434 AnjutaUI* ui = anjuta_shell_get_ui(shell, NULL);
435 GtkAction* action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
436 "ActionViewFullscreen");
437 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
438 TRUE);
440 gtk_window_fullscreen (GTK_WINDOW (shell));
443 else if (anjuta_session_get_int (session, "Anjuta", "Maximized"))
445 gtk_window_maximize (GTK_WINDOW (shell));
448 /* Restore layout */
449 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
450 "dock-layout.xml", NULL);
451 anjuta_app_layout_load (app, layout_file, NULL);
452 g_free (layout_file);
456 static void
457 anjuta_app_dispose (GObject *widget)
459 AnjutaApp *app;
461 g_return_if_fail (ANJUTA_IS_APP (widget));
463 app = ANJUTA_APP (widget);
465 if (app->widgets)
467 if (g_hash_table_size (app->widgets) > 0)
470 g_warning ("Some widgets are still inside shell (%d widgets), they are:",
471 g_hash_table_size (app->widgets));
472 g_hash_table_foreach (app->widgets, (GHFunc)puts, NULL);
475 g_hash_table_destroy (app->widgets);
476 app->widgets = NULL;
479 if (app->values)
481 if (g_hash_table_size (app->values) > 0)
484 g_warning ("Some Values are still left in shell (%d Values), they are:",
485 g_hash_table_size (app->values));
486 g_hash_table_foreach (app->values, (GHFunc)puts, NULL);
489 g_hash_table_destroy (app->values);
490 app->values = NULL;
493 if (app->layout_manager) {
494 g_object_unref (app->layout_manager);
495 app->layout_manager = NULL;
497 if (app->profile_manager) {
498 g_object_unref (G_OBJECT (app->profile_manager));
499 app->profile_manager = NULL;
501 if (app->plugin_manager) {
502 g_object_unref (G_OBJECT (app->plugin_manager));
503 app->plugin_manager = NULL;
505 if (app->status) {
506 g_object_unref (G_OBJECT (app->status));
507 app->status = NULL;
510 G_OBJECT_CLASS (parent_class)->dispose (widget);
513 static void
514 anjuta_app_finalize (GObject *widget)
516 AnjutaApp *app;
518 g_return_if_fail (ANJUTA_IS_APP (widget));
520 app = ANJUTA_APP (widget);
522 gtk_widget_destroy (GTK_WIDGET (app->ui));
523 gtk_widget_destroy (GTK_WIDGET (app->preferences));
525 G_OBJECT_CLASS (parent_class)->finalize (widget);
528 static void
529 anjuta_app_instance_init (AnjutaApp *app)
531 gint merge_id;
532 GtkWidget *menubar, *about_menu;
533 GtkWidget *view_menu, *hbox;
534 GtkWidget *main_box;
535 GtkWidget *dockbar;
536 GtkAction* action;
537 GList *plugins_dirs = NULL;
538 gchar* style;
539 GdkGeometry size_hints = {
540 100, 100, 0, 0, 100, 100, 1, 1, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
543 DEBUG_PRINT ("%s", "Initializing Anjuta...");
545 gtk_window_set_geometry_hints (GTK_WINDOW (app), GTK_WIDGET (app),
546 &size_hints, GDK_HINT_RESIZE_INC);
547 gtk_window_set_resizable (GTK_WINDOW (app), TRUE);
550 * Main box
552 main_box = gtk_vbox_new (FALSE, 0);
553 gtk_container_add (GTK_CONTAINER (app), main_box);
554 gtk_widget_show (main_box);
556 app->values = NULL;
557 app->widgets = NULL;
558 app->maximized = FALSE;
560 /* Status bar */
561 app->status = ANJUTA_STATUS (anjuta_status_new ());
562 anjuta_status_set_title_window (app->status, GTK_WIDGET (app));
563 gtk_widget_show (GTK_WIDGET (app->status));
564 gtk_box_pack_end (GTK_BOX (main_box),
565 GTK_WIDGET (app->status), FALSE, TRUE, 0);
566 g_object_ref (G_OBJECT (app->status));
567 g_object_add_weak_pointer (G_OBJECT (app->status), (gpointer)&app->status);
569 /* configure dock */
570 hbox = gtk_hbox_new (FALSE, 0);
571 gtk_widget_show (hbox);
572 app->dock = gdl_dock_new ();
573 gtk_widget_show (app->dock);
574 gtk_box_pack_end(GTK_BOX (hbox), app->dock, TRUE, TRUE, 0);
576 dockbar = gdl_dock_bar_new (GDL_DOCK(app->dock));
577 gtk_widget_show (dockbar);
578 gtk_box_pack_start(GTK_BOX (hbox), dockbar, FALSE, FALSE, 0);
580 app->layout_manager = gdl_dock_layout_new (GDL_DOCK (app->dock));
581 g_signal_connect (app->layout_manager, "notify::dirty",
582 G_CALLBACK (on_layout_dirty_notify), app);
583 g_signal_connect (app->layout_manager->master, "notify::locked",
584 G_CALLBACK (on_layout_locked_notify), app);
586 /* UI engine */
587 app->ui = anjuta_ui_new ();
588 g_object_add_weak_pointer (G_OBJECT (app->ui), (gpointer)&app->ui);
589 /* show tooltips in the statusbar */
590 g_signal_connect (app->ui,
591 "connect_proxy",
592 G_CALLBACK (connect_proxy_cb),
593 app);
594 g_signal_connect (app->ui,
595 "disconnect_proxy",
596 G_CALLBACK (disconnect_proxy_cb),
597 app);
599 /* Plugin Manager */
600 plugins_dirs = g_list_prepend (plugins_dirs, PACKAGE_PLUGIN_DIR);
601 app->plugin_manager = anjuta_plugin_manager_new (G_OBJECT (app),
602 app->status,
603 plugins_dirs);
604 app->profile_manager = anjuta_profile_manager_new (app->plugin_manager);
605 g_list_free (plugins_dirs);
607 /* Preferences */
608 app->preferences = anjuta_preferences_new (app->plugin_manager);
609 g_object_add_weak_pointer (G_OBJECT (app->preferences),
610 (gpointer)&app->preferences);
612 anjuta_preferences_notify_add_string (app->preferences, "anjuta.gdl.style",
613 on_gdl_style_changed, app, NULL);
614 style = anjuta_preferences_get (app->preferences, "anjuta.gdl.style");
616 on_gdl_style_changed (app->preferences, NULL,
617 style, app);
618 g_free (style);
620 /* Register actions */
621 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupFile", _("File"),
622 menu_entries_file,
623 G_N_ELEMENTS (menu_entries_file),
624 GETTEXT_PACKAGE, TRUE, app);
625 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupEdit", _("Edit"),
626 menu_entries_edit,
627 G_N_ELEMENTS (menu_entries_edit),
628 GETTEXT_PACKAGE, TRUE, app);
629 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupView", _("View"),
630 menu_entries_view,
631 G_N_ELEMENTS (menu_entries_view),
632 GETTEXT_PACKAGE, TRUE, app);
633 anjuta_ui_add_toggle_action_group_entries (app->ui, "ActionGroupToggleView",
634 _("View"),
635 menu_entries_toggle_view,
636 G_N_ELEMENTS (menu_entries_toggle_view),
637 GETTEXT_PACKAGE, TRUE, app);
638 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupHelp", _("Help"),
639 menu_entries_help,
640 G_N_ELEMENTS (menu_entries_help),
641 GETTEXT_PACKAGE, TRUE, app);
643 /* Merge UI */
644 merge_id = anjuta_ui_merge (app->ui, UI_FILE);
646 /* Adding accels group */
647 gtk_window_add_accel_group (GTK_WINDOW (app),
648 gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (app->ui)));
650 /* create main menu */
651 menubar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (app->ui),
652 "/MenuMain");
653 gtk_box_pack_start (GTK_BOX (main_box), menubar, FALSE, FALSE, 0);
654 gtk_widget_show (menubar);
656 /* create toolbar */
657 app->toolbar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (app->ui),
658 "/ToolbarMain");
659 if (!anjuta_preferences_get_bool (app->preferences, "anjuta.toolbar.visible"))
660 gtk_widget_hide (app->toolbar);
661 gtk_box_pack_start (GTK_BOX (main_box), app->toolbar, FALSE, FALSE, 0);
662 action = gtk_ui_manager_get_action (GTK_UI_MANAGER (app->ui),
663 "/MenuMain/MenuView/Toolbar");
664 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action),
665 anjuta_preferences_get_bool_with_default (app->preferences,
666 "anjuta.toolbar.visible",
667 TRUE));
668 anjuta_preferences_notify_add_string (app->preferences, "anjuta.toolbar.style",
669 on_toolbar_style_changed, app, NULL);
670 style = anjuta_preferences_get (app->preferences, "anjuta.toolbar.style");
671 on_toolbar_style_changed (app->preferences, NULL, style, app);
672 g_free (style);
674 /* Create widgets menu */
675 view_menu =
676 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
677 "/MenuMain/MenuView");
678 app->view_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (view_menu));
680 /* Disable unavailible tutorials */
681 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpTutorial");
682 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
683 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpAdvancedTutorial");
684 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
686 /* Create about plugins menu */
687 about_menu =
688 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
689 "/MenuMain/PlaceHolderHelpMenus/MenuHelp/"
690 "PlaceHolderHelpAbout/AboutPlugins");
691 about_create_plugins_submenu (ANJUTA_SHELL (app), about_menu);
693 /* Add main view */
694 gtk_box_pack_start (GTK_BOX (main_box), hbox, TRUE, TRUE, 0);
696 /* Connect to session */
697 g_signal_connect (G_OBJECT (app), "save_session",
698 G_CALLBACK (on_session_save), app);
699 g_signal_connect (G_OBJECT (app), "load_session",
700 G_CALLBACK (on_session_load), app);
702 /* Loading accels */
703 anjuta_ui_load_accels (NULL);
705 app->save_count = 0;
709 * GtkWindow catches keybindings for the menu items _before_ passing them to
710 * the focused widget. This is unfortunate and means that pressing ctrl+V
711 * in an entry on a panel ends up pasting text in the TextView.
712 * Here we override GtkWindow's handler to do the same things that it
713 * does, but in the opposite order and then we chain up to the grand
714 * parent handler, skipping gtk_window_key_press_event.
716 static gboolean
717 anjuta_app_key_press_event (GtkWidget *widget,
718 GdkEventKey *event)
720 static gpointer grand_parent_class = NULL;
721 GtkWindow *window = GTK_WINDOW (widget);
722 gboolean handled = FALSE;
724 if (grand_parent_class == NULL)
725 grand_parent_class = g_type_class_peek_parent (parent_class);
727 /* handle focus widget key events */
728 if (!handled)
729 handled = gtk_window_propagate_key_event (window, event);
731 /* handle mnemonics and accelerators */
732 if (!handled)
733 handled = gtk_window_activate_key (window, event);
735 /* Chain up, invokes binding set */
736 if (!handled)
737 handled = GTK_WIDGET_CLASS (grand_parent_class)->key_press_event (widget, event);
739 return handled;
742 static void
743 anjuta_app_class_init (AnjutaAppClass *class)
745 GObjectClass *object_class;
746 GtkWidgetClass *widget_class;
748 parent_class = g_type_class_peek_parent (class);
749 object_class = (GObjectClass*) class;
750 widget_class = (GtkWidgetClass*) class;
752 object_class->finalize = anjuta_app_finalize;
753 object_class->dispose = anjuta_app_dispose;
755 widget_class->key_press_event = anjuta_app_key_press_event;
758 GtkWidget *
759 anjuta_app_new (void)
761 AnjutaApp *app;
763 app = ANJUTA_APP (g_object_new (ANJUTA_TYPE_APP,
764 "title", "Anjuta",
765 NULL));
766 return GTK_WIDGET (app);
769 gchar*
770 anjuta_app_get_geometry (AnjutaApp *app)
772 gchar *geometry;
773 gint width, height, posx, posy;
775 g_return_val_if_fail (ANJUTA_IS_APP (app), NULL);
777 geometry = NULL;
778 width = height = posx = posy = 0;
779 if (gtk_widget_get_window (GTK_WIDGET (app)))
781 gtk_window_get_size (GTK_WINDOW (app), &width, &height);
782 gtk_window_get_position (GTK_WINDOW(app), &posx, &posy);
784 geometry = g_strdup_printf ("%dx%d+%d+%d", width, height, posx, posy);
786 return geometry;
789 void
790 anjuta_app_set_geometry (AnjutaApp *app, const gchar *geometry)
792 gint width, height, posx, posy;
793 gboolean geometry_set = FALSE;
795 if (geometry && strlen (geometry) > 0)
797 DEBUG_PRINT ("Setting geometry: %s", geometry);
799 if (sscanf (geometry, "%dx%d+%d+%d", &width, &height,
800 &posx, &posy) == 4)
802 if (gtk_widget_get_realized (GTK_WIDGET (app)))
804 gtk_window_resize (GTK_WINDOW (app), width, height);
806 else
808 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
809 gtk_window_move (GTK_WINDOW (app), posx, posy);
811 geometry_set = TRUE;
813 else
815 g_warning ("Failed to parse geometry: %s", geometry);
818 if (!geometry_set)
820 posx = 10;
821 posy = 10;
822 width = gdk_screen_width () - 10;
823 height = gdk_screen_height () - 25;
824 width = (width < 790)? width : 790;
825 height = (height < 575)? width : 575;
826 if (gtk_widget_get_realized (GTK_WIDGET (app)) == FALSE)
828 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
829 gtk_window_move (GTK_WINDOW (app), posx, posy);
834 static void
835 anjuta_app_layout_save (AnjutaApp *app, const gchar *filename,
836 const gchar *name)
838 g_return_if_fail (ANJUTA_IS_APP (app));
839 g_return_if_fail (filename != NULL);
841 /* If maximized, the layout should be loaded from the back-up first */
842 if(app->maximized)
843 gdl_dock_layout_load_layout (app->layout_manager, "back-up");
845 /* Continue with the saving */
846 gdl_dock_layout_save_layout (app->layout_manager, name);
847 if (!gdl_dock_layout_save_to_file (app->layout_manager, filename))
848 g_warning ("Saving dock layout to '%s' failed!", filename);
850 /* This is a good place to save the accels too */
851 anjuta_ui_save_accels (NULL);
854 static void
855 anjuta_app_layout_load (AnjutaApp *app, const gchar *layout_filename,
856 const gchar *name)
858 g_return_if_fail (ANJUTA_IS_APP (app));
860 if (!layout_filename ||
861 !gdl_dock_layout_load_from_file (app->layout_manager, layout_filename))
863 gchar *datadir, *filename;
864 datadir = anjuta_res_get_data_dir();
866 filename = g_build_filename (datadir, "layout.xml", NULL);
867 DEBUG_PRINT ("Layout = %s", filename);
868 g_free (datadir);
869 if (!gdl_dock_layout_load_from_file (app->layout_manager, filename))
870 g_warning ("Loading layout from '%s' failed!!", filename);
871 g_free (filename);
874 if (!gdl_dock_layout_load_layout (app->layout_manager, name))
875 g_warning ("Loading layout failed!!");
878 void
879 anjuta_app_layout_reset (AnjutaApp *app)
881 anjuta_app_layout_load (app, NULL, NULL);
884 void
885 anjuta_app_install_preferences (AnjutaApp *app)
887 GtkBuilder* builder = gtk_builder_new ();
888 GError* error = NULL;
889 GtkWidget *notebook, *shortcuts, *plugins, *remember_plugins;
891 /* Create preferences page */
892 gtk_builder_add_from_file (builder, GLADE_FILE, &error);
893 if (error)
895 g_warning("Could not load general preferences: %s",
896 error->message);
897 g_error_free (error);
898 return;
900 anjuta_preferences_add_from_builder (app->preferences, builder,
901 "General", _("General"), ICON_FILE);
902 notebook = GTK_WIDGET (gtk_builder_get_object (builder, "General"));
903 shortcuts = anjuta_ui_get_accel_editor (ANJUTA_UI (app->ui));
904 plugins = anjuta_plugin_manager_get_plugins_page (app->plugin_manager);
905 remember_plugins = anjuta_plugin_manager_get_remembered_plugins_page (app->plugin_manager);
907 gtk_widget_show (shortcuts);
908 gtk_widget_show (plugins);
909 gtk_widget_show (remember_plugins);
911 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), plugins,
912 gtk_label_new (_("Installed plugins")));
913 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), remember_plugins,
914 gtk_label_new (_("Preferred plugins")));
915 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), shortcuts,
916 gtk_label_new (_("Shortcuts")));
918 g_object_unref (builder);
921 /* AnjutaShell Implementation */
923 static void
924 on_value_removed_from_hash (gpointer value)
926 g_value_unset ((GValue*)value);
927 g_free (value);
930 static void
931 anjuta_app_add_value (AnjutaShell *shell, const char *name,
932 const GValue *value, GError **error)
934 GValue *copy;
935 AnjutaApp *app;
937 g_return_if_fail (ANJUTA_IS_APP (shell));
938 g_return_if_fail (name != NULL);
939 g_return_if_fail (G_IS_VALUE(value));
941 app = ANJUTA_APP (shell);
943 if (app->values == NULL)
945 app->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
946 on_value_removed_from_hash);
948 anjuta_shell_remove_value (shell, name, error);
950 copy = g_new0 (GValue, 1);
951 g_value_init (copy, value->g_type);
952 g_value_copy (value, copy);
954 g_hash_table_insert (app->values, g_strdup (name), copy);
955 g_signal_emit_by_name (shell, "value_added", name, copy);
958 static void
959 anjuta_app_get_value (AnjutaShell *shell, const char *name, GValue *value,
960 GError **error)
962 GValue *val;
963 AnjutaApp *app;
965 g_return_if_fail (ANJUTA_IS_APP (shell));
966 g_return_if_fail (name != NULL);
967 /* g_return_if_fail (G_IS_VALUE (value)); */
969 app = ANJUTA_APP (shell);
971 val = NULL;
972 if (app->values)
973 val = g_hash_table_lookup (app->values, name);
974 if (val)
976 if (!value->g_type)
978 g_value_init (value, val->g_type);
980 g_value_copy (val, value);
982 else
984 if (error)
986 *error = g_error_new (ANJUTA_SHELL_ERROR,
987 ANJUTA_SHELL_ERROR_DOESNT_EXIST,
988 _("Value doesn't exist"));
993 static void
994 anjuta_app_remove_value (AnjutaShell *shell, const char *name, GError **error)
996 AnjutaApp *app;
997 GValue *value;
998 char *key;
1000 g_return_if_fail (ANJUTA_IS_APP (shell));
1001 g_return_if_fail (name != NULL);
1003 app = ANJUTA_APP (shell);
1006 g_return_if_fail (app->values != NULL);
1007 if (app->widgets && g_hash_table_lookup_extended (app->widgets, name,
1008 (gpointer*)&key,
1009 (gpointer*)&w)) {
1010 GtkWidget *item;
1011 item = g_object_get_data (G_OBJECT (w), "dockitem");
1012 gdl_dock_item_hide_item (GDL_DOCK_ITEM (item));
1013 gdl_dock_object_unbind (GDL_DOCK_OBJECT (item));
1014 g_free (key);
1018 if (app->values && g_hash_table_lookup_extended (app->values, name,
1019 (gpointer)&key,
1020 (gpointer)&value)) {
1021 g_signal_emit_by_name (app, "value_removed", name);
1022 g_hash_table_remove (app->values, name);
1026 static void
1027 anjuta_app_saving_push (AnjutaShell* shell)
1029 AnjutaApp* app = ANJUTA_APP (shell);
1030 app->save_count++;
1033 static void
1034 anjuta_app_saving_pop (AnjutaShell* shell)
1036 AnjutaApp* app = ANJUTA_APP (shell);
1037 app->save_count--;
1040 static gboolean
1041 remove_from_widgets_hash (gpointer name, gpointer hash_widget, gpointer widget)
1043 if (hash_widget == widget)
1044 return TRUE;
1045 return FALSE;
1048 static void
1049 on_widget_destroy (GtkWidget *widget, AnjutaApp *app)
1051 DEBUG_PRINT ("%s", "Widget about to be destroyed");
1052 g_hash_table_foreach_remove (app->widgets, remove_from_widgets_hash,
1053 widget);
1056 static void
1057 on_widget_remove (GtkWidget *container, GtkWidget *widget, AnjutaApp *app)
1059 GtkWidget *dock_item;
1061 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1062 if (dock_item)
1064 gchar* unique_name = g_object_get_data(G_OBJECT(dock_item), "unique_name");
1065 g_free(unique_name);
1066 g_signal_handlers_disconnect_by_func (G_OBJECT (dock_item),
1067 G_CALLBACK (on_widget_remove), app);
1068 gdl_dock_item_unbind (GDL_DOCK_ITEM(dock_item));
1070 if (g_hash_table_foreach_remove (app->widgets,
1071 remove_from_widgets_hash,
1072 widget)){
1073 DEBUG_PRINT ("%s", "Widget removed from container");
1077 static void
1078 on_widget_removed_from_hash (gpointer widget)
1080 AnjutaApp *app;
1081 GtkWidget *menuitem;
1082 GdlDockItem *dockitem;
1084 DEBUG_PRINT ("%s", "Removing widget from hash");
1086 app = g_object_get_data (G_OBJECT (widget), "app-object");
1087 dockitem = g_object_get_data (G_OBJECT (widget), "dockitem");
1088 menuitem = g_object_get_data (G_OBJECT (widget), "menuitem");
1090 gtk_widget_destroy (menuitem);
1092 g_object_set_data (G_OBJECT (widget), "dockitem", NULL);
1093 g_object_set_data (G_OBJECT (widget), "menuitem", NULL);
1095 g_signal_handlers_disconnect_by_func (G_OBJECT (widget),
1096 G_CALLBACK (on_widget_destroy), app);
1097 g_signal_handlers_disconnect_by_func (G_OBJECT (dockitem),
1098 G_CALLBACK (on_widget_remove), app);
1100 g_object_unref (G_OBJECT (widget));
1103 static void
1104 anjuta_app_setup_widget (AnjutaApp* app,
1105 const gchar* name,
1106 GtkWidget *widget,
1107 GtkWidget* item,
1108 const gchar* title,
1109 gboolean locked)
1111 GtkCheckMenuItem* menuitem;
1113 /* Add the widget to hash */
1114 if (app->widgets == NULL)
1116 app->widgets = g_hash_table_new_full (g_str_hash, g_str_equal,
1117 g_free,
1118 on_widget_removed_from_hash);
1120 g_hash_table_insert (app->widgets, g_strdup (name), widget);
1121 g_object_ref (widget);
1123 /* Add toggle button for the widget */
1124 menuitem = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (title));
1125 gtk_widget_show (GTK_WIDGET (menuitem));
1126 gtk_check_menu_item_set_active (menuitem, TRUE);
1127 gtk_menu_shell_append (GTK_MENU_SHELL (app->view_menu), GTK_WIDGET (menuitem));
1129 if (locked)
1130 g_object_set( G_OBJECT(menuitem), "visible", FALSE, NULL);
1133 g_object_set_data (G_OBJECT (widget), "app-object", app);
1134 g_object_set_data (G_OBJECT (widget), "menuitem", menuitem);
1135 g_object_set_data (G_OBJECT (widget), "dockitem", item);
1137 /* For toggling widget view on/off */
1138 g_signal_connect (G_OBJECT (menuitem), "toggled",
1139 G_CALLBACK (on_toggle_widget_view), item);
1142 Watch for widget removal/destruction so that it could be
1143 removed from widgets hash.
1145 g_signal_connect (G_OBJECT (item), "remove",
1146 G_CALLBACK (on_widget_remove), app);
1147 g_signal_connect_after (G_OBJECT (widget), "destroy",
1148 G_CALLBACK (on_widget_destroy), app);
1150 gtk_widget_show_all (item);
1154 static void
1155 anjuta_app_add_widget_full (AnjutaShell *shell,
1156 GtkWidget *widget,
1157 const char *name,
1158 const char *title,
1159 const char *stock_id,
1160 AnjutaShellPlacement placement,
1161 gboolean locked,
1162 GError **error)
1164 AnjutaApp *app;
1165 GtkWidget *item;
1167 g_return_if_fail (ANJUTA_IS_APP (shell));
1168 g_return_if_fail (GTK_IS_WIDGET (widget));
1169 g_return_if_fail (name != NULL);
1170 g_return_if_fail (title != NULL);
1172 app = ANJUTA_APP (shell);
1174 /* Add the widget to dock */
1175 if (stock_id == NULL)
1176 item = gdl_dock_item_new (name, title, GDL_DOCK_ITEM_BEH_NORMAL);
1177 else
1178 item = gdl_dock_item_new_with_stock (name, title, stock_id,
1179 GDL_DOCK_ITEM_BEH_NORMAL);
1180 if (locked)
1182 guint flags = 0;
1183 flags |= GDL_DOCK_ITEM_BEH_NEVER_FLOATING;
1184 flags |= GDL_DOCK_ITEM_BEH_CANT_CLOSE;
1185 flags |= GDL_DOCK_ITEM_BEH_CANT_ICONIFY;
1186 flags |= GDL_DOCK_ITEM_BEH_NO_GRIP;
1187 g_object_set(G_OBJECT(item), "behavior", flags, NULL);
1190 gtk_container_add (GTK_CONTAINER (item), widget);
1191 gdl_dock_add_item (GDL_DOCK (app->dock),
1192 GDL_DOCK_ITEM (item), placement);
1194 if (locked)
1195 gdl_dock_item_set_default_position(GDL_DOCK_ITEM(item), GDL_DOCK_OBJECT(app->dock));
1197 anjuta_app_setup_widget (app, name, widget, item, title, locked);
1200 static void
1201 anjuta_app_add_widget_custom (AnjutaShell *shell,
1202 GtkWidget *widget,
1203 const char *name,
1204 const char *title,
1205 const char *stock_id,
1206 GtkWidget *label,
1207 AnjutaShellPlacement placement,
1208 GError **error)
1210 AnjutaApp *app;
1211 GtkWidget *item;
1212 GtkWidget *grip;
1214 g_return_if_fail (ANJUTA_IS_APP (shell));
1215 g_return_if_fail (GTK_IS_WIDGET (widget));
1216 g_return_if_fail (name != NULL);
1217 g_return_if_fail (title != NULL);
1219 app = ANJUTA_APP (shell);
1221 /* Add the widget to dock */
1222 /* Add the widget to dock */
1223 if (stock_id == NULL)
1224 item = gdl_dock_item_new (name, title, GDL_DOCK_ITEM_BEH_NORMAL);
1225 else
1226 item = gdl_dock_item_new_with_stock (name, title, stock_id,
1227 GDL_DOCK_ITEM_BEH_NORMAL);
1229 gtk_container_add (GTK_CONTAINER (item), widget);
1230 gdl_dock_add_item (GDL_DOCK (app->dock),
1231 GDL_DOCK_ITEM (item), placement);
1233 grip = gdl_dock_item_get_grip (GDL_DOCK_ITEM (item));
1235 gdl_dock_item_grip_set_label (GDL_DOCK_ITEM_GRIP (grip), label);
1237 anjuta_app_setup_widget (app, name, widget, item, title, FALSE);
1240 static void
1241 anjuta_app_remove_widget (AnjutaShell *shell, GtkWidget *widget,
1242 GError **error)
1244 AnjutaApp *app;
1245 GtkWidget *dock_item;
1247 g_return_if_fail (ANJUTA_IS_APP (shell));
1248 g_return_if_fail (GTK_IS_WIDGET (widget));
1250 app = ANJUTA_APP (shell);
1252 g_return_if_fail (app->widgets != NULL);
1254 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1255 g_return_if_fail (dock_item != NULL);
1257 /* Remove the widget from container */
1258 g_object_ref (widget);
1259 /* It should call on_widget_remove() and clean up should happen */
1260 gtk_container_remove (GTK_CONTAINER (dock_item), widget);
1261 g_object_unref (widget);
1264 static void
1265 anjuta_app_present_widget (AnjutaShell *shell, GtkWidget *widget,
1266 GError **error)
1268 AnjutaApp *app;
1269 GdlDockItem *dock_item;
1270 GtkWidget *parent;
1272 g_return_if_fail (ANJUTA_IS_APP (shell));
1273 g_return_if_fail (GTK_IS_WIDGET (widget));
1275 app = ANJUTA_APP (shell);
1277 g_return_if_fail (app->widgets != NULL);
1279 dock_item = g_object_get_data (G_OBJECT(widget), "dockitem");
1280 g_return_if_fail (dock_item != NULL);
1282 /* Hack to present the dock item if it's in a notebook dock item */
1283 parent = gtk_widget_get_parent (GTK_WIDGET(dock_item) );
1284 if (GTK_IS_NOTEBOOK (parent))
1286 gint pagenum;
1287 pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (parent), GTK_WIDGET (dock_item));
1288 gtk_notebook_set_current_page (GTK_NOTEBOOK (parent), pagenum);
1290 else if (!GDL_DOCK_OBJECT_ATTACHED (dock_item))
1292 gdl_dock_item_show_item (GDL_DOCK_ITEM (dock_item));
1295 /* FIXME: If the item is floating, present the window */
1296 /* FIXME: There is no way to detect if a widget was floating before it was
1297 detached since it no longer has a parent there is no way to access the
1298 floating property of the GdlDock structure.*/
1301 static GObject*
1302 anjuta_app_get_object (AnjutaShell *shell, const char *iface_name,
1303 GError **error)
1305 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1306 g_return_val_if_fail (iface_name != NULL, NULL);
1307 return anjuta_plugin_manager_get_plugin (ANJUTA_APP (shell)->plugin_manager,
1308 iface_name);
1311 static AnjutaStatus*
1312 anjuta_app_get_status (AnjutaShell *shell, GError **error)
1314 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1315 return ANJUTA_APP (shell)->status;
1318 static AnjutaUI *
1319 anjuta_app_get_ui (AnjutaShell *shell, GError **error)
1321 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1322 return ANJUTA_APP (shell)->ui;
1325 static AnjutaPreferences *
1326 anjuta_app_get_preferences (AnjutaShell *shell, GError **error)
1328 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1329 return ANJUTA_APP (shell)->preferences;
1332 static AnjutaPluginManager *
1333 anjuta_app_get_plugin_manager (AnjutaShell *shell, GError **error)
1335 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1336 return ANJUTA_APP (shell)->plugin_manager;
1339 static AnjutaProfileManager *
1340 anjuta_app_get_profile_manager (AnjutaShell *shell, GError **error)
1342 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1343 return ANJUTA_APP (shell)->profile_manager;
1346 static void
1347 anjuta_shell_iface_init (AnjutaShellIface *iface)
1349 iface->add_widget_full = anjuta_app_add_widget_full;
1350 iface->add_widget_custom = anjuta_app_add_widget_custom;
1351 iface->remove_widget = anjuta_app_remove_widget;
1352 iface->present_widget = anjuta_app_present_widget;
1353 iface->iconify_dockable_widget = anjuta_app_iconify_dockable_widget;
1354 iface->hide_dockable_widget = anjuta_app_hide_dockable_widget;
1355 iface->show_dockable_widget = anjuta_app_show_dockable_widget;
1356 iface->maximize_widget = anjuta_app_maximize_widget;
1357 iface->unmaximize = anjuta_app_unmaximize;
1358 iface->add_value = anjuta_app_add_value;
1359 iface->get_value = anjuta_app_get_value;
1360 iface->remove_value = anjuta_app_remove_value;
1361 iface->get_object = anjuta_app_get_object;
1362 iface->get_status = anjuta_app_get_status;
1363 iface->get_ui = anjuta_app_get_ui;
1364 iface->get_preferences = anjuta_app_get_preferences;
1365 iface->get_plugin_manager = anjuta_app_get_plugin_manager;
1366 iface->get_profile_manager = anjuta_app_get_profile_manager;
1367 iface->saving_push = anjuta_app_saving_push;
1368 iface->saving_pop = anjuta_app_saving_pop;
1371 ANJUTA_TYPE_BEGIN(AnjutaApp, anjuta_app, GTK_TYPE_WINDOW);
1372 ANJUTA_TYPE_ADD_INTERFACE(anjuta_shell, ANJUTA_TYPE_SHELL);
1373 ANJUTA_TYPE_END;