Implement fetching
[anjuta-git-plugin.git] / src / anjuta-app.c
blob4506aef0499bbd2021a8e081ce5cda4b40afa152
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-utils.h>
42 #include <libanjuta/resources.h>
43 #include <libanjuta/anjuta-plugin-manager.h>
44 #include <libanjuta/anjuta-debug.h>
46 #include "anjuta-app.h"
47 #include "anjuta-actions.h"
48 #include "about.h"
50 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta.ui"
51 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta.glade"
52 #define ICON_FILE "anjuta-preferences-general-48.png"
54 static void anjuta_app_layout_load (AnjutaApp *app,
55 const gchar *layout_filename,
56 const gchar *name);
57 static void anjuta_app_layout_save (AnjutaApp *app,
58 const gchar *layout_filename,
59 const gchar *name);
61 static gpointer parent_class = NULL;
62 static GList* toolbars = NULL;
63 static GtkToolbarStyle style = -1;
65 static void
66 on_toolbar_style_changed (GConfClient* client, guint id, GConfEntry* entry,
67 gpointer user_data)
69 AnjutaApp* app = ANJUTA_APP (user_data);
70 GList *node = toolbars;
72 char* tb_style = anjuta_preferences_get (app->preferences, "anjuta.toolbar.style");
74 if (tb_style)
76 if (strcasecmp (tb_style, "Default") == 0)
77 style = -1;
78 else if (strcasecmp (tb_style, "Both") == 0)
79 style = GTK_TOOLBAR_BOTH;
80 else if (strcasecmp (tb_style, "Horiz") == 0)
81 style = GTK_TOOLBAR_BOTH_HORIZ;
82 else if (strcasecmp (tb_style, "Icons") == 0)
83 style = GTK_TOOLBAR_ICONS;
84 else if (strcasecmp (tb_style, "Text") == 0)
85 style = GTK_TOOLBAR_TEXT;
87 DEBUG_PRINT ("Toolbar style: %s", tb_style);
89 g_free(tb_style);
92 if (style != -1)
94 while (node)
96 gtk_toolbar_set_style (GTK_TOOLBAR (node->data), style);
97 node = node->next;
100 else
102 while (node)
104 gtk_toolbar_unset_style (GTK_TOOLBAR (node->data));
105 node = node->next;
112 * Accels
114 static gchar *
115 get_accel_file (void)
117 gchar *anjuta_dir = NULL;
118 gchar *filename = NULL;
120 anjuta_dir = anjuta_util_get_user_config_dir ();
122 if (anjuta_dir != NULL)
123 filename = g_build_filename (anjuta_dir, "anjuta-accels", NULL);
125 g_free (anjuta_dir);
127 return filename;
130 static void
131 load_accels (void)
133 gchar *filename;
135 filename = get_accel_file ();
136 if (filename != NULL)
138 gtk_accel_map_load (filename);
139 g_free (filename);
143 static void
144 save_accels (void)
146 gchar *filename;
148 filename = get_accel_file ();
149 if (filename != NULL)
151 gtk_accel_map_save (filename);
152 g_free (filename);
156 static void
157 on_gdl_style_changed (GConfClient* client, guint id, GConfEntry* entry,
158 gpointer user_data)
160 AnjutaApp* app = ANJUTA_APP (user_data);
161 GdlSwitcherStyle style = GDL_SWITCHER_STYLE_BOTH;
163 gchar* pr_style = anjuta_preferences_get (app->preferences, "anjuta.gdl.style");
165 if (pr_style)
167 if (strcasecmp (pr_style, "Text") == 0)
168 style = GDL_SWITCHER_STYLE_TEXT;
169 else if (strcasecmp (pr_style, "Icon") == 0)
170 style = GDL_SWITCHER_STYLE_ICON;
171 else if (strcasecmp (pr_style, "Both") == 0)
172 style = GDL_SWITCHER_STYLE_BOTH;
173 else if (strcasecmp (pr_style, "Toolbar") == 0)
174 style = GDL_SWITCHER_STYLE_TOOLBAR;
175 else if (strcasecmp (pr_style, "Tabs") == 0)
176 style = GDL_SWITCHER_STYLE_TABS;
178 DEBUG_PRINT ("Switcher style: %s", pr_style);
180 g_free (pr_style);
182 g_object_set (G_OBJECT(app->layout_manager->master), "switcher-style",
183 style, NULL);
186 static void
187 on_toggle_widget_view (GtkCheckMenuItem *menuitem, GtkWidget *dockitem)
189 gboolean state;
190 state = gtk_check_menu_item_get_active (menuitem);
191 if (state)
192 gdl_dock_item_show_item (GDL_DOCK_ITEM (dockitem));
193 else
194 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dockitem));
197 static void
198 on_update_widget_view_menuitem (gpointer key, gpointer wid, gpointer data)
200 GtkCheckMenuItem *menuitem;
201 GdlDockItem *dockitem;
203 dockitem = g_object_get_data (G_OBJECT (wid), "dockitem");
204 menuitem = g_object_get_data (G_OBJECT (wid), "menuitem");
206 g_signal_handlers_block_by_func (menuitem,
207 G_CALLBACK (on_toggle_widget_view),
208 dockitem);
210 if (GDL_DOCK_OBJECT_ATTACHED (dockitem))
211 gtk_check_menu_item_set_active (menuitem, TRUE);
212 else
213 gtk_check_menu_item_set_active (menuitem, FALSE);
215 g_signal_handlers_unblock_by_func (menuitem,
216 G_CALLBACK (on_toggle_widget_view),
217 dockitem);
220 static void
221 on_layout_dirty_notify (GObject *object, GParamSpec *pspec, gpointer user_data)
223 if (!strcmp (pspec->name, "dirty")) {
224 gboolean dirty;
225 g_object_get (object, "dirty", &dirty, NULL);
226 if (dirty) {
227 /* Update UI toggle buttons */
228 g_hash_table_foreach (ANJUTA_APP (user_data)->widgets,
229 on_update_widget_view_menuitem,
230 NULL);
235 static void
236 on_layout_locked_notify (GdlDockMaster *master, GParamSpec *pspec,
237 AnjutaApp *app)
239 AnjutaUI *ui;
240 GtkAction *action;
241 gint locked;
243 ui = app->ui;
244 action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
245 "ActionViewLockLayout");
247 g_object_get (master, "locked", &locked, NULL);
248 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
249 (locked == 1));
252 static void
253 layout_changed (GtkWidget *w, AnjutaApp *app)
255 BonoboDockLayout *layout;
256 gchar *s;
258 g_return_if_fail (ANJUTA_IS_APP (app));
259 g_return_if_fail (BONOBO_IS_DOCK (w));
261 layout = bonobo_dock_get_layout (BONOBO_DOCK (app->bonobo_dock));
262 s = bonobo_dock_layout_create_string (layout);
263 anjuta_preferences_set (app->preferences, "anjuta.bonobo.layout", s);
264 g_object_unref (G_OBJECT (layout));
265 g_free (s);
268 static void
269 anjuta_app_add_dock_item (AnjutaApp *app, BonoboDockItem *item,
270 BonoboDockPlacement placement, gint band_num,
271 gint band_position, gint offset)
273 if (app->bonobo_layout)
274 bonobo_dock_layout_add_item (app->bonobo_layout,
275 BONOBO_DOCK_ITEM (item),
276 placement, band_num, band_position,
277 offset);
278 else
279 bonobo_dock_add_item (BONOBO_DOCK(app->bonobo_dock),
280 BONOBO_DOCK_ITEM( item),
281 placement, band_num, band_position, offset, FALSE);
283 g_signal_emit_by_name (app->bonobo_dock, "layout_changed", app);
287 static void
288 on_toolbar_view_toggled (GtkCheckMenuItem *menuitem, GtkWidget *widget)
290 AnjutaApp *app;
291 GtkWidget *dock_item;
292 const gchar *name;
293 gint band;
294 gint position;
295 gint offset;
298 name = gtk_widget_get_name (widget);
299 app = g_object_get_data (G_OBJECT(widget), "app");
300 dock_item = g_object_get_data (G_OBJECT(widget), "dock_item");
301 band = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "band"));
302 position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "position"));
303 offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(widget), "offset"));
306 if (gtk_check_menu_item_get_active (menuitem))
308 if (!dock_item)
310 static gint count;
311 gchar *unique_name = g_strdup_printf ("%s-%d", name, count);
313 DEBUG_PRINT ("Adding dock item %s band %d, offset %d, position %d",
314 unique_name, band, offset, position);
316 dock_item = bonobo_dock_item_new (unique_name,
317 BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL |
318 BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING);
320 gtk_container_add (GTK_CONTAINER (dock_item), widget);
322 /* Widget not yet added to the dock. Add it */
323 anjuta_app_add_dock_item (app, BONOBO_DOCK_ITEM (dock_item),
324 BONOBO_DOCK_TOP, band, position, offset);
326 g_object_set_data_full (G_OBJECT(dock_item), "unique_name",
327 unique_name, g_free);
328 g_object_set_data (G_OBJECT(widget), "dock_item", dock_item);
329 count++;
331 gtk_widget_show (dock_item);
332 gtk_widget_show (GTK_BIN (dock_item)->child);
334 else if (dock_item)
336 gtk_widget_hide (dock_item);
337 gtk_widget_hide (GTK_BIN (dock_item)->child);
341 static void
342 on_merge_widget_destroy (GtkWidget *merge_widget, GtkWidget *menuitem)
344 toolbars = g_list_remove (toolbars, merge_widget);
345 DEBUG_PRINT ("Destroying menuitem for toolbar widget");
346 gtk_widget_destroy (menuitem);
349 static void
350 on_add_merge_widget (GtkUIManager *merge, GtkWidget *widget,
351 GtkWidget *ui_container)
353 DEBUG_PRINT ("Adding UI item ...");
355 if (GTK_IS_MENU_BAR (widget))
357 /* We don't need to manage GtkMenuBar widgets */
358 return;
360 else
362 static gint count = 0;
363 const gchar *toolbarname;
364 gchar* visible_key;
365 gchar* band_key;
366 gchar* position_key;
367 gchar* offset_key;
368 AnjutaPreferences *pr;
369 GtkWidget *menuitem;
370 gint band;
371 gint position;
372 gint offset;
373 pr = ANJUTA_PREFERENCES (ANJUTA_APP(ui_container)->preferences);
375 /* Showing the arrows seem to break anything completly! */
376 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (widget), FALSE);
378 /* Set the toolbar style */
379 if (style != -1)
380 gtk_toolbar_set_style(GTK_TOOLBAR (widget), style);
382 gtk_widget_show (widget);
383 g_object_set_data (G_OBJECT (widget), "app", ui_container);
385 /* Load toolbar position */
386 toolbarname = gtk_widget_get_name (widget);
387 band_key = g_strconcat (toolbarname, ".band", NULL);
388 position_key = g_strconcat (toolbarname, ".position", NULL);
389 offset_key = g_strconcat (toolbarname, ".offset", NULL);
390 band = anjuta_preferences_get_int_with_default(pr, band_key, -1);
391 position = anjuta_preferences_get_int_with_default(pr, position_key, 0);
392 offset = anjuta_preferences_get_int_with_default(pr, offset_key, 0);
393 /* Without these check you might see odd results */
394 if (band < 1)
395 band = count + 1;
396 g_object_set_data(G_OBJECT(widget), "position", GINT_TO_POINTER(position));
397 g_object_set_data(G_OBJECT(widget), "offset", GINT_TO_POINTER(offset));
398 g_object_set_data (G_OBJECT (widget), "band",
399 GINT_TO_POINTER(band));
400 g_free(offset_key);
401 g_free(position_key);
402 g_free(band_key);
403 DEBUG_PRINT ("Adding toolbar: %s", toolbarname);
405 if (!ANJUTA_APP (ui_container)->toolbars_menu)
407 ANJUTA_APP (ui_container)->toolbars_menu = gtk_menu_new ();
408 gtk_widget_show (GTK_WIDGET (ANJUTA_APP (ui_container)->toolbars_menu));
411 menuitem = gtk_check_menu_item_new_with_label (toolbarname);
412 gtk_menu_append (GTK_MENU (ANJUTA_APP (ui_container)->toolbars_menu),
413 menuitem);
414 gtk_widget_show (GTK_WIDGET (menuitem));
415 g_signal_connect (G_OBJECT (menuitem), "toggled",
416 G_CALLBACK (on_toolbar_view_toggled), widget);
417 g_object_set_data(G_OBJECT(widget), "menuitem", menuitem);
419 /* When the toolbar is destroyed make sure corresponding menuitem is
420 * also destroyed */
421 g_signal_connect (widget, "destroy",
422 G_CALLBACK (on_merge_widget_destroy),
423 menuitem);
425 toolbars = g_list_append(toolbars, widget);
427 /* Show/hide toolbar */
428 visible_key = g_strconcat (toolbarname, ".visible", NULL);
429 if (anjuta_preferences_get_int_with_default (pr, visible_key,
430 (count == 0)? 1:0))
432 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
433 TRUE);
435 g_free (visible_key);
436 count ++;
440 static void
441 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
442 AnjutaSession *session, AnjutaApp *app)
444 gchar *geometry, *layout_file;
445 GdkWindowState state;
446 GList* node = toolbars;
449 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
450 return;
452 /* Save toolbars */
453 while (node)
455 GtkWidget* widget = node->data;
456 GtkWidget* dock_item = g_object_get_data (G_OBJECT(widget), "dock_item");;
457 const gchar* toolbarname = gtk_widget_get_name(widget);
458 AnjutaPreferences* pr = ANJUTA_PREFERENCES (app->preferences);
460 if (dock_item)
462 gboolean visible;
463 gchar* key = g_strconcat (toolbarname, ".visible", NULL);
464 gchar* band_key = g_strconcat (toolbarname, ".band", NULL);
465 gchar* position_key = g_strconcat (toolbarname, ".position", NULL);
466 gchar* offset_key = g_strconcat (toolbarname, ".offset", NULL);
468 /* Save visibility */
469 g_object_get(G_OBJECT(dock_item), "visible", &visible, NULL);
470 anjuta_preferences_set_int(pr, key, visible);
471 g_free(key);
473 /* Save toolbar position */
474 if (app->bonobo_dock != NULL)
476 guint band;
477 guint position;
478 guint offset;
479 BonoboDockPlacement placement;
480 gchar* unique_name = g_object_get_data(G_OBJECT(dock_item),
481 "unique_name");
483 BonoboDockItem* item = bonobo_dock_get_item_by_name(BONOBO_DOCK(app->bonobo_dock),
484 unique_name, &placement,
485 &band, &position, &offset);
486 g_return_if_fail(item != NULL);
488 anjuta_preferences_set_int(pr, band_key, band);
489 anjuta_preferences_set_int(pr, position_key, position);
490 anjuta_preferences_set_int(pr, offset_key, offset);
493 g_free (band_key);
494 g_free (position_key);
495 g_free (offset_key);
497 node = g_list_next(node);
500 /* Save geometry */
501 state = gdk_window_get_state (GTK_WIDGET (app)->window);
502 if (state & GDK_WINDOW_STATE_MAXIMIZED) {
503 anjuta_session_set_int (session, "Anjuta", "Maximized", 1);
505 if (state & GDK_WINDOW_STATE_FULLSCREEN) {
506 anjuta_session_set_int (session, "Anjuta", "Fullscreen", 1);
509 /* Save geometry only if window is not maximized or fullscreened */
510 if (!(state & GDK_WINDOW_STATE_MAXIMIZED) ||
511 !(state & GDK_WINDOW_STATE_FULLSCREEN))
513 geometry = anjuta_app_get_geometry (app);
514 if (geometry)
515 anjuta_session_set_string (session, "Anjuta", "Geometry",
516 geometry);
517 g_free (geometry);
520 /* Save layout */
521 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
522 "dock-layout.xml", NULL);
523 anjuta_app_layout_save (app, layout_file, NULL);
524 g_free (layout_file);
527 static void
528 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase,
529 AnjutaSession *session, AnjutaApp *app)
531 /* We load layout at last so that all plugins would have loaded by now */
532 if (phase == ANJUTA_SESSION_PHASE_LAST)
534 gchar *geometry;
535 gchar *layout_file;
537 /* Restore geometry */
538 geometry = anjuta_session_get_string (session, "Anjuta", "Geometry");
539 anjuta_app_set_geometry (app, geometry);
541 /* Restore window state */
542 if (anjuta_session_get_int (session, "Anjuta", "Fullscreen"))
544 /* bug #304495 */
545 AnjutaUI* ui = anjuta_shell_get_ui(shell, NULL);
546 GtkAction* action = anjuta_ui_get_action (ui, "ActionGroupToggleView",
547 "ActionViewFullscreen");
548 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
549 TRUE);
551 gtk_window_fullscreen (GTK_WINDOW (shell));
554 else if (anjuta_session_get_int (session, "Anjuta", "Maximized"))
556 gtk_window_maximize (GTK_WINDOW (shell));
559 /* Restore layout */
560 layout_file = g_build_filename (anjuta_session_get_session_directory (session),
561 "dock-layout.xml", NULL);
562 anjuta_app_layout_load (app, layout_file, NULL);
563 g_free (layout_file);
567 static void
568 anjuta_app_dispose (GObject *widget)
570 AnjutaApp *app;
571 GList *tmp_list;
573 g_return_if_fail (ANJUTA_IS_APP (widget));
575 app = ANJUTA_APP (widget);
577 if (app->widgets)
579 if (g_hash_table_size (app->widgets) > 0)
582 g_warning ("Some widgets are still inside shell (%d widgets), they are:",
583 g_hash_table_size (app->widgets));
584 g_hash_table_foreach (app->widgets, (GHFunc)puts, NULL);
587 g_hash_table_destroy (app->widgets);
588 app->widgets = NULL;
591 if (app->values)
593 if (g_hash_table_size (app->values) > 0)
596 g_warning ("Some Values are still left in shell (%d Values), they are:",
597 g_hash_table_size (app->values));
598 g_hash_table_foreach (app->values, (GHFunc)puts, NULL);
601 g_hash_table_destroy (app->values);
602 app->values = NULL;
605 /* We need to destroy to the toolbars now so that the
606 * on_merge_widget_destroy() does not produce a error trying to destory
607 * already destroyed menuitems which happen when the window is being
608 * destroyed
610 * Make a tmp list because the handler removes items from 'toolbars' list.
611 * FIXME: Why is 'toolbars' a global static variable?
613 tmp_list = g_list_copy (toolbars);
614 g_list_foreach (tmp_list, (GFunc)gtk_widget_destroy, NULL);
615 g_list_free (tmp_list);
617 if (app->layout_manager) {
618 g_object_unref (app->layout_manager);
619 app->layout_manager = NULL;
621 if (app->profile_manager) {
622 g_object_unref (G_OBJECT (app->profile_manager));
623 app->profile_manager = NULL;
625 if (app->plugin_manager) {
626 g_object_unref (G_OBJECT (app->plugin_manager));
627 app->plugin_manager = NULL;
629 if (app->status) {
630 g_object_unref (G_OBJECT (app->status));
631 app->status = NULL;
634 G_OBJECT_CLASS (parent_class)->dispose (widget);
637 static void
638 anjuta_app_finalize (GObject *widget)
640 AnjutaApp *app;
642 g_return_if_fail (ANJUTA_IS_APP (widget));
644 app = ANJUTA_APP (widget);
646 gtk_widget_destroy (GTK_WIDGET (app->ui));
647 gtk_widget_destroy (GTK_WIDGET (app->preferences));
649 G_OBJECT_CLASS (parent_class)->finalize (widget);
652 static void
653 anjuta_app_instance_init (AnjutaApp *app)
655 gint merge_id;
656 GtkWidget *menubar, *toolbar_menu, *about_menu;
657 GtkWidget *view_menu, *hbox;
658 GtkWidget *main_box;
659 GtkWidget *dockbar;
660 GtkAction* action;
661 GList *plugins_dirs = NULL;
662 gchar *bonobo_string = NULL;
663 GdkGeometry size_hints = {
664 100, 100, 0, 0, 100, 100, 1, 1, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
667 DEBUG_PRINT ("Initializing Anjuta...");
669 gtk_window_set_geometry_hints (GTK_WINDOW (app), GTK_WIDGET (app),
670 &size_hints, GDK_HINT_RESIZE_INC);
671 gtk_window_set_resizable (GTK_WINDOW (app), TRUE);
674 * Main box
676 main_box = gtk_vbox_new (FALSE, 0);
677 gtk_container_add (GTK_CONTAINER (app), main_box);
678 gtk_widget_show (main_box);
680 app->layout_manager = NULL;
682 app->values = NULL;
683 app->widgets = NULL;
685 /* Status bar */
686 app->status = ANJUTA_STATUS (anjuta_status_new ());
687 anjuta_status_set_title_window (app->status, GTK_WIDGET (app));
688 gtk_widget_show (GTK_WIDGET (app->status));
689 gtk_box_pack_end (GTK_BOX (main_box),
690 GTK_WIDGET (app->status), FALSE, TRUE, 0);
691 g_object_ref (G_OBJECT (app->status));
692 g_object_add_weak_pointer (G_OBJECT (app->status), (gpointer)&app->status);
694 /* configure dock */
695 hbox = gtk_hbox_new (FALSE, 0);
696 gtk_widget_show (hbox);
697 app->dock = gdl_dock_new ();
698 gtk_widget_show (app->dock);
699 gtk_box_pack_end(GTK_BOX (hbox), app->dock, TRUE, TRUE, 0);
701 dockbar = gdl_dock_bar_new (GDL_DOCK(app->dock));
702 gtk_widget_show (dockbar);
703 gtk_box_pack_start(GTK_BOX (hbox), dockbar, FALSE, FALSE, 0);
704 gtk_box_pack_end (GTK_BOX (main_box), hbox, TRUE, TRUE, 0);
706 app->layout_manager = gdl_dock_layout_new (GDL_DOCK (app->dock));
707 g_signal_connect (app->layout_manager, "notify::dirty",
708 G_CALLBACK (on_layout_dirty_notify), app);
709 g_signal_connect (app->layout_manager->master, "notify::locked",
710 G_CALLBACK (on_layout_locked_notify), app);
712 /* UI engine */
713 app->ui = anjuta_ui_new ();
715 g_signal_connect (G_OBJECT (app->ui),
716 "add_widget", G_CALLBACK (on_add_merge_widget),
717 app);
718 g_object_add_weak_pointer (G_OBJECT (app->ui), (gpointer)&app->ui);
720 /* Plugin Manager */
721 plugins_dirs = g_list_prepend (plugins_dirs, PACKAGE_PLUGIN_DIR);
722 app->plugin_manager = anjuta_plugin_manager_new (G_OBJECT (app),
723 app->status,
724 plugins_dirs);
725 app->profile_manager = anjuta_profile_manager_new (app->plugin_manager);
726 g_list_free (plugins_dirs);
728 /* Preferences */
729 app->preferences = anjuta_preferences_new (app->plugin_manager);
730 g_object_add_weak_pointer (G_OBJECT (app->preferences),
731 (gpointer)&app->preferences);
733 anjuta_preferences_notify_add (app->preferences, "anjuta.gdl.style",
734 on_gdl_style_changed, app, NULL);
736 on_gdl_style_changed (NULL, 0, NULL, app);
738 anjuta_preferences_notify_add (app->preferences, "anjuta.toolbar.style",
739 on_toolbar_style_changed, app, NULL);
741 on_toolbar_style_changed (NULL, 0, NULL, app);
743 /* Register actions */
744 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupFile", _("File"),
745 menu_entries_file,
746 G_N_ELEMENTS (menu_entries_file),
747 GETTEXT_PACKAGE, TRUE, app);
748 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupEdit", _("Edit"),
749 menu_entries_edit,
750 G_N_ELEMENTS (menu_entries_edit),
751 GETTEXT_PACKAGE, TRUE, app);
752 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupView", _("View"),
753 menu_entries_view,
754 G_N_ELEMENTS (menu_entries_view),
755 GETTEXT_PACKAGE, TRUE, app);
756 anjuta_ui_add_toggle_action_group_entries (app->ui, "ActionGroupToggleView",
757 _("View"),
758 menu_entries_toggle_view,
759 G_N_ELEMENTS (menu_entries_toggle_view),
760 GETTEXT_PACKAGE, TRUE, app);
761 anjuta_ui_add_action_group_entries (app->ui, "ActionGroupHelp", _("Help"),
762 menu_entries_help,
763 G_N_ELEMENTS (menu_entries_help),
764 GETTEXT_PACKAGE, TRUE, app);
766 /* Bonobo stuff */
767 app->bonobo_dock = bonobo_dock_new ();
768 gtk_widget_show (app->bonobo_dock);
770 g_signal_connect (app->bonobo_dock, "layout_changed",
771 G_CALLBACK (layout_changed), app);
773 app->bonobo_layout = bonobo_dock_layout_new ();
775 bonobo_string = anjuta_preferences_get (app->preferences, "anjuta.bonobo.layout");
776 if (bonobo_string)
778 bonobo_dock_layout_parse_string (app->bonobo_layout, bonobo_string);
779 g_free (bonobo_string);
782 bonobo_dock_add_from_layout (BONOBO_DOCK (app->bonobo_dock),
783 app->bonobo_layout);
785 g_object_unref (app->bonobo_layout);
786 app->bonobo_layout = NULL;
788 /* Merge UI */
789 merge_id = anjuta_ui_merge (app->ui, UI_FILE);
791 /* Adding accels group */
792 gtk_window_add_accel_group (GTK_WINDOW (app),
793 gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (app->ui)));
795 /* create main menu */
796 menubar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (app->ui),
797 "/MenuMain");
798 gtk_box_pack_start (GTK_BOX (main_box), menubar, FALSE, FALSE, 0);
799 gtk_widget_show (menubar);
802 * We have to add the dock after merging the ui
804 gtk_box_pack_start (GTK_BOX (main_box), app->bonobo_dock,
805 FALSE, FALSE, 0);
807 /* create toolbar menus */
808 toolbar_menu =
809 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
810 "/MenuMain/MenuView/Toolbars");
811 if (toolbar_menu)
812 gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolbar_menu),
813 app->toolbars_menu);
814 else
815 g_warning ("Cannot retrive main menu widget");
817 /* Create widgets menu */
818 view_menu =
819 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
820 "/MenuMain/MenuView");
821 app->view_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (view_menu));
823 /* Disable unavailible tutorials */
824 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpTutorial");
825 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
826 action = anjuta_ui_get_action(app->ui, "ActionGroupHelp", "ActionHelpAdvancedTutorial");
827 g_object_set(G_OBJECT(action), "visible", FALSE, NULL);
829 /* Create about plugins menu */
830 about_menu =
831 gtk_ui_manager_get_widget (GTK_UI_MANAGER(app->ui),
832 "/MenuMain/PlaceHolderHelpMenus/MenuHelp/"
833 "PlaceHolderHelpAbout/AboutPlugins");
834 about_create_plugins_submenu (ANJUTA_SHELL (app), about_menu);
836 /* Connect to session */
837 g_signal_connect (G_OBJECT (app), "save_session",
838 G_CALLBACK (on_session_save), app);
839 g_signal_connect (G_OBJECT (app), "load_session",
840 G_CALLBACK (on_session_load), app);
842 /* Loading accels */
843 load_accels ();
846 static void
847 anjuta_app_class_init (AnjutaAppClass *class)
849 GObjectClass *object_class;
850 GtkWidgetClass *widget_class;
852 parent_class = g_type_class_peek_parent (class);
853 object_class = (GObjectClass*) class;
854 widget_class = (GtkWidgetClass*) class;
855 object_class->finalize = anjuta_app_finalize;
856 object_class->dispose = anjuta_app_dispose;
859 GtkWidget *
860 anjuta_app_new (void)
862 AnjutaApp *app;
864 app = ANJUTA_APP (g_object_new (ANJUTA_TYPE_APP,
865 "title", "Anjuta",
866 NULL));
867 return GTK_WIDGET (app);
870 gchar*
871 anjuta_app_get_geometry (AnjutaApp *app)
873 gchar *geometry;
874 gint width, height, posx, posy;
876 g_return_val_if_fail (ANJUTA_IS_APP (app), NULL);
878 geometry = NULL;
879 width = height = posx = posy = 0;
880 if (GTK_WIDGET(app)->window)
882 gtk_window_get_size (GTK_WINDOW (app), &width, &height);
883 gtk_window_get_position (GTK_WINDOW(app), &posx, &posy);
885 geometry = g_strdup_printf ("%dx%d+%d+%d", width, height, posx, posy);
887 return geometry;
890 void
891 anjuta_app_set_geometry (AnjutaApp *app, const gchar *geometry)
893 gint width, height, posx, posy;
894 gboolean geometry_set = FALSE;
896 if (geometry && strlen (geometry) > 0)
898 DEBUG_PRINT ("Setting geometry: %s", geometry);
900 if (sscanf (geometry, "%dx%d+%d+%d", &width, &height,
901 &posx, &posy) == 4)
903 if (GTK_WIDGET_REALIZED (app))
905 gtk_window_resize (GTK_WINDOW (app), width, height);
907 else
909 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
910 gtk_window_move (GTK_WINDOW (app), posx, posy);
912 geometry_set = TRUE;
914 else
916 g_warning ("Failed to parse geometry: %s", geometry);
919 if (!geometry_set)
921 posx = 10;
922 posy = 10;
923 width = gdk_screen_width () - 10;
924 height = gdk_screen_height () - 25;
925 width = (width < 790)? width : 790;
926 height = (height < 575)? width : 575;
927 if (GTK_WIDGET_REALIZED (app) == FALSE)
929 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
930 gtk_window_move (GTK_WINDOW (app), posx, posy);
935 static void
936 anjuta_app_layout_save (AnjutaApp *app, const gchar *filename,
937 const gchar *name)
939 g_return_if_fail (ANJUTA_IS_APP (app));
940 g_return_if_fail (filename != NULL);
942 gdl_dock_layout_save_layout (app->layout_manager, name);
943 if (!gdl_dock_layout_save_to_file (app->layout_manager, filename))
944 g_warning ("Saving dock layout to '%s' failed!", filename);
946 /* This is a good place to save the accels too */
947 save_accels ();
950 static void
951 anjuta_app_layout_load (AnjutaApp *app, const gchar *layout_filename,
952 const gchar *name)
954 g_return_if_fail (ANJUTA_IS_APP (app));
956 if (!layout_filename ||
957 !gdl_dock_layout_load_from_file (app->layout_manager, layout_filename))
959 gchar *datadir, *filename;
960 datadir = anjuta_res_get_data_dir();
962 filename = g_build_filename (datadir, "layout.xml", NULL);
963 DEBUG_PRINT ("Layout = %s", filename);
964 g_free (datadir);
965 if (!gdl_dock_layout_load_from_file (app->layout_manager, filename))
966 g_warning ("Loading layout from '%s' failed!!", filename);
967 g_free (filename);
970 if (!gdl_dock_layout_load_layout (app->layout_manager, name))
971 g_warning ("Loading layout failed!!");
974 void
975 anjuta_app_layout_reset (AnjutaApp *app)
977 anjuta_app_layout_load (app, NULL, NULL);
980 void
981 anjuta_app_install_preferences (AnjutaApp *app)
983 GladeXML *gxml;
984 GtkWidget *notebook, *shortcuts, *plugins, *remember_plugins;
986 /* Create preferences page */
987 gxml = glade_xml_new (GLADE_FILE, "anjuta_preferences_window", NULL);
988 anjuta_preferences_add_page (app->preferences, gxml,
989 "General", _("General"), ICON_FILE);
990 notebook = glade_xml_get_widget (gxml, "General");
991 shortcuts = anjuta_ui_get_accel_editor (ANJUTA_UI (app->ui));
992 plugins = anjuta_plugin_manager_get_plugins_page (app->plugin_manager);
993 remember_plugins = anjuta_plugin_manager_get_remembered_plugins_page (app->plugin_manager);
995 gtk_widget_show (shortcuts);
996 gtk_widget_show (plugins);
997 gtk_widget_show (remember_plugins);
999 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), plugins,
1000 gtk_label_new (_("Installed plugins")));
1001 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), remember_plugins,
1002 gtk_label_new (_("Preferred plugins")));
1003 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), shortcuts,
1004 gtk_label_new (_("Shortcuts")));
1006 g_object_unref (gxml);
1009 /* AnjutaShell Implementation */
1011 static void
1012 on_value_removed_from_hash (gpointer value)
1014 g_value_unset ((GValue*)value);
1015 g_free (value);
1018 static void
1019 anjuta_app_add_value (AnjutaShell *shell, const char *name,
1020 const GValue *value, GError **error)
1022 GValue *copy;
1023 AnjutaApp *app;
1025 g_return_if_fail (ANJUTA_IS_APP (shell));
1026 g_return_if_fail (name != NULL);
1027 g_return_if_fail (G_IS_VALUE(value));
1029 app = ANJUTA_APP (shell);
1031 if (app->values == NULL)
1033 app->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
1034 on_value_removed_from_hash);
1036 anjuta_shell_remove_value (shell, name, error);
1038 copy = g_new0 (GValue, 1);
1039 g_value_init (copy, value->g_type);
1040 g_value_copy (value, copy);
1042 g_hash_table_insert (app->values, g_strdup (name), copy);
1043 g_signal_emit_by_name (shell, "value_added", name, copy);
1046 static void
1047 anjuta_app_get_value (AnjutaShell *shell, const char *name, GValue *value,
1048 GError **error)
1050 GValue *val;
1051 AnjutaApp *app;
1053 g_return_if_fail (ANJUTA_IS_APP (shell));
1054 g_return_if_fail (name != NULL);
1055 /* g_return_if_fail (G_IS_VALUE (value)); */
1057 app = ANJUTA_APP (shell);
1059 val = NULL;
1060 if (app->values)
1061 val = g_hash_table_lookup (app->values, name);
1062 if (val)
1064 if (!value->g_type)
1066 g_value_init (value, val->g_type);
1068 g_value_copy (val, value);
1070 else
1072 if (error)
1074 *error = g_error_new (ANJUTA_SHELL_ERROR,
1075 ANJUTA_SHELL_ERROR_DOESNT_EXIST,
1076 _("Value doesn't exist"));
1081 static void
1082 anjuta_app_remove_value (AnjutaShell *shell, const char *name, GError **error)
1084 AnjutaApp *app;
1085 GValue *value;
1086 char *key;
1088 g_return_if_fail (ANJUTA_IS_APP (shell));
1089 g_return_if_fail (name != NULL);
1091 app = ANJUTA_APP (shell);
1094 g_return_if_fail (app->values != NULL);
1095 if (app->widgets && g_hash_table_lookup_extended (app->widgets, name,
1096 (gpointer*)&key,
1097 (gpointer*)&w)) {
1098 GtkWidget *item;
1099 item = g_object_get_data (G_OBJECT (w), "dockitem");
1100 gdl_dock_item_hide_item (GDL_DOCK_ITEM (item));
1101 gdl_dock_object_unbind (GDL_DOCK_OBJECT (item));
1102 g_free (key);
1106 if (app->values && g_hash_table_lookup_extended (app->values, name,
1107 (gpointer)&key,
1108 (gpointer)&value)) {
1109 g_signal_emit_by_name (app, "value_removed", name);
1110 g_hash_table_remove (app->values, name);
1114 static gboolean
1115 remove_from_widgets_hash (gpointer name, gpointer hash_widget, gpointer widget)
1117 if (hash_widget == widget)
1118 return TRUE;
1119 return FALSE;
1122 static void
1123 on_widget_destroy (GtkWidget *widget, AnjutaApp *app)
1125 DEBUG_PRINT ("Widget about to be destroyed");
1126 g_hash_table_foreach_remove (app->widgets, remove_from_widgets_hash,
1127 widget);
1130 static void
1131 on_widget_remove (GtkWidget *container, GtkWidget *widget, AnjutaApp *app)
1133 GtkWidget *dock_item;
1134 GList* node = toolbars;
1135 while (node)
1137 if (node->data == widget)
1139 g_message("Removing toolbar");
1140 GtkWidget* menuitem = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "menuitem"));
1141 gtk_widget_hide(menuitem);
1142 gtk_widget_destroy(menuitem);
1143 toolbars = g_list_delete_link(toolbars, node);
1144 break;
1146 node = g_list_next(node);
1149 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1150 if (dock_item)
1152 gchar* unique_name = g_object_get_data(G_OBJECT(dock_item), "unique_name");
1153 g_free(unique_name);
1154 g_signal_handlers_disconnect_by_func (G_OBJECT (dock_item),
1155 G_CALLBACK (on_widget_remove), app);
1156 gdl_dock_item_unbind (GDL_DOCK_ITEM(dock_item));
1158 if (g_hash_table_foreach_remove (app->widgets,
1159 remove_from_widgets_hash,
1160 widget)){
1161 DEBUG_PRINT ("Widget removed from container");
1165 static void
1166 on_widget_removed_from_hash (gpointer widget)
1168 AnjutaApp *app;
1169 GtkWidget *menuitem;
1170 GdlDockItem *dockitem;
1172 DEBUG_PRINT ("Removing widget from hash");
1174 app = g_object_get_data (G_OBJECT (widget), "app-object");
1175 dockitem = g_object_get_data (G_OBJECT (widget), "dockitem");
1176 menuitem = g_object_get_data (G_OBJECT (widget), "menuitem");
1178 gtk_widget_destroy (menuitem);
1180 g_object_set_data (G_OBJECT (widget), "dockitem", NULL);
1181 g_object_set_data (G_OBJECT (widget), "menuitem", NULL);
1183 g_signal_handlers_disconnect_by_func (G_OBJECT (widget),
1184 G_CALLBACK (on_widget_destroy), app);
1185 g_signal_handlers_disconnect_by_func (G_OBJECT (dockitem),
1186 G_CALLBACK (on_widget_remove), app);
1188 g_object_unref (G_OBJECT (widget));
1191 static void
1192 anjuta_app_add_widget_full (AnjutaShell *shell,
1193 GtkWidget *widget,
1194 const char *name,
1195 const char *title,
1196 const char *stock_id,
1197 AnjutaShellPlacement placement,
1198 gboolean locked,
1199 GError **error)
1201 AnjutaApp *app;
1202 GtkWidget *item;
1203 GtkCheckMenuItem* menuitem;
1205 g_return_if_fail (ANJUTA_IS_APP (shell));
1206 g_return_if_fail (GTK_IS_WIDGET (widget));
1207 g_return_if_fail (name != NULL);
1208 g_return_if_fail (title != NULL);
1210 app = ANJUTA_APP (shell);
1213 anjuta_shell_add (shell, name, G_TYPE_FROM_INSTANCE (widget),
1214 widget, NULL);
1217 /* Add the widget to hash */
1218 if (app->widgets == NULL)
1220 app->widgets = g_hash_table_new_full (g_str_hash, g_str_equal,
1221 g_free,
1222 on_widget_removed_from_hash);
1224 g_hash_table_insert (app->widgets, g_strdup (name), widget);
1225 g_object_ref (widget);
1227 /* Add the widget to dock */
1228 if (stock_id == NULL)
1229 item = gdl_dock_item_new (name, title, GDL_DOCK_ITEM_BEH_NORMAL);
1230 else
1231 item = gdl_dock_item_new_with_stock (name, title, stock_id,
1232 GDL_DOCK_ITEM_BEH_NORMAL);
1233 if (locked)
1235 guint flags = 0;
1236 flags |= GDL_DOCK_ITEM_BEH_NEVER_FLOATING;
1237 flags |= GDL_DOCK_ITEM_BEH_CANT_CLOSE;
1238 flags |= GDL_DOCK_ITEM_BEH_CANT_ICONIFY;
1239 flags |= GDL_DOCK_ITEM_BEH_NO_GRIP;
1240 g_object_set(G_OBJECT(item), "behavior", flags, NULL);
1243 gtk_container_add (GTK_CONTAINER (item), widget);
1244 gdl_dock_add_item (GDL_DOCK (app->dock),
1245 GDL_DOCK_ITEM (item), placement);
1246 gtk_widget_show_all (item);
1248 /* Add toggle button for the widget */
1249 menuitem = GTK_CHECK_MENU_ITEM (gtk_check_menu_item_new_with_label (title));
1250 gtk_widget_show (GTK_WIDGET (menuitem));
1251 gtk_check_menu_item_set_active (menuitem, TRUE);
1252 gtk_menu_append (GTK_MENU (app->view_menu), GTK_WIDGET (menuitem));
1254 if (locked)
1255 g_object_set( G_OBJECT(menuitem), "visible", FALSE, NULL);
1258 g_object_set_data (G_OBJECT (widget), "app-object", app);
1259 g_object_set_data (G_OBJECT (widget), "menuitem", menuitem);
1260 g_object_set_data (G_OBJECT (widget), "dockitem", item);
1262 /* For toggling widget view on/off */
1263 g_signal_connect (G_OBJECT (menuitem), "toggled",
1264 G_CALLBACK (on_toggle_widget_view), item);
1267 Watch for widget removal/destruction so that it could be
1268 removed from widgets hash.
1270 g_signal_connect (G_OBJECT (item), "remove",
1271 G_CALLBACK (on_widget_remove), app);
1272 g_signal_connect_after (G_OBJECT (widget), "destroy",
1273 G_CALLBACK (on_widget_destroy), app);
1276 static void
1277 anjuta_app_remove_widget (AnjutaShell *shell, GtkWidget *widget,
1278 GError **error)
1280 AnjutaApp *app;
1281 GtkWidget *dock_item;
1283 g_return_if_fail (ANJUTA_IS_APP (shell));
1284 g_return_if_fail (GTK_IS_WIDGET (widget));
1286 app = ANJUTA_APP (shell);
1288 g_return_if_fail (app->widgets != NULL);
1290 dock_item = g_object_get_data (G_OBJECT (widget), "dockitem");
1291 g_return_if_fail (dock_item != NULL);
1293 /* Remove the widget from container */
1294 g_object_ref (widget);
1295 /* It should call on_widget_remove() and clean up should happen */
1296 gtk_container_remove (GTK_CONTAINER (dock_item), widget);
1297 g_object_unref (widget);
1300 static void
1301 anjuta_app_present_widget (AnjutaShell *shell, GtkWidget *widget,
1302 GError **error)
1304 AnjutaApp *app;
1305 GdlDockItem *dock_item;
1306 GtkWidget *parent;
1308 g_return_if_fail (ANJUTA_IS_APP (shell));
1309 g_return_if_fail (GTK_IS_WIDGET (widget));
1311 app = ANJUTA_APP (shell);
1313 g_return_if_fail (app->widgets != NULL);
1315 dock_item = g_object_get_data (G_OBJECT(widget), "dockitem");
1316 g_return_if_fail (dock_item != NULL);
1318 /* Hack to present the dock item if it's in a notebook dock item */
1319 parent = gtk_widget_get_parent (GTK_WIDGET(dock_item) );
1320 if (GTK_IS_NOTEBOOK (parent))
1322 gint pagenum;
1323 pagenum = gtk_notebook_page_num (GTK_NOTEBOOK (parent), GTK_WIDGET (dock_item));
1324 gtk_notebook_set_current_page (GTK_NOTEBOOK (parent), pagenum);
1326 else if (!GDL_DOCK_OBJECT_ATTACHED (dock_item))
1328 gdl_dock_item_show_item (GDL_DOCK_ITEM (dock_item));
1331 /* FIXME: If the item is floating, present the window */
1332 /* FIXME: There is no way to detect if a widget was floating before it was
1333 detached since it no longer has a parent there is no way to access the
1334 floating property of the GdlDock structure.*/
1337 static GObject*
1338 anjuta_app_get_object (AnjutaShell *shell, const char *iface_name,
1339 GError **error)
1341 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1342 g_return_val_if_fail (iface_name != NULL, NULL);
1343 return anjuta_plugin_manager_get_plugin (ANJUTA_APP (shell)->plugin_manager,
1344 iface_name);
1347 static AnjutaStatus*
1348 anjuta_app_get_status (AnjutaShell *shell, GError **error)
1350 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1351 return ANJUTA_APP (shell)->status;
1354 static AnjutaUI *
1355 anjuta_app_get_ui (AnjutaShell *shell, GError **error)
1357 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1358 return ANJUTA_APP (shell)->ui;
1361 static AnjutaPreferences *
1362 anjuta_app_get_preferences (AnjutaShell *shell, GError **error)
1364 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1365 return ANJUTA_APP (shell)->preferences;
1368 static AnjutaPluginManager *
1369 anjuta_app_get_plugin_manager (AnjutaShell *shell, GError **error)
1371 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1372 return ANJUTA_APP (shell)->plugin_manager;
1375 static AnjutaProfileManager *
1376 anjuta_app_get_profile_manager (AnjutaShell *shell, GError **error)
1378 g_return_val_if_fail (ANJUTA_IS_APP (shell), NULL);
1379 return ANJUTA_APP (shell)->profile_manager;
1382 static void
1383 anjuta_shell_iface_init (AnjutaShellIface *iface)
1385 iface->add_widget_full = anjuta_app_add_widget_full;
1386 iface->remove_widget = anjuta_app_remove_widget;
1387 iface->present_widget = anjuta_app_present_widget;
1388 iface->add_value = anjuta_app_add_value;
1389 iface->get_value = anjuta_app_get_value;
1390 iface->remove_value = anjuta_app_remove_value;
1391 iface->get_object = anjuta_app_get_object;
1392 iface->get_status = anjuta_app_get_status;
1393 iface->get_ui = anjuta_app_get_ui;
1394 iface->get_preferences = anjuta_app_get_preferences;
1395 iface->get_plugin_manager = anjuta_app_get_plugin_manager;
1396 iface->get_profile_manager = anjuta_app_get_profile_manager;
1399 ANJUTA_TYPE_BEGIN(AnjutaApp, anjuta_app, GTK_TYPE_WINDOW);
1400 ANJUTA_TYPE_ADD_INTERFACE(anjuta_shell, ANJUTA_TYPE_SHELL);
1401 ANJUTA_TYPE_END;