Put all of the UI utility functions into the "git" namespace.
[anjuta-git-plugin.git] / src / anjuta-app.c
blobe86f263322cf2a27de1a39f6617b3eefae2f8e9b
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 <glade/glade-xml.h>
31 #include <gtk/gtkwidget.h>
32 #include <gtk/gtkwindow.h>
34 #include <gdl/gdl-dock.h>
35 #include <gdl/gdl-dock-bar.h>
36 #include <gdl/gdl-switcher.h>
38 #include <bonobo/bonobo-dock-item.h>
40 #include <libanjuta/anjuta-shell.h>
41 #include <libanjuta/anjuta-ui.h>
42 #include <libanjuta/anjuta-utils.h>
43 #include <libanjuta/resources.h>
44 #include <libanjuta/anjuta-plugin-manager.h>
45 #include <libanjuta/anjuta-debug.h>
47 #include "anjuta-app.h"
48 #include "anjuta-actions.h"
49 #include "about.h"
51 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta.ui"
52 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta.glade"
53 #define ICON_FILE "anjuta-preferences-general-48.png"
55 static void anjuta_app_layout_load (AnjutaApp *app,
56 const gchar *layout_filename,
57 const gchar *name);
58 static void anjuta_app_layout_save (AnjutaApp *app,
59 const gchar *layout_filename,
60 const gchar *name);
62 static gpointer parent_class = NULL;
63 static GList* toolbars = NULL;
64 static GtkToolbarStyle style = -1;
66 static void
67 on_toolbar_style_changed (GConfClient* client, guint id, GConfEntry* entry,
68 gpointer user_data)
70 AnjutaApp* app = ANJUTA_APP (user_data);
71 GList *node = toolbars;
73 char* tb_style = anjuta_preferences_get (app->preferences, "anjuta.toolbar.style");
75 if (tb_style)
77 if (strcasecmp (tb_style, "Default") == 0)
78 style = -1;
79 else if (strcasecmp (tb_style, "Both") == 0)
80 style = GTK_TOOLBAR_BOTH;
81 else if (strcasecmp (tb_style, "Horiz") == 0)
82 style = GTK_TOOLBAR_BOTH_HORIZ;
83 else if (strcasecmp (tb_style, "Icons") == 0)
84 style = GTK_TOOLBAR_ICONS;
85 else if (strcasecmp (tb_style, "Text") == 0)
86 style = GTK_TOOLBAR_TEXT;
88 DEBUG_PRINT ("Toolbar style: %s", tb_style);
90 g_free(tb_style);
93 if (style != -1)
95 while (node)
97 gtk_toolbar_set_style (GTK_TOOLBAR (node->data), style);
98 node = node->next;
101 else
103 while (node)
105 gtk_toolbar_unset_style (GTK_TOOLBAR (node->data));
106 node = node->next;
111 static void
112 on_gdl_style_changed (GConfClient* client, guint id, GConfEntry* entry,
113 gpointer user_data)
115 AnjutaApp* app = ANJUTA_APP (user_data);
116 GdlSwitcherStyle style = GDL_SWITCHER_STYLE_BOTH;
118 gchar* pr_style = anjuta_preferences_get (app->preferences, "anjuta.gdl.style");
120 if (pr_style)
122 if (strcasecmp (pr_style, "Text") == 0)
123 style = GDL_SWITCHER_STYLE_TEXT;
124 else if (strcasecmp (pr_style, "Icon") == 0)
125 style = GDL_SWITCHER_STYLE_ICON;
126 else if (strcasecmp (pr_style, "Both") == 0)
127 style = GDL_SWITCHER_STYLE_BOTH;
128 else if (strcasecmp (pr_style, "Toolbar") == 0)
129 style = GDL_SWITCHER_STYLE_TOOLBAR;
130 else if (strcasecmp (pr_style, "Tabs") == 0)
131 style = GDL_SWITCHER_STYLE_TABS;
133 DEBUG_PRINT ("Switcher style: %s", pr_style);
135 g_free (pr_style);
137 g_object_set (G_OBJECT(app->layout_manager->master), "switcher-style",
138 style, NULL);
141 static void
142 on_toggle_widget_view (GtkCheckMenuItem *menuitem, GtkWidget *dockitem)
144 gboolean state;
145 state = gtk_check_menu_item_get_active (menuitem);
146 if (state)
147 gdl_dock_item_show_item (GDL_DOCK_ITEM (dockitem));
148 else
149 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dockitem));
152 static void
153 on_update_widget_view_menuitem (gpointer key, gpointer wid, gpointer data)
155 GtkCheckMenuItem *menuitem;
156 GdlDockItem *dockitem;
158 dockitem = g_object_get_data (G_OBJECT (wid), "dockitem");
159 menuitem = g_object_get_data (G_OBJECT (wid), "menuitem");
161 g_signal_handlers_block_by_func (menuitem,
162 G_CALLBACK (on_toggle_widget_view),
163 dockitem);
165 if (GDL_DOCK_OBJECT_ATTACHED (dockitem))
166 gtk_check_menu_item_set_active (menuitem, TRUE);
167 else
168 gtk_check_menu_item_set_active (menuitem, FALSE);
170 g_signal_handlers_unblock_by_func (menuitem,
171 G_CALLBACK (on_toggle_widget_view),
172 dockitem);
175 static void
176 on_layout_dirty_notify (GObject *object, GParamSpec *pspec, gpointer user_data)
178 if (!strcmp (pspec->name, "dirty")) {
179 gboolean dirty;
180 g_object_get (object, "dirty", &dirty, NULL);
181 if (dirty) {
182 /* Update UI toggle buttons */
183 g_hash_table_foreach (ANJUTA_APP (user_data)->widgets,
184 on_update_widget_view_menuitem,
185 NULL);
190 static void
191 on_layout_locked_notify (GdlDockMaster *master, GParamSpec *pspec,
192 AnjutaApp *app)
194 AnjutaUI *ui;
195 GtkAction *action;
196 gint locked;
198 ui = app->ui;
199 action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
200 "ActionViewLockLayout");
202 g_object_get (master, "locked", &locked, NULL);
203 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
204 (locked == 1));
207 static void
208 layout_changed (GtkWidget *w, AnjutaApp *app)
210 BonoboDockLayout *layout;
211 gchar *s;
213 g_return_if_fail (ANJUTA_IS_APP (app));
214 g_return_if_fail (BONOBO_IS_DOCK (w));
216 layout = bonobo_dock_get_layout (BONOBO_DOCK (app->bonobo_dock));
217 s = bonobo_dock_layout_create_string (layout);
218 anjuta_preferences_set (app->preferences, "anjuta.bonobo.layout", s);
219 g_object_unref (G_OBJECT (layout));
220 g_free (s);
223 static void
224 anjuta_app_add_dock_item (AnjutaApp *app, BonoboDockItem *item,
225 BonoboDockPlacement placement, gint band_num,
226 gint band_position, gint offset)
228 if (app->bonobo_layout)
229 bonobo_dock_layout_add_item (app->bonobo_layout,
230 BONOBO_DOCK_ITEM (item),
231 placement, band_num, band_position,
232 offset);
233 else
234 bonobo_dock_add_item (BONOBO_DOCK(app->bonobo_dock),
235 BONOBO_DOCK_ITEM( item),
236 placement, band_num, band_position, offset, FALSE);
238 g_signal_emit_by_name (app->bonobo_dock, "layout_changed", app);
242 static void
243 on_toolbar_view_toggled (GtkCheckMenuItem *menuitem, GtkWidget *widget)
245 AnjutaApp *app;
246 GtkWidget *dock_item;
247 const gchar *name;
248 gint band;
249 gint position;
250 gint offset;
253 name = gtk_widget_get_name (widget);
254 app = g_object_get_data (G_OBJECT(widget), "app");
255 dock_item = g_object_get_data (G_OBJECT(widget), "dock_item");
256 band = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "band"));
257 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "position"));
258 offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "offset"));
261 if (gtk_check_menu_item_get_active (menuitem))
263 if (!dock_item)
265 static gint count;
266 gchar *unique_name = g_strdup_printf ("%s-%d", name, count);
268 DEBUG_PRINT ("Adding dock item %s band %d, offset %d, position %d",
269 unique_name, band, offset, position);
271 dock_item = bonobo_dock_item_new (unique_name,
272 BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL |
273 BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING);
275 gtk_container_add (GTK_CONTAINER (dock_item), widget);
277 /* Widget not yet added to the dock. Add it */
278 anjuta_app_add_dock_item (app, BONOBO_DOCK_ITEM (dock_item),
279 BONOBO_DOCK_TOP, band, position, offset);
281 g_object_set_data_full (G_OBJECT(dock_item), "unique_name",
282 unique_name, g_free);
283 g_object_set_data (G_OBJECT(widget), "dock_item", dock_item);
284 count++;
286 gtk_widget_show (dock_item);
287 gtk_widget_show (GTK_BIN (dock_item)->child);
289 else if (dock_item)
291 gtk_widget_hide (dock_item);
292 gtk_widget_hide (GTK_BIN (dock_item)->child);
296 static void
297 on_merge_widget_destroy (GtkWidget *merge_widget, GtkWidget *menuitem)
299 toolbars = g_list_remove (toolbars, merge_widget);
300 DEBUG_PRINT ("Destroying menuitem for toolbar widget");
301 gtk_widget_destroy (menuitem);
304 static void
305 on_add_merge_widget (GtkUIManager *merge, GtkWidget *widget,
306 GtkWidget *ui_container)
308 DEBUG_PRINT ("Adding UI item ...");
310 if (GTK_IS_MENU_BAR (widget))
312 /* We don't need to manage GtkMenuBar widgets */
313 return;
315 else
317 static gint count = 0;
318 const gchar *toolbarname;
319 gchar* visible_key;
320 gchar* band_key;
321 gchar* position_key;
322 gchar* offset_key;
323 AnjutaPreferences *pr;
324 GtkWidget *menuitem;
325 gint band;
326 gint position;
327 gint offset;
328 pr = ANJUTA_PREFERENCES (ANJUTA_APP(ui_container)->preferences);
330 /* Showing the arrows seem to break anything completly! */
331 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (widget), FALSE);
333 /* Set the toolbar style */
334 if (style != -1)
335 gtk_toolbar_set_style(GTK_TOOLBAR (widget), style);
337 gtk_widget_show (widget);
338 g_object_set_data (G_OBJECT (widget), "app", ui_container);
340 /* Load toolbar position */
341 toolbarname = gtk_widget_get_name (widget);
342 band_key = g_strconcat (toolbarname, ".band", NULL);
343 position_key = g_strconcat (toolbarname, ".position", NULL);
344 offset_key = g_strconcat (toolbarname, ".offset", NULL);
345 band = anjuta_preferences_get_int_with_default(pr, band_key, -1);
346 position = anjuta_preferences_get_int_with_default(pr, position_key, 0);
347 offset = anjuta_preferences_get_int_with_default(pr, offset_key, 0);
348 /* Without these check you might see odd results */
349 if (band < 1)
350 band = count + 1;
351 g_object_set_data(G_OBJECT(widget), "position", GINT_TO_POINTER(position));
352 g_object_set_data(G_OBJECT(widget), "offset", GINT_TO_POINTER(offset));
353 g_object_set_data (G_OBJECT (widget), "band",
354 GINT_TO_POINTER(band));
355 g_free(offset_key);
356 g_free(position_key);
357 g_free(band_key);
358 DEBUG_PRINT ("Adding toolbar: %s", toolbarname);
360 if (!ANJUTA_APP (ui_container)->toolbars_menu)
362 ANJUTA_APP (ui_container)->toolbars_menu = gtk_menu_new ();
363 gtk_widget_show (GTK_WIDGET (ANJUTA_APP (ui_container)->toolbars_menu));
366 menuitem = gtk_check_menu_item_new_with_label (toolbarname);
367 gtk_menu_append (GTK_MENU (ANJUTA_APP (ui_container)->toolbars_menu),
368 menuitem);
369 gtk_widget_show (GTK_WIDGET (menuitem));
370 g_signal_connect (G_OBJECT (menuitem), "toggled",
371 G_CALLBACK (on_toolbar_view_toggled), widget);
372 g_object_set_data(G_OBJECT(widget), "menuitem", menuitem);
374 /* When the toolbar is destroyed make sure corresponding menuitem is
375 * also destroyed */
376 g_signal_connect (widget, "destroy",
377 G_CALLBACK (on_merge_widget_destroy),
378 menuitem);
380 toolbars = g_list_append(toolbars, widget);
382 /* Show/hide toolbar */
383 visible_key = g_strconcat (toolbarname, ".visible", NULL);
384 if (anjuta_preferences_get_int_with_default (pr, visible_key,
385 (count == 0)? 1:0))
387 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
388 TRUE);
390 g_free (visible_key);
391 count ++;
395 static void
396 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
397 AnjutaSession *session, AnjutaApp *app)
399 gchar *geometry, *layout_file;
400 GdkWindowState state;
401 GList* node = toolbars;
404 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
405 return;
407 /* Save toolbars */
408 while (node)
410 GtkWidget* widget = node->data;
411 GtkWidget* dock_item = g_object_get_data (G_OBJECT(widget), "dock_item");;
412 const gchar* toolbarname = gtk_widget_get_name(widget);
413 AnjutaPreferences* pr = ANJUTA_PREFERENCES (app->preferences);
415 if (dock_item)
417 gboolean visible;
418 gchar* key = g_strconcat (toolbarname, ".visible", NULL);
419 gchar* band_key = g_strconcat (toolbarname, ".band", NULL);
420 gchar* position_key = g_strconcat (toolbarname, ".position", NULL);
421 gchar* offset_key = g_strconcat (toolbarname, ".offset", NULL);
423 /* Save visibility */
424 g_object_get(G_OBJECT(dock_item), "visible", &visible, NULL);
425 anjuta_preferences_set_int(pr, key, visible);
426 g_free(key);
428 /* Save toolbar position */
429 if (app->bonobo_dock != NULL)
431 guint band;
432 guint position;
433 guint offset;
434 BonoboDockPlacement placement;
435 gchar* unique_name = g_object_get_data(G_OBJECT(dock_item),
436 "unique_name");
438 BonoboDockItem* item = bonobo_dock_get_item_by_name(BONOBO_DOCK(app->bonobo_dock),
439 unique_name, &placement,
440 &band, &position, &offset);
441 g_return_if_fail(item != NULL);
443 anjuta_preferences_set_int(pr, band_key, band);
444 anjuta_preferences_set_int(pr, position_key, position);
445 anjuta_preferences_set_int(pr, offset_key, offset);
448 g_free (band_key);
449 g_free (position_key);
450 g_free (offset_key);
452 node = g_list_next(node);
455 /* Save geometry */
456 state = gdk_window_get_state (GTK_WIDGET (app)->window);
457 if (state & GDK_WINDOW_STATE_MAXIMIZED) {
458 anjuta_session_set_int (session, "Anjuta", "Maximized", 1);
460 if (state & GDK_WINDOW_STATE_FULLSCREEN) {
461 anjuta_session_set_int (session, "Anjuta", "Fullscreen", 1);
464 /* Save geometry only if window is not maximized or fullscreened */
465 if (!(state & GDK_WINDOW_STATE_MAXIMIZED) ||
466 !(state & GDK_WINDOW_STATE_FULLSCREEN))
468 geometry = anjuta_app_get_geometry (app);
469 if (geometry)
470 anjuta_session_set_string (session, "Anjuta", "Geometry",
471 geometry);
472 g_free (geometry);
475 /* Save layout */
476 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
477 "dock-layout.xml", NULL);
478 anjuta_app_layout_save (app, layout_file, NULL);
479 g_free (layout_file);
482 static void
483 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
484 AnjutaSession *session, AnjutaApp *app)
486 /* We load layout at last so that all plugins would have loaded by now */
487 if (phase == ANJUTA_SESSION_PHASE_LAST)
489 gchar *geometry;
490 gchar *layout_file;
492 /* Restore geometry */
493 geometry = anjuta_session_get_string (session, "Anjuta", "Geometry");
494 anjuta_app_set_geometry (app, geometry);
496 /* Restore window state */
497 if (anjuta_session_get_int (session, "Anjuta", "Fullscreen"))
499 /* bug #304495 */
500 AnjutaUI* ui = anjuta_shell_get_ui(shell, NULL);
501 GtkAction* action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
502 "ActionViewFullscreen");
503 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
504 TRUE);
506 gtk_window_fullscreen (GTK_WINDOW (shell));
509 else if (anjuta_session_get_int (session, "Anjuta", "Maximized"))
511 gtk_window_maximize (GTK_WINDOW (shell));
514 /* Restore layout */
515 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
516 "dock-layout.xml", NULL);
517 anjuta_app_layout_load (app, layout_file, NULL);
518 g_free (layout_file);
522 static void
523 anjuta_app_dispose (GObject *widget)
525 AnjutaApp *app;
526 GList *tmp_list;
528 g_return_if_fail (ANJUTA_IS_APP (widget));
530 app = ANJUTA_APP (widget);
532 if (app->widgets)
534 if (g_hash_table_size (app->widgets) > 0)
537 g_warning ("Some widgets are still inside shell (%d widgets), they are:",
538 g_hash_table_size (app->widgets));
539 g_hash_table_foreach (app->widgets, (GHFunc)puts, NULL);
542 g_hash_table_destroy (app->widgets);
543 app->widgets = NULL;
546 if (app->values)
548 if (g_hash_table_size (app->values) > 0)
551 g_warning ("Some Values are still left in shell (%d Values), they are:",
552 g_hash_table_size (app->values));
553 g_hash_table_foreach (app->values, (GHFunc)puts, NULL);
556 g_hash_table_destroy (app->values);
557 app->values = NULL;
560 /* We need to destroy to the toolbars now so that the
561 * on_merge_widget_destroy() does not produce a error trying to destory
562 * already destroyed menuitems which happen when the window is being
563 * destroyed
565 * Make a tmp list because the handler removes items from 'toolbars' list.
566 * FIXME: Why is 'toolbars' a global static variable?
568 tmp_list = g_list_copy (toolbars);
569 g_list_foreach (tmp_list, (GFunc)gtk_widget_destroy, NULL);
570 g_list_free (tmp_list);
572 if (app->layout_manager) {
573 g_object_unref (app->layout_manager);
574 app->layout_manager = NULL;
576 if (app->profile_manager) {
577 g_object_unref (G_OBJECT (app->profile_manager));
578 app->profile_manager = NULL;
580 if (app->plugin_manager) {
581 g_object_unref (G_OBJECT (app->plugin_manager));
582 app->plugin_manager = NULL;
584 if (app->status) {
585 g_object_unref (G_OBJECT (app->status));
586 app->status = NULL;
589 G_OBJECT_CLASS (parent_class)->dispose (widget);
592 static void
593 anjuta_app_finalize (GObject *widget)
595 AnjutaApp *app;
597 g_return_if_fail (ANJUTA_IS_APP (widget));
599 app = ANJUTA_APP (widget);
601 gtk_widget_destroy (GTK_WIDGET (app->ui));
602 gtk_widget_destroy (GTK_WIDGET (app->preferences));
604 G_OBJECT_CLASS (parent_class)->finalize (widget);
607 static void
608 anjuta_app_instance_init (AnjutaApp *app)
610 gint merge_id;
611 GtkWidget *menubar, *toolbar_menu, *about_menu;
612 GtkWidget *view_menu, *hbox;
613 GtkWidget *main_box;
614 GtkWidget *dockbar;
615 GtkAction* action;
616 GList *plugins_dirs = NULL;
617 gchar *bonobo_string = NULL;
618 GdkGeometry size_hints = {
619 100, 100, 0, 0, 100, 100, 1, 1, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
622 DEBUG_PRINT ("Initializing Anjuta...");
624 gtk_window_set_geometry_hints (GTK_WINDOW (app), GTK_WIDGET (app),
625 &size_hints, GDK_HINT_RESIZE_INC);
626 gtk_window_set_resizable (GTK_WINDOW (app), TRUE);
629 * Main box
631 main_box = gtk_vbox_new (FALSE, 0);
632 gtk_container_add (GTK_CONTAINER (app), main_box);
633 gtk_widget_show (main_box);
635 app->layout_manager = NULL;
637 app->values = NULL;
638 app->widgets = NULL;
640 /* Status bar */
641 app->status = ANJUTA_STATUS (anjuta_status_new ());
642 anjuta_status_set_title_window (app->status, GTK_WIDGET (app));
643 gtk_widget_show (GTK_WIDGET (app->status));
644 gtk_box_pack_end (GTK_BOX (main_box),
645 GTK_WIDGET (app->status), FALSE, TRUE, 0);
646 g_object_ref (G_OBJECT (app->status));
647 g_object_add_weak_pointer (G_OBJECT (app->status), (gpointer)&app->status);
649 /* configure dock */
650 hbox = gtk_hbox_new (FALSE, 0);
651 gtk_widget_show (hbox);
652 app->dock = gdl_dock_new ();
653 gtk_widget_show (app->dock);
654 gtk_box_pack_end(GTK_BOX (hbox), app->dock, TRUE, TRUE, 0);
656 dockbar = gdl_dock_bar_new (GDL_DOCK(app->dock));
657 gtk_widget_show (dockbar);
658 gtk_box_pack_start(GTK_BOX (hbox), dockbar, FALSE, FALSE, 0);
659 gtk_box_pack_end (GTK_BOX (main_box), hbox, TRUE, TRUE, 0);
661 app->layout_manager = gdl_dock_layout_new (GDL_DOCK (app->dock));
662 g_signal_connect (app->layout_manager, "notify::dirty",
663 G_CALLBACK (on_layout_dirty_notify), app);
664 g_signal_connect (app->layout_manager->master, "notify::locked",
665 G_CALLBACK (on_layout_locked_notify), app);
667 /* UI engine */
668 app->ui = anjuta_ui_new ();
670 g_signal_connect (G_OBJECT (app->ui),
671 "add_widget", G_CALLBACK (on_add_merge_widget),
672 app);
673 g_object_add_weak_pointer (G_OBJECT (app->ui), (gpointer)&app->ui);
675 /* Plugin Manager */
676 plugins_dirs = g_list_prepend (plugins_dirs, PACKAGE_PLUGIN_DIR);
677 app->plugin_manager = anjuta_plugin_manager_new (G_OBJECT (app),
678 app->status,
679 plugins_dirs);
680 app->profile_manager = anjuta_profile_manager_new (app->plugin_manager);
681 g_list_free (plugins_dirs);
683 /* Preferences */
684 app->preferences = anjuta_preferences_new (app->plugin_manager);
685 g_object_add_weak_pointer (G_OBJECT (app->preferences),
686 (gpointer)&app->preferences);
688 anjuta_preferences_notify_add (app->preferences, "anjuta.gdl.style",
689 on_gdl_style_changed, app, NULL);
691 on_gdl_style_changed (NULL, 0, NULL, app);
693 anjuta_preferences_notify_add (app->preferences, "anjuta.toolbar.style",
694 on_toolbar_style_changed, app, NULL);
696 on_toolbar_style_changed (NULL, 0, NULL, app);
698 /* Register actions */
699 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupFile", _("File"),
700 menu_entries_file,
701 G_N_ELEMENTS (menu_entries_file),
702 GETTEXT_PACKAGE, TRUE, app);
703 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupEdit", _("Edit"),
704 menu_entries_edit,
705 G_N_ELEMENTS (menu_entries_edit),
706 GETTEXT_PACKAGE, TRUE, app);
707 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupView", _("View"),
708 menu_entries_view,
709 G_N_ELEMENTS (menu_entries_view),
710 GETTEXT_PACKAGE, TRUE, app);
711 anjuta_ui_add_toggle_action_group_entries (app->ui, "ActionGroupToggleView",
712 _("View"),
713 menu_entries_toggle_view,
714 G_N_ELEMENTS (menu_entries_toggle_view),
715 GETTEXT_PACKAGE, TRUE, app);
716 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupHelp", _("Help"),
717 menu_entries_help,
718 G_N_ELEMENTS (menu_entries_help),
719 GETTEXT_PACKAGE, TRUE, app);
721 /* Bonobo stuff */
722 app->bonobo_dock = bonobo_dock_new ();
723 gtk_widget_show (app->bonobo_dock);
725 g_signal_connect (app->bonobo_dock, "layout_changed",
726 G_CALLBACK (layout_changed), app);
728 app->bonobo_layout = bonobo_dock_layout_new ();
730 bonobo_string = anjuta_preferences_get (app->preferences, "anjuta.bonobo.layout");
731 if (bonobo_string)
733 bonobo_dock_layout_parse_string (app->bonobo_layout, bonobo_string);
734 g_free (bonobo_string);
737 bonobo_dock_add_from_layout (BONOBO_DOCK (app->bonobo_dock),
738 app->bonobo_layout);
740 g_object_unref (app->bonobo_layout);
741 app->bonobo_layout = NULL;
743 /* Merge UI */
744 merge_id = anjuta_ui_merge (app->ui, UI_FILE);
746 /* Adding accels group */
747 gtk_window_add_accel_group (GTK_WINDOW (app),
748 gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (app->ui)));
750 /* create main menu */
751 menubar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (app->ui),
752 "/MenuMain");
753 gtk_box_pack_start (GTK_BOX (main_box), menubar, FALSE, FALSE, 0);
754 gtk_widget_show (menubar);
757 * We have to add the dock after merging the ui
759 gtk_box_pack_start (GTK_BOX (main_box), app->bonobo_dock,
760 FALSE, FALSE, 0);
762 /* create toolbar menus */
763 toolbar_menu =
764 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
765 "/MenuMain/MenuView/Toolbars");
766 if (toolbar_menu)
767 gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolbar_menu),
768 app->toolbars_menu);
769 else
770 g_warning ("Cannot retrive main menu widget");
772 /* Create widgets menu */
773 view_menu =
774 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
775 "/MenuMain/MenuView");
776 app->view_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (view_menu));
778 /* Disable unavailible tutorials */
779 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpTutorial");
780 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
781 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpAdvancedTutorial");
782 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
784 /* Create about plugins menu */
785 about_menu =
786 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
787 "/MenuMain/PlaceHolderHelpMenus/MenuHelp/"
788 "PlaceHolderHelpAbout/AboutPlugins");
789 about_create_plugins_submenu (ANJUTA_SHELL (app), about_menu);
791 /* Connect to session */
792 g_signal_connect (G_OBJECT (app), "save_session",
793 G_CALLBACK (on_session_save), app);
794 g_signal_connect (G_OBJECT (app), "load_session",
795 G_CALLBACK (on_session_load), app);
797 /* Loading accels */
798 anjuta_ui_load_accels ();
801 static void
802 anjuta_app_class_init (AnjutaAppClass *class)
804 GObjectClass *object_class;
805 GtkWidgetClass *widget_class;
807 parent_class = g_type_class_peek_parent (class);
808 object_class = (GObjectClass*) class;
809 widget_class = (GtkWidgetClass*) class;
810 object_class->finalize = anjuta_app_finalize;
811 object_class->dispose = anjuta_app_dispose;
814 GtkWidget *
815 anjuta_app_new (void)
817 AnjutaApp *app;
819 app = ANJUTA_APP (g_object_new (ANJUTA_TYPE_APP,
820 "title", "Anjuta",
821 NULL));
822 return GTK_WIDGET (app);
825 gchar*
826 anjuta_app_get_geometry (AnjutaApp *app)
828 gchar *geometry;
829 gint width, height, posx, posy;
831 g_return_val_if_fail (ANJUTA_IS_APP (app), NULL);
833 geometry = NULL;
834 width = height = posx = posy = 0;
835 if (GTK_WIDGET(app)->window)
837 gtk_window_get_size (GTK_WINDOW (app), &width, &height);
838 gtk_window_get_position (GTK_WINDOW(app), &posx, &posy);
840 geometry = g_strdup_printf ("%dx%d+%d+%d", width, height, posx, posy);
842 return geometry;
845 void
846 anjuta_app_set_geometry (AnjutaApp *app, const gchar *geometry)
848 gint width, height, posx, posy;
849 gboolean geometry_set = FALSE;
851 if (geometry && strlen (geometry) > 0)
853 DEBUG_PRINT ("Setting geometry: %s", geometry);
855 if (sscanf (geometry, "%dx%d+%d+%d", &width, &height,
856 &posx, &posy) == 4)
858 if (GTK_WIDGET_REALIZED (app))
860 gtk_window_resize (GTK_WINDOW (app), width, height);
862 else
864 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
865 gtk_window_move (GTK_WINDOW (app), posx, posy);
867 geometry_set = TRUE;
869 else
871 g_warning ("Failed to parse geometry: %s", geometry);
874 if (!geometry_set)
876 posx = 10;
877 posy = 10;
878 width = gdk_screen_width () - 10;
879 height = gdk_screen_height () - 25;
880 width = (width < 790)? width : 790;
881 height = (height < 575)? width : 575;
882 if (GTK_WIDGET_REALIZED (app) == FALSE)
884 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
885 gtk_window_move (GTK_WINDOW (app), posx, posy);
890 static void
891 anjuta_app_layout_save (AnjutaApp *app, const gchar *filename,
892 const gchar *name)
894 g_return_if_fail (ANJUTA_IS_APP (app));
895 g_return_if_fail (filename != NULL);
897 gdl_dock_layout_save_layout (app->layout_manager, name);
898 if (!gdl_dock_layout_save_to_file (app->layout_manager, filename))
899 g_warning ("Saving dock layout to '%s' failed!", filename);
901 /* This is a good place to save the accels too */
902 anjuta_ui_save_accels ();
905 static void
906 anjuta_app_layout_load (AnjutaApp *app, const gchar *layout_filename,
907 const gchar *name)
909 g_return_if_fail (ANJUTA_IS_APP (app));
911 if (!layout_filename ||
912 !gdl_dock_layout_load_from_file (app->layout_manager, layout_filename))
914 gchar *datadir, *filename;
915 datadir = anjuta_res_get_data_dir();
917 filename = g_build_filename (datadir, "layout.xml", NULL);
918 DEBUG_PRINT ("Layout = %s", filename);
919 g_free (datadir);
920 if (!gdl_dock_layout_load_from_file (app->layout_manager, filename))
921 g_warning ("Loading layout from '%s' failed!!", filename);
922 g_free (filename);
925 if (!gdl_dock_layout_load_layout (app->layout_manager, name))
926 g_warning ("Loading layout failed!!");
929 void
930 anjuta_app_layout_reset (AnjutaApp *app)
932 anjuta_app_layout_load (app, NULL, NULL);
935 void
936 anjuta_app_install_preferences (AnjutaApp *app)
938 GladeXML *gxml;
939 GtkWidget *notebook, *shortcuts, *plugins, *remember_plugins;
941 /* Create preferences page */
942 gxml = glade_xml_new (GLADE_FILE, "anjuta_preferences_window", NULL);
943 anjuta_preferences_add_page (app->preferences, gxml,
944 "General", _("General"), ICON_FILE);
945 notebook = glade_xml_get_widget (gxml, "General");
946 shortcuts = anjuta_ui_get_accel_editor (ANJUTA_UI (app->ui));
947 plugins = anjuta_plugin_manager_get_plugins_page (app->plugin_manager);
948 remember_plugins = anjuta_plugin_manager_get_remembered_plugins_page (app->plugin_manager);
950 gtk_widget_show (shortcuts);
951 gtk_widget_show (plugins);
952 gtk_widget_show (remember_plugins);
954 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), plugins,
955 gtk_label_new (_("Installed plugins")));
956 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), remember_plugins,
957 gtk_label_new (_("Preferred plugins")));
958 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), shortcuts,
959 gtk_label_new (_("Shortcuts")));
961 g_object_unref (gxml);
964 /* AnjutaShell Implementation */
966 static void
967 on_value_removed_from_hash (gpointer value)
969 g_value_unset ((GValue*)value);
970 g_free (value);
973 static void
974 anjuta_app_add_value (AnjutaShell *shell, const char *name,
975 const GValue *value, GError **error)
977 GValue *copy;
978 AnjutaApp *app;
980 g_return_if_fail (ANJUTA_IS_APP (shell));
981 g_return_if_fail (name != NULL);
982 g_return_if_fail (G_IS_VALUE(value));
984 app = ANJUTA_APP (shell);
986 if (app->values == NULL)
988 app->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
989 on_value_removed_from_hash);
991 anjuta_shell_remove_value (shell, name, error);
993 copy = g_new0 (GValue, 1);
994 g_value_init (copy, value->g_type);
995 g_value_copy (value, copy);
997 g_hash_table_insert (app->values, g_strdup (name), copy);
998 g_signal_emit_by_name (shell, "value_added", name, copy);
1001 static void
1002 anjuta_app_get_value (AnjutaShell *shell, const char *name, GValue *value,
1003 GError **error)
1005 GValue *val;
1006 AnjutaApp *app;
1008 g_return_if_fail (ANJUTA_IS_APP (shell));
1009 g_return_if_fail (name != NULL);
1010 /* g_return_if_fail (G_IS_VALUE (value)); */
1012 app = ANJUTA_APP (shell);
1014 val = NULL;
1015 if (app->values)
1016 val = g_hash_table_lookup (app->values, name);
1017 if (val)
1019 if (!value->g_type)
1021 g_value_init (value, val->g_type);
1023 g_value_copy (val, value);
1025 else
1027 if (error)
1029 *error = g_error_new (ANJUTA_SHELL_ERROR,
1030 ANJUTA_SHELL_ERROR_DOESNT_EXIST,
1031 _("Value doesn't exist"));
1036 static void
1037 anjuta_app_remove_value (AnjutaShell *shell, const char *name, GError **error)
1039 AnjutaApp *app;
1040 GValue *value;
1041 char *key;
1043 g_return_if_fail (ANJUTA_IS_APP (shell));
1044 g_return_if_fail (name != NULL);
1046 app = ANJUTA_APP (shell);
1049 g_return_if_fail (app->values != NULL);
1050 if (app->widgets && g_hash_table_lookup_extended (app->widgets, name,
1051 (gpointer*)&key,
1052 (gpointer*)&w)) {
1053 GtkWidget *item;
1054 item = g_object_get_data (G_OBJECT (w), "dockitem");
1055 gdl_dock_item_hide_item (GDL_DOCK_ITEM (item));
1056 gdl_dock_object_unbind (GDL_DOCK_OBJECT (item));
1057 g_free (key);
1061 if (app->values && g_hash_table_lookup_extended (app->values, name,
1062 (gpointer)&key,
1063 (gpointer)&value)) {
1064 g_signal_emit_by_name (app, "value_removed", name);
1065 g_hash_table_remove (app->values, name);
1069 static gboolean
1070 remove_from_widgets_hash (gpointer name, gpointer hash_widget, gpointer widget)
1072 if (hash_widget == widget)
1073 return TRUE;
1074 return FALSE;
1077 static void
1078 on_widget_destroy (GtkWidget *widget, AnjutaApp *app)
1080 DEBUG_PRINT ("Widget about to be destroyed");
1081 g_hash_table_foreach_remove (app->widgets, remove_from_widgets_hash,
1082 widget);
1085 static void
1086 on_widget_remove (GtkWidget *container, GtkWidget *widget, AnjutaApp *app)
1088 GtkWidget *dock_item;
1089 GList* node = toolbars;
1090 while (node)
1092 if (node->data == widget)
1094 g_message("Removing toolbar");
1095 GtkWidget* menuitem = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "menuitem"));
1096 gtk_widget_hide(menuitem);
1097 gtk_widget_destroy(menuitem);
1098 toolbars = g_list_delete_link(toolbars, node);
1099 break;
1101 node = g_list_next(node);
1104 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1105 if (dock_item)
1107 gchar* unique_name = g_object_get_data(G_OBJECT(dock_item), "unique_name");
1108 g_free(unique_name);
1109 g_signal_handlers_disconnect_by_func (G_OBJECT (dock_item),
1110 G_CALLBACK (on_widget_remove), app);
1111 gdl_dock_item_unbind (GDL_DOCK_ITEM(dock_item));
1113 if (g_hash_table_foreach_remove (app->widgets,
1114 remove_from_widgets_hash,
1115 widget)){
1116 DEBUG_PRINT ("Widget removed from container");
1120 static void
1121 on_widget_removed_from_hash (gpointer widget)
1123 AnjutaApp *app;
1124 GtkWidget *menuitem;
1125 GdlDockItem *dockitem;
1127 DEBUG_PRINT ("Removing widget from hash");
1129 app = g_object_get_data (G_OBJECT (widget), "app-object");
1130 dockitem = g_object_get_data (G_OBJECT (widget), "dockitem");
1131 menuitem = g_object_get_data (G_OBJECT (widget), "menuitem");
1133 gtk_widget_destroy (menuitem);
1135 g_object_set_data (G_OBJECT (widget), "dockitem", NULL);
1136 g_object_set_data (G_OBJECT (widget), "menuitem", NULL);
1138 g_signal_handlers_disconnect_by_func (G_OBJECT (widget),
1139 G_CALLBACK (on_widget_destroy), app);
1140 g_signal_handlers_disconnect_by_func (G_OBJECT (dockitem),
1141 G_CALLBACK (on_widget_remove), app);
1143 g_object_unref (G_OBJECT (widget));
1146 static void
1147 anjuta_app_add_widget_full (AnjutaShell *shell,
1148 GtkWidget *widget,
1149 const char *name,
1150 const char *title,
1151 const char *stock_id,
1152 AnjutaShellPlacement placement,
1153 gboolean locked,
1154 GError **error)
1156 AnjutaApp *app;
1157 GtkWidget *item;
1158 GtkCheckMenuItem* menuitem;
1160 g_return_if_fail (ANJUTA_IS_APP (shell));
1161 g_return_if_fail (GTK_IS_WIDGET (widget));
1162 g_return_if_fail (name != NULL);
1163 g_return_if_fail (title != NULL);
1165 app = ANJUTA_APP (shell);
1168 anjuta_shell_add (shell, name, G_TYPE_FROM_INSTANCE (widget),
1169 widget, NULL);
1172 /* Add the widget to hash */
1173 if (app->widgets == NULL)
1175 app->widgets = g_hash_table_new_full (g_str_hash, g_str_equal,
1176 g_free,
1177 on_widget_removed_from_hash);
1179 g_hash_table_insert (app->widgets, g_strdup (name), widget);
1180 g_object_ref (widget);
1182 /* Add the widget to dock */
1183 if (stock_id == NULL)
1184 item = gdl_dock_item_new (name, title, GDL_DOCK_ITEM_BEH_NORMAL);
1185 else
1186 item = gdl_dock_item_new_with_stock (name, title, stock_id,
1187 GDL_DOCK_ITEM_BEH_NORMAL);
1188 if (locked)
1190 guint flags = 0;
1191 flags |= GDL_DOCK_ITEM_BEH_NEVER_FLOATING;
1192 flags |= GDL_DOCK_ITEM_BEH_CANT_CLOSE;
1193 flags |= GDL_DOCK_ITEM_BEH_CANT_ICONIFY;
1194 flags |= GDL_DOCK_ITEM_BEH_NO_GRIP;
1195 g_object_set(G_OBJECT(item), "behavior", flags, NULL);
1198 gtk_container_add (GTK_CONTAINER (item), widget);
1199 gdl_dock_add_item (GDL_DOCK (app->dock),
1200 GDL_DOCK_ITEM (item), placement);
1201 gtk_widget_show_all (item);
1203 /* Add toggle button for the widget */
1204 menuitem = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (title));
1205 gtk_widget_show (GTK_WIDGET (menuitem));
1206 gtk_check_menu_item_set_active (menuitem, TRUE);
1207 gtk_menu_append (GTK_MENU (app->view_menu), GTK_WIDGET (menuitem));
1209 if (locked)
1210 g_object_set( G_OBJECT(menuitem), "visible", FALSE, NULL);
1213 g_object_set_data (G_OBJECT (widget), "app-object", app);
1214 g_object_set_data (G_OBJECT (widget), "menuitem", menuitem);
1215 g_object_set_data (G_OBJECT (widget), "dockitem", item);
1217 /* For toggling widget view on/off */
1218 g_signal_connect (G_OBJECT (menuitem), "toggled",
1219 G_CALLBACK (on_toggle_widget_view), item);
1222 Watch for widget removal/destruction so that it could be
1223 removed from widgets hash.
1225 g_signal_connect (G_OBJECT (item), "remove",
1226 G_CALLBACK (on_widget_remove), app);
1227 g_signal_connect_after (G_OBJECT (widget), "destroy",
1228 G_CALLBACK (on_widget_destroy), app);
1231 static void
1232 anjuta_app_remove_widget (AnjutaShell *shell, GtkWidget *widget,
1233 GError **error)
1235 AnjutaApp *app;
1236 GtkWidget *dock_item;
1238 g_return_if_fail (ANJUTA_IS_APP (shell));
1239 g_return_if_fail (GTK_IS_WIDGET (widget));
1241 app = ANJUTA_APP (shell);
1243 g_return_if_fail (app->widgets != NULL);
1245 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1246 g_return_if_fail (dock_item != NULL);
1248 /* Remove the widget from container */
1249 g_object_ref (widget);
1250 /* It should call on_widget_remove() and clean up should happen */
1251 gtk_container_remove (GTK_CONTAINER (dock_item), widget);
1252 g_object_unref (widget);
1255 static void
1256 anjuta_app_present_widget (AnjutaShell *shell, GtkWidget *widget,
1257 GError **error)
1259 AnjutaApp *app;
1260 GdlDockItem *dock_item;
1261 GtkWidget *parent;
1263 g_return_if_fail (ANJUTA_IS_APP (shell));
1264 g_return_if_fail (GTK_IS_WIDGET (widget));
1266 app = ANJUTA_APP (shell);
1268 g_return_if_fail (app->widgets != NULL);
1270 dock_item = g_object_get_data (G_OBJECT(widget), "dockitem");
1271 g_return_if_fail (dock_item != NULL);
1273 /* Hack to present the dock item if it's in a notebook dock item */
1274 parent = gtk_widget_get_parent (GTK_WIDGET(dock_item) );
1275 if (GTK_IS_NOTEBOOK (parent))
1277 gint pagenum;
1278 pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (parent), GTK_WIDGET (dock_item));
1279 gtk_notebook_set_current_page (GTK_NOTEBOOK (parent), pagenum);
1281 else if (!GDL_DOCK_OBJECT_ATTACHED (dock_item))
1283 gdl_dock_item_show_item (GDL_DOCK_ITEM (dock_item));
1286 /* FIXME: If the item is floating, present the window */
1287 /* FIXME: There is no way to detect if a widget was floating before it was
1288 detached since it no longer has a parent there is no way to access the
1289 floating property of the GdlDock structure.*/
1292 static GObject*
1293 anjuta_app_get_object (AnjutaShell *shell, const char *iface_name,
1294 GError **error)
1296 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1297 g_return_val_if_fail (iface_name != NULL, NULL);
1298 return anjuta_plugin_manager_get_plugin (ANJUTA_APP (shell)->plugin_manager,
1299 iface_name);
1302 static AnjutaStatus*
1303 anjuta_app_get_status (AnjutaShell *shell, GError **error)
1305 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1306 return ANJUTA_APP (shell)->status;
1309 static AnjutaUI *
1310 anjuta_app_get_ui (AnjutaShell *shell, GError **error)
1312 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1313 return ANJUTA_APP (shell)->ui;
1316 static AnjutaPreferences *
1317 anjuta_app_get_preferences (AnjutaShell *shell, GError **error)
1319 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1320 return ANJUTA_APP (shell)->preferences;
1323 static AnjutaPluginManager *
1324 anjuta_app_get_plugin_manager (AnjutaShell *shell, GError **error)
1326 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1327 return ANJUTA_APP (shell)->plugin_manager;
1330 static AnjutaProfileManager *
1331 anjuta_app_get_profile_manager (AnjutaShell *shell, GError **error)
1333 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1334 return ANJUTA_APP (shell)->profile_manager;
1337 static void
1338 anjuta_shell_iface_init (AnjutaShellIface *iface)
1340 iface->add_widget_full = anjuta_app_add_widget_full;
1341 iface->remove_widget = anjuta_app_remove_widget;
1342 iface->present_widget = anjuta_app_present_widget;
1343 iface->add_value = anjuta_app_add_value;
1344 iface->get_value = anjuta_app_get_value;
1345 iface->remove_value = anjuta_app_remove_value;
1346 iface->get_object = anjuta_app_get_object;
1347 iface->get_status = anjuta_app_get_status;
1348 iface->get_ui = anjuta_app_get_ui;
1349 iface->get_preferences = anjuta_app_get_preferences;
1350 iface->get_plugin_manager = anjuta_app_get_plugin_manager;
1351 iface->get_profile_manager = anjuta_app_get_profile_manager;
1354 ANJUTA_TYPE_BEGIN(AnjutaApp, anjuta_app, GTK_TYPE_WINDOW);
1355 ANJUTA_TYPE_ADD_INTERFACE(anjuta_shell, ANJUTA_TYPE_SHELL);
1356 ANJUTA_TYPE_END;