1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) 2003 Naba Kumar <naba@gnome.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc., 59
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
35 #include <gtksourceview/gtksourceview.h>
37 #include <libanjuta/anjuta-shell.h>
38 #include <libanjuta/anjuta-ui.h>
39 #include <libanjuta/anjuta-utils.h>
40 #include <libanjuta/resources.h>
41 #include <libanjuta/anjuta-plugin-manager.h>
42 #include <libanjuta/anjuta-debug.h>
44 #include "anjuta-window.h"
45 #include "anjuta-actions.h"
46 #include "anjuta-application.h"
49 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta.xml"
50 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/preferences.ui"
51 #define ICON_FILE "anjuta-preferences-general-48.png"
53 #define PREF_SCHEMA "org.gnome.anjuta"
54 #define GDL_STYLE "gdl-style"
55 #define TOOLBAR_VISIBLE "toolbar-visible"
56 #define TOOLBAR_STYLE "toolbar-style"
58 static void anjuta_window_layout_load (AnjutaWindow
*win
,
59 const gchar
*layout_filename
,
61 static void anjuta_window_layout_save (AnjutaWindow
*win
,
62 const gchar
*layout_filename
,
65 static gpointer parent_class
= NULL
;
66 static GtkToolbarStyle style
= -1;
69 menu_item_select_cb (GtkMenuItem
*proxy
,
75 action
= gtk_activatable_get_related_action (GTK_ACTIVATABLE (proxy
));
76 g_return_if_fail (action
!= NULL
);
78 g_object_get (G_OBJECT (action
), "tooltip", &message
, NULL
);
81 anjuta_status_push (win
->status
, "%s", message
);
87 menu_item_deselect_cb (GtkMenuItem
*proxy
,
90 anjuta_status_pop (win
->status
);
95 connect_proxy_cb (GtkUIManager
*manager
,
100 if (GTK_IS_MENU_ITEM (proxy
))
102 g_signal_connect (proxy
, "select",
103 G_CALLBACK (menu_item_select_cb
), win
);
104 g_signal_connect (proxy
, "deselect",
105 G_CALLBACK (menu_item_deselect_cb
), win
);
110 disconnect_proxy_cb (GtkUIManager
*manager
,
115 if (GTK_IS_MENU_ITEM (proxy
))
117 g_signal_handlers_disconnect_by_func
118 (proxy
, G_CALLBACK (menu_item_select_cb
), win
);
119 g_signal_handlers_disconnect_by_func
120 (proxy
, G_CALLBACK (menu_item_deselect_cb
), win
);
125 anjuta_window_iconify_dockable_widget (AnjutaShell
*shell
, GtkWidget
*widget
,
128 AnjutaWindow
*win
= NULL
;
129 GtkWidget
*dock_item
= NULL
;
131 /* Argumments assertions */
132 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
133 g_return_if_fail (GTK_IS_WIDGET (widget
));
135 win
= ANJUTA_WINDOW (shell
);
136 g_return_if_fail (win
->widgets
!= NULL
);
138 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
139 g_return_if_fail (dock_item
!= NULL
);
141 /* Iconify the dockable item */
142 gdl_dock_item_iconify_item (GDL_DOCK_ITEM (dock_item
));
146 anjuta_window_hide_dockable_widget (AnjutaShell
*shell
, GtkWidget
*widget
,
149 AnjutaWindow
*win
= NULL
;
150 GtkWidget
*dock_item
= NULL
;
152 /* Argumments assertions */
153 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
154 g_return_if_fail (GTK_IS_WIDGET (widget
));
156 win
= ANJUTA_WINDOW (shell
);
157 g_return_if_fail (win
->widgets
!= NULL
);
159 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
160 g_return_if_fail (dock_item
!= NULL
);
162 /* Hide the dockable item */
163 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dock_item
));
167 anjuta_window_show_dockable_widget (AnjutaShell
*shell
, GtkWidget
* widget
,
170 AnjutaWindow
*win
= NULL
;
171 GtkWidget
*dock_item
= NULL
;
173 /* Argumments assertions */
174 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
175 g_return_if_fail (GTK_IS_WIDGET (widget
));
177 win
= ANJUTA_WINDOW (shell
);
178 g_return_if_fail (win
->widgets
!= NULL
);
180 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
181 g_return_if_fail (dock_item
!= NULL
);
183 /* Show the dockable item */
184 gdl_dock_item_show_item(GDL_DOCK_ITEM (dock_item
));
188 anjuta_window_maximize_widget (AnjutaShell
*shell
,
189 const char *widget_name
,
192 AnjutaWindow
*win
= NULL
;
193 GtkWidget
*dock_item
= NULL
;
195 GtkWidget
*widget
= NULL
;
198 /* AnjutaWindow assertions */
199 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
200 win
= ANJUTA_WINDOW (shell
);
202 /* If win->maximized is TRUE then another widget is already maximized.
203 Restoring the UI for a new maximization. */
205 gdl_dock_layout_load_layout (win
->layout_manager
, "back-up");
207 /* Back-up the layout so it can be restored */
208 gdl_dock_layout_save_layout(win
->layout_manager
, "back-up");
210 /* Mark the win as maximized (the other widgets except center are hidden) */
211 win
->maximized
= TRUE
;
213 /* Hide all DockItem's except the ones positioned in the center */
214 g_hash_table_iter_init (&iter
, win
->widgets
);
215 while (g_hash_table_iter_next (&iter
, &key
, &value
))
220 /* Widget assertions */
221 widget
= GTK_WIDGET (value
);
222 if(!GTK_IS_WIDGET (widget
))
225 /* DockItem assertions */
226 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
227 if(dock_item
== NULL
|| !GDL_IS_DOCK_ITEM (dock_item
))
230 if(!g_strcmp0((gchar
*)key
, widget_name
))
232 /* If it's the widget requesting maximization then make sure the
233 * widget is visible*/
234 gdl_dock_item_show_item (GDL_DOCK_ITEM (dock_item
));
238 /* Hide the other item */
239 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dock_item
));
245 anjuta_window_unmaximize (AnjutaShell
*shell
,
248 AnjutaWindow
*win
= NULL
;
250 /* AnjutaWindow assertions */
251 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
252 win
= ANJUTA_WINDOW (shell
);
254 /* If not maximized then the operation doesn't make sence. */
255 g_return_if_fail (win
->maximized
);
257 /* Load the backed-up layout */
258 gdl_dock_layout_load_layout (win
->layout_manager
, "back-up");
259 gdl_dock_layout_delete_layout (win
->layout_manager
, "back-up");
261 /* Un-mark maximized */
262 win
->maximized
= FALSE
;
266 anjuta_window_create_window (AnjutaShell
*shell
,
269 AnjutaWindow
*win
= NULL
;
270 AnjutaApplication
*app
;
272 /* AnjutaWindow assertions */
273 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
275 app
= ANJUTA_APPLICATION (gtk_window_get_application (GTK_WINDOW (shell
)));
276 win
= anjuta_application_create_window (ANJUTA_APPLICATION (app
));
278 return ANJUTA_SHELL (win
);
282 on_toolbar_style_changed (GSettings
* settings
,
286 AnjutaWindow
* win
= ANJUTA_WINDOW (user_data
);
287 gchar
* tb_style
= g_settings_get_string (settings
, key
);
289 if (strcasecmp (tb_style
, "Default") == 0)
291 else if (strcasecmp (tb_style
, "Both") == 0)
292 style
= GTK_TOOLBAR_BOTH
;
293 else if (strcasecmp (tb_style
, "Horiz") == 0)
294 style
= GTK_TOOLBAR_BOTH_HORIZ
;
295 else if (strcasecmp (tb_style
, "Icons") == 0)
296 style
= GTK_TOOLBAR_ICONS
;
297 else if (strcasecmp (tb_style
, "Text") == 0)
298 style
= GTK_TOOLBAR_TEXT
;
302 gtk_toolbar_set_style (GTK_TOOLBAR (win
->toolbar
), style
);
306 gtk_toolbar_unset_style (GTK_TOOLBAR (win
->toolbar
));
312 on_gdl_style_changed (GSettings
* settings
,
316 AnjutaWindow
* win
= ANJUTA_WINDOW (user_data
);
317 GdlSwitcherStyle style
= GDL_SWITCHER_STYLE_BOTH
;
319 gchar
* pr_style
= g_settings_get_string (settings
, key
);
321 if (strcasecmp (pr_style
, "Text") == 0)
322 style
= GDL_SWITCHER_STYLE_TEXT
;
323 else if (strcasecmp (pr_style
, "Icon") == 0)
324 style
= GDL_SWITCHER_STYLE_ICON
;
325 else if (strcasecmp (pr_style
, "Both") == 0)
326 style
= GDL_SWITCHER_STYLE_BOTH
;
327 else if (strcasecmp (pr_style
, "Toolbar") == 0)
328 style
= GDL_SWITCHER_STYLE_TOOLBAR
;
329 else if (strcasecmp (pr_style
, "Tabs") == 0)
330 style
= GDL_SWITCHER_STYLE_TABS
;
332 g_object_set (gdl_dock_layout_get_master (win
->layout_manager
), "switcher-style",
338 on_toggle_widget_view (GtkCheckMenuItem
*menuitem
, GtkWidget
*dockitem
)
341 state
= gtk_check_menu_item_get_active (menuitem
);
343 gdl_dock_item_show_item (GDL_DOCK_ITEM (dockitem
));
345 gdl_dock_item_hide_item (GDL_DOCK_ITEM (dockitem
));
349 on_update_widget_view_menuitem (gpointer key
, gpointer wid
, gpointer data
)
351 GtkCheckMenuItem
*menuitem
;
352 GdlDockItem
*dockitem
;
354 dockitem
= g_object_get_data (G_OBJECT (wid
), "dockitem");
355 menuitem
= g_object_get_data (G_OBJECT (wid
), "menuitem");
357 g_signal_handlers_block_by_func (menuitem
,
358 G_CALLBACK (on_toggle_widget_view
),
361 if (GDL_DOCK_OBJECT_ATTACHED (dockitem
))
362 gtk_check_menu_item_set_active (menuitem
, TRUE
);
364 gtk_check_menu_item_set_active (menuitem
, FALSE
);
366 g_signal_handlers_unblock_by_func (menuitem
,
367 G_CALLBACK (on_toggle_widget_view
),
372 on_layout_dirty_notify (GObject
*object
, GParamSpec
*pspec
, gpointer user_data
)
374 if (!strcmp (pspec
->name
, "dirty")) {
376 g_object_get (object
, "dirty", &dirty
, NULL
);
378 /* Update UI toggle buttons */
379 g_hash_table_foreach (ANJUTA_WINDOW (user_data
)->widgets
,
380 on_update_widget_view_menuitem
,
387 on_layout_locked_notify (GdlDockMaster
*master
, GParamSpec
*pspec
,
395 action
= anjuta_ui_get_action (ui
, "ActionGroupToggleView",
396 "ActionViewLockLayout");
398 g_object_get (master
, "locked", &locked
, NULL
);
399 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
404 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
405 AnjutaSession
*session
, AnjutaWindow
*win
)
407 gchar
*geometry
, *layout_file
;
408 GdkWindowState state
;
410 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
414 state
= gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (win
)));
415 if (state
& GDK_WINDOW_STATE_MAXIMIZED
) {
416 anjuta_session_set_int (session
, "Anjuta", "Maximized", 1);
418 if (state
& GDK_WINDOW_STATE_FULLSCREEN
) {
419 anjuta_session_set_int (session
, "Anjuta", "Fullscreen", 1);
422 /* Save geometry only if window is not maximized or fullscreened */
423 if (!(state
& GDK_WINDOW_STATE_MAXIMIZED
) ||
424 !(state
& GDK_WINDOW_STATE_FULLSCREEN
))
426 geometry
= anjuta_window_get_geometry (win
);
428 anjuta_session_set_string (session
, "Anjuta", "Geometry",
434 layout_file
= g_build_filename (anjuta_session_get_session_directory (session
),
435 "dock-layout.xml", NULL
);
436 anjuta_window_layout_save (win
, layout_file
, NULL
);
437 g_free (layout_file
);
441 on_session_load (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
442 AnjutaSession
*session
, AnjutaWindow
*win
)
444 if (phase
== ANJUTA_SESSION_PHASE_START
)
446 AnjutaApplication
*app
;
448 app
= ANJUTA_APPLICATION (gtk_window_get_application (GTK_WINDOW (win
)));
451 if (anjuta_application_get_no_session (app
))
454 anjuta_session_clear (session
);
456 else if (anjuta_application_get_no_files (app
))
458 /* Clear files from session */
459 anjuta_session_set_string_list (session
, "File Loader",
462 if (anjuta_application_get_geometry (app
))
464 /* Set new geometry */
465 anjuta_session_set_string (session
, "Anjuta", "Geometry",
466 anjuta_application_get_geometry (app
));
471 /* We load layout at last so that all plugins would have loaded by now */
472 if (phase
== ANJUTA_SESSION_PHASE_LAST
)
477 /* Restore geometry */
478 geometry
= anjuta_session_get_string (session
, "Anjuta", "Geometry");
479 anjuta_window_set_geometry (win
, geometry
);
482 /* Restore window state */
483 if (anjuta_session_get_int (session
, "Anjuta", "Fullscreen"))
486 AnjutaUI
* ui
= anjuta_shell_get_ui(shell
, NULL
);
487 GtkAction
* action
= anjuta_ui_get_action (ui
, "ActionGroupToggleView",
488 "ActionViewFullscreen");
489 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
492 gtk_window_fullscreen (GTK_WINDOW (shell
));
495 else if (anjuta_session_get_int (session
, "Anjuta", "Maximized"))
497 gtk_window_maximize (GTK_WINDOW (shell
));
501 gtk_window_unmaximize (GTK_WINDOW (shell
));
503 gtk_widget_show (GTK_WIDGET (win
));
506 layout_file
= g_build_filename (anjuta_session_get_session_directory (session
),
507 "dock-layout.xml", NULL
);
508 anjuta_window_layout_load (win
, layout_file
, NULL
);
509 g_free (layout_file
);
514 anjuta_window_dispose (GObject
*widget
)
518 g_return_if_fail (ANJUTA_IS_WINDOW (widget
));
520 win
= ANJUTA_WINDOW (widget
);
524 if (g_hash_table_size (win
->widgets
) > 0)
527 g_warning ("Some widgets are still inside shell (%d widgets), they are:",
528 g_hash_table_size (win->widgets));
529 g_hash_table_foreach (win->widgets, (GHFunc)puts, NULL);
532 g_hash_table_destroy (win
->widgets
);
538 if (g_hash_table_size (win
->values
) > 0)
541 g_warning ("Some Values are still left in shell (%d Values), they are:",
542 g_hash_table_size (win->values));
543 g_hash_table_foreach (win->values, (GHFunc)puts, NULL);
546 g_hash_table_destroy (win
->values
);
550 g_object_unref (win
->ui
);
553 if (win
->preferences
)
555 g_object_unref (win
->preferences
);
556 win
->preferences
= NULL
;
558 if (win
->layout_manager
) {
559 /* Disconnect signal handlers so we don't get any signals after we're
561 g_signal_handlers_disconnect_by_func (win
->layout_manager
, on_layout_dirty_notify
,
563 g_signal_handlers_disconnect_by_func (gdl_dock_layout_get_master (win
->layout_manager
),
564 on_layout_locked_notify
, win
);
565 g_object_unref (win
->layout_manager
);
566 win
->layout_manager
= NULL
;
568 if (win
->profile_manager
) {
569 g_object_unref (G_OBJECT (win
->profile_manager
));
570 win
->profile_manager
= NULL
;
572 if (win
->plugin_manager
) {
573 g_object_unref (G_OBJECT (win
->plugin_manager
));
574 win
->plugin_manager
= NULL
;
577 g_object_unref (G_OBJECT (win
->status
));
582 g_object_unref (win
->settings
);
583 win
->settings
= NULL
;
586 G_OBJECT_CLASS (parent_class
)->dispose (widget
);
590 anjuta_window_instance_init (AnjutaWindow
*win
)
592 GtkWidget
*menubar
, *about_menu
;
593 GtkWidget
*view_menu
, *hbox
;
597 GList
*plugins_dirs
= NULL
;
598 GdkGeometry size_hints
= {
599 100, 100, 0, 0, 100, 100, 1, 1, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
602 DEBUG_PRINT ("%s", "Initializing Anjuta...");
604 gtk_window_set_geometry_hints (GTK_WINDOW (win
), GTK_WIDGET (win
),
605 &size_hints
, GDK_HINT_RESIZE_INC
);
606 gtk_window_set_resizable (GTK_WINDOW (win
), TRUE
);
611 main_box
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
612 gtk_container_add (GTK_CONTAINER (win
), main_box
);
613 gtk_widget_show (main_box
);
617 win
->maximized
= FALSE
;
620 win
->settings
= g_settings_new (PREF_SCHEMA
);
623 win
->status
= ANJUTA_STATUS (anjuta_status_new ());
624 anjuta_status_set_title_window (win
->status
, GTK_WIDGET (win
));
625 gtk_widget_show (GTK_WIDGET (win
->status
));
626 gtk_box_pack_end (GTK_BOX (main_box
),
627 GTK_WIDGET (win
->status
), FALSE
, TRUE
, 0);
628 g_object_ref (G_OBJECT (win
->status
));
629 g_object_add_weak_pointer (G_OBJECT (win
->status
), (gpointer
)&win
->status
);
632 hbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 0);
633 gtk_widget_show (hbox
);
634 win
->dock
= gdl_dock_new ();
635 gtk_widget_show (win
->dock
);
636 gtk_box_pack_end(GTK_BOX (hbox
), win
->dock
, TRUE
, TRUE
, 0);
638 dockbar
= gdl_dock_bar_new (G_OBJECT (win
->dock
));
639 gtk_widget_show (dockbar
);
640 gtk_box_pack_start(GTK_BOX (hbox
), dockbar
, FALSE
, FALSE
, 0);
642 win
->layout_manager
= gdl_dock_layout_new (G_OBJECT (win
->dock
));
643 g_signal_connect (win
->layout_manager
, "notify::dirty",
644 G_CALLBACK (on_layout_dirty_notify
), win
);
645 g_signal_connect (gdl_dock_layout_get_master (win
->layout_manager
), "notify::locked",
646 G_CALLBACK (on_layout_locked_notify
), win
);
649 win
->ui
= anjuta_ui_new ();
650 g_object_add_weak_pointer (G_OBJECT (win
->ui
), (gpointer
)&win
->ui
);
651 /* show tooltips in the statusbar */
652 g_signal_connect (win
->ui
,
654 G_CALLBACK (connect_proxy_cb
),
656 g_signal_connect (win
->ui
,
658 G_CALLBACK (disconnect_proxy_cb
),
662 plugins_dirs
= g_list_prepend (plugins_dirs
, PACKAGE_PLUGIN_DIR
);
663 win
->plugin_manager
= anjuta_plugin_manager_new (G_OBJECT (win
),
666 win
->profile_manager
= anjuta_profile_manager_new (win
->plugin_manager
);
667 g_list_free (plugins_dirs
);
670 win
->preferences
= anjuta_preferences_new (win
->plugin_manager
, PREF_SCHEMA
);
671 g_object_add_weak_pointer (G_OBJECT (win
->preferences
),
672 (gpointer
)&win
->preferences
);
674 g_signal_connect (win
->settings
, "changed::" GDL_STYLE
,
675 G_CALLBACK (on_gdl_style_changed
), win
);
676 on_gdl_style_changed (win
->settings
, GDL_STYLE
, win
);
678 /* Register actions */
679 anjuta_ui_add_action_group_entries (win
->ui
, "ActionGroupFile", _("File"),
681 G_N_ELEMENTS (menu_entries_file
),
682 GETTEXT_PACKAGE
, TRUE
, win
);
683 anjuta_ui_add_action_group_entries (win
->ui
, "ActionGroupEdit", _("Edit"),
685 G_N_ELEMENTS (menu_entries_edit
),
686 GETTEXT_PACKAGE
, TRUE
, win
);
687 anjuta_ui_add_action_group_entries (win
->ui
, "ActionGroupView", _("View"),
689 G_N_ELEMENTS (menu_entries_view
),
690 GETTEXT_PACKAGE
, TRUE
, win
);
691 anjuta_ui_add_toggle_action_group_entries (win
->ui
, "ActionGroupToggleView",
693 menu_entries_toggle_view
,
694 G_N_ELEMENTS (menu_entries_toggle_view
),
695 GETTEXT_PACKAGE
, TRUE
, win
);
696 anjuta_ui_add_action_group_entries (win
->ui
, "ActionGroupHelp", _("Help"),
698 G_N_ELEMENTS (menu_entries_help
),
699 GETTEXT_PACKAGE
, TRUE
, win
);
702 anjuta_ui_merge (win
->ui
, UI_FILE
);
704 /* Adding accels group */
705 gtk_window_add_accel_group (GTK_WINDOW (win
),
706 gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (win
->ui
)));
708 /* create main menu */
709 menubar
= gtk_ui_manager_get_widget (GTK_UI_MANAGER (win
->ui
),
711 gtk_box_pack_start (GTK_BOX (main_box
), menubar
, FALSE
, FALSE
, 0);
712 gtk_widget_show (menubar
);
715 win
->toolbar
= gtk_ui_manager_get_widget (GTK_UI_MANAGER (win
->ui
),
717 if (!g_settings_get_boolean (win
->settings
, TOOLBAR_VISIBLE
))
718 gtk_widget_hide (win
->toolbar
);
719 gtk_style_context_add_class (gtk_widget_get_style_context (win
->toolbar
),
720 GTK_STYLE_CLASS_PRIMARY_TOOLBAR
);
721 gtk_toolbar_set_icon_size (GTK_TOOLBAR (win
->toolbar
),
723 gtk_box_pack_start (GTK_BOX (main_box
), win
->toolbar
, FALSE
, FALSE
, 0);
724 action
= gtk_ui_manager_get_action (GTK_UI_MANAGER (win
->ui
),
725 "/MenuMain/MenuView/Toolbar");
726 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action
),
727 g_settings_get_boolean (win
->settings
,
729 g_signal_connect (win
->settings
, "changed::" TOOLBAR_STYLE
,
730 G_CALLBACK (on_toolbar_style_changed
), win
);
731 on_toolbar_style_changed (win
->settings
, TOOLBAR_STYLE
, win
);
733 /* Create widgets menu */
735 gtk_ui_manager_get_widget (GTK_UI_MANAGER(win
->ui
),
736 "/MenuMain/MenuView");
737 win
->view_menu
= gtk_menu_item_get_submenu (GTK_MENU_ITEM (view_menu
));
739 /* Create about plugins menu */
741 gtk_ui_manager_get_widget (GTK_UI_MANAGER(win
->ui
),
742 "/MenuMain/PlaceHolderHelpMenus/MenuHelp/"
743 "PlaceHolderHelpAbout/AboutPlugins");
744 about_create_plugins_submenu (ANJUTA_SHELL (win
), about_menu
);
747 gtk_box_pack_start (GTK_BOX (main_box
), hbox
, TRUE
, TRUE
, 0);
749 /* Connect to session */
750 g_signal_connect (G_OBJECT (win
), "save_session",
751 G_CALLBACK (on_session_save
), win
);
752 g_signal_connect (G_OBJECT (win
), "load_session",
753 G_CALLBACK (on_session_load
), win
);
756 anjuta_ui_load_accels (NULL
);
762 * GtkWindow catches keybindings for the menu items _before_ passing them to
763 * the focused widget. This is unfortunate and means that pressing ctrl+V
764 * in an entry on a panel ends up pasting text in the TextView.
765 * Here we override GtkWindow's handler to do the same things that it
766 * does, but in the opposite order and then we chain up to the grand
767 * parent handler, skipping gtk_window_key_press_event.
770 anjuta_window_key_press_event (GtkWidget
*widget
,
773 static gpointer grand_parent_class
= NULL
;
774 GtkWindow
*window
= GTK_WINDOW (widget
);
775 GtkWidget
*focus
= gtk_window_get_focus (window
);
776 gboolean handled
= FALSE
;
778 if (grand_parent_class
== NULL
)
779 grand_parent_class
= g_type_class_peek_parent (parent_class
);
781 /* Special case the editor - it catches all shortcuts otherwise */
782 if (GTK_SOURCE_IS_VIEW (focus
))
783 if (gtk_window_activate_key (window
, event
))
785 switch (event
->keyval
)
799 /* handle mnemonics and accelerators */
801 handled
= gtk_window_activate_key (window
, event
);
804 /* handle focus widget key events */
806 handled
= gtk_window_propagate_key_event (window
, event
);
809 /* handle mnemonics and accelerators */
811 handled
= gtk_window_activate_key (window
, event
);
813 /* Chain up, invokes binding set */
815 handled
= GTK_WIDGET_CLASS (grand_parent_class
)->key_press_event (widget
, event
);
821 anjuta_window_class_init (AnjutaWindowClass
*class)
823 GObjectClass
*object_class
;
824 GtkWidgetClass
*widget_class
;
826 parent_class
= g_type_class_peek_parent (class);
827 object_class
= (GObjectClass
*) class;
828 widget_class
= (GtkWidgetClass
*) class;
830 object_class
->dispose
= anjuta_window_dispose
;
832 widget_class
->key_press_event
= anjuta_window_key_press_event
;
836 anjuta_window_new (void)
840 win
= ANJUTA_WINDOW (g_object_new (ANJUTA_TYPE_WINDOW
,
843 return GTK_WIDGET (win
);
847 anjuta_window_get_geometry (AnjutaWindow
*win
)
850 gint width
, height
, posx
, posy
;
852 g_return_val_if_fail (ANJUTA_IS_WINDOW (win
), NULL
);
855 width
= height
= posx
= posy
= 0;
856 if (gtk_widget_get_window (GTK_WIDGET (win
)))
858 gtk_window_get_size (GTK_WINDOW (win
), &width
, &height
);
859 gtk_window_get_position (GTK_WINDOW(win
), &posx
, &posy
);
861 geometry
= g_strdup_printf ("%dx%d+%d+%d", width
, height
, posx
, posy
);
867 anjuta_window_set_geometry (AnjutaWindow
*win
, const gchar
*geometry
)
869 gint width
, height
, posx
, posy
;
870 gboolean geometry_set
= FALSE
;
872 if (geometry
&& strlen (geometry
) > 0)
874 DEBUG_PRINT ("Setting geometry: %s", geometry
);
876 if (sscanf (geometry
, "%dx%d+%d+%d", &width
, &height
,
879 if (gtk_widget_get_realized (GTK_WIDGET (win
)))
881 gtk_window_resize (GTK_WINDOW (win
), width
, height
);
885 gtk_window_set_default_size (GTK_WINDOW (win
), width
, height
);
886 gtk_window_move (GTK_WINDOW (win
), posx
, posy
);
892 g_warning ("Failed to parse geometry: %s", geometry
);
899 width
= gdk_screen_width () - 10;
900 height
= gdk_screen_height () - 25;
901 width
= (width
< 790)? width
: 790;
902 height
= (height
< 575)? width
: 575;
903 if (gtk_widget_get_realized (GTK_WIDGET (win
)) == FALSE
)
905 gtk_window_set_default_size (GTK_WINDOW (win
), width
, height
);
906 gtk_window_move (GTK_WINDOW (win
), posx
, posy
);
912 anjuta_window_layout_save (AnjutaWindow
*win
, const gchar
*filename
,
915 g_return_if_fail (ANJUTA_IS_WINDOW (win
));
916 g_return_if_fail (filename
!= NULL
);
918 /* If maximized, the layout should be loaded from the back-up first */
920 gdl_dock_layout_load_layout (win
->layout_manager
, "back-up");
922 /* Continue with the saving */
923 gdl_dock_layout_save_layout (win
->layout_manager
, name
);
924 if (!gdl_dock_layout_save_to_file (win
->layout_manager
, filename
))
925 g_warning ("Saving dock layout to '%s' failed!", filename
);
927 /* This is a good place to save the accels too */
928 anjuta_ui_save_accels (NULL
);
932 anjuta_window_layout_load (AnjutaWindow
*win
, const gchar
*layout_filename
,
935 g_return_if_fail (ANJUTA_IS_WINDOW (win
));
937 if (!layout_filename
||
938 !gdl_dock_layout_load_from_file (win
->layout_manager
, layout_filename
))
940 gchar
*datadir
, *filename
;
941 datadir
= anjuta_res_get_data_dir();
943 filename
= g_build_filename (datadir
, "layout.xml", NULL
);
944 DEBUG_PRINT ("Layout = %s", filename
);
946 if (!gdl_dock_layout_load_from_file (win
->layout_manager
, filename
))
947 g_warning ("Loading layout from '%s' failed!!", filename
);
951 if (!gdl_dock_layout_load_layout (win
->layout_manager
, name
))
952 g_warning ("Loading layout failed!!");
954 /* Layout loaded from file are not maximized */
955 win
->maximized
= FALSE
;
959 anjuta_window_layout_reset (AnjutaWindow
*win
)
961 anjuta_window_layout_load (win
, NULL
, NULL
);
965 anjuta_window_install_preferences (AnjutaWindow
*win
)
967 GtkBuilder
* builder
= gtk_builder_new ();
968 GError
* error
= NULL
;
969 GtkWidget
*notebook
, *shortcuts
, *plugins
, *remember_plugins
;
971 /* Create preferences page */
972 gtk_builder_add_from_file (builder
, GLADE_FILE
, &error
);
975 g_warning("Could not load general preferences: %s",
977 g_error_free (error
);
980 anjuta_preferences_add_from_builder (win
->preferences
, builder
, win
->settings
,
981 "General", _("General"), ICON_FILE
);
982 notebook
= GTK_WIDGET (gtk_builder_get_object (builder
, "General"));
983 shortcuts
= anjuta_ui_get_accel_editor (ANJUTA_UI (win
->ui
));
984 plugins
= anjuta_plugin_manager_get_plugins_page (win
->plugin_manager
);
985 remember_plugins
= anjuta_plugin_manager_get_remembered_plugins_page (win
->plugin_manager
);
987 gtk_widget_show (shortcuts
);
988 gtk_widget_show (plugins
);
989 gtk_widget_show (remember_plugins
);
991 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), plugins
,
992 gtk_label_new (_("Installed plugins")));
993 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), remember_plugins
,
994 gtk_label_new (_("Preferred plugins")));
995 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), shortcuts
,
996 gtk_label_new (_("Shortcuts")));
998 g_object_unref (builder
);
1001 /* AnjutaShell Implementation */
1004 on_value_removed_from_hash (gpointer value
)
1006 g_value_unset ((GValue
*)value
);
1011 anjuta_window_add_value (AnjutaShell
*shell
, const char *name
,
1012 const GValue
*value
, GError
**error
)
1017 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1018 g_return_if_fail (name
!= NULL
);
1019 g_return_if_fail (G_IS_VALUE(value
));
1021 win
= ANJUTA_WINDOW (shell
);
1023 if (win
->values
== NULL
)
1025 win
->values
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
,
1026 on_value_removed_from_hash
);
1028 anjuta_shell_remove_value (shell
, name
, error
);
1030 copy
= g_new0 (GValue
, 1);
1031 g_value_init (copy
, value
->g_type
);
1032 g_value_copy (value
, copy
);
1034 g_hash_table_insert (win
->values
, g_strdup (name
), copy
);
1035 g_signal_emit_by_name (shell
, "value_added", name
, copy
);
1039 anjuta_window_get_value (AnjutaShell
*shell
, const char *name
, GValue
*value
,
1045 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1046 g_return_if_fail (name
!= NULL
);
1047 /* g_return_if_fail (G_IS_VALUE (value)); */
1049 win
= ANJUTA_WINDOW (shell
);
1053 val
= g_hash_table_lookup (win
->values
, name
);
1058 g_value_init (value
, val
->g_type
);
1060 g_value_copy (val
, value
);
1066 *error
= g_error_new (ANJUTA_SHELL_ERROR
,
1067 ANJUTA_SHELL_ERROR_DOESNT_EXIST
,
1068 _("Value doesn't exist"));
1074 anjuta_window_remove_value (AnjutaShell
*shell
, const char *name
, GError
**error
)
1080 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1081 g_return_if_fail (name
!= NULL
);
1083 win
= ANJUTA_WINDOW (shell
);
1086 g_return_if_fail (win->values != NULL);
1087 if (win->widgets && g_hash_table_lookup_extended (win->widgets, name,
1091 item = g_object_get_data (G_OBJECT (w), "dockitem");
1092 gdl_dock_item_hide_item (GDL_DOCK_ITEM (item));
1093 gdl_dock_object_unbind (GDL_DOCK_OBJECT (item));
1098 if (win
->values
&& g_hash_table_lookup_extended (win
->values
, name
,
1100 (gpointer
)&value
)) {
1101 g_signal_emit_by_name (win
, "value_removed", name
);
1102 g_hash_table_remove (win
->values
, name
);
1107 anjuta_window_saving_push (AnjutaShell
* shell
)
1109 AnjutaWindow
* win
= ANJUTA_WINDOW (shell
);
1114 anjuta_window_saving_pop (AnjutaShell
* shell
)
1116 AnjutaWindow
* win
= ANJUTA_WINDOW (shell
);
1121 remove_from_widgets_hash (gpointer name
, gpointer hash_widget
, gpointer widget
)
1123 if (hash_widget
== widget
)
1129 on_widget_destroy (GtkWidget
*widget
, AnjutaWindow
*win
)
1131 DEBUG_PRINT ("%s", "Widget about to be destroyed");
1132 g_hash_table_foreach_remove (win
->widgets
, remove_from_widgets_hash
,
1137 on_widget_remove (GtkWidget
*container
, GtkWidget
*widget
, AnjutaWindow
*win
)
1139 GtkWidget
*dock_item
;
1141 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
1144 gchar
* unique_name
= g_object_get_data(G_OBJECT(dock_item
), "unique_name");
1145 g_free(unique_name
);
1146 g_signal_handlers_disconnect_by_func (G_OBJECT (dock_item
),
1147 G_CALLBACK (on_widget_remove
), win
);
1148 gdl_dock_item_unbind (GDL_DOCK_ITEM(dock_item
));
1150 if (g_hash_table_foreach_remove (win
->widgets
,
1151 remove_from_widgets_hash
,
1153 DEBUG_PRINT ("%s", "Widget removed from container");
1158 on_widget_removed_from_hash (gpointer widget
)
1161 GtkWidget
*menuitem
;
1162 GdlDockItem
*dockitem
;
1164 DEBUG_PRINT ("%s", "Removing widget from hash");
1166 win
= g_object_get_data (G_OBJECT (widget
), "app-object");
1167 dockitem
= g_object_get_data (G_OBJECT (widget
), "dockitem");
1168 menuitem
= g_object_get_data (G_OBJECT (widget
), "menuitem");
1170 gtk_widget_destroy (menuitem
);
1172 g_object_set_data (G_OBJECT (widget
), "dockitem", NULL
);
1173 g_object_set_data (G_OBJECT (widget
), "menuitem", NULL
);
1175 g_signal_handlers_disconnect_by_func (G_OBJECT (widget
),
1176 G_CALLBACK (on_widget_destroy
), win
);
1177 g_signal_handlers_disconnect_by_func (G_OBJECT (dockitem
),
1178 G_CALLBACK (on_widget_remove
), win
);
1180 g_object_unref (G_OBJECT (widget
));
1184 anjuta_window_setup_widget (AnjutaWindow
* win
,
1191 GtkCheckMenuItem
* menuitem
;
1193 /* Add the widget to hash */
1194 if (win
->widgets
== NULL
)
1196 win
->widgets
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
1198 on_widget_removed_from_hash
);
1200 g_hash_table_insert (win
->widgets
, g_strdup (name
), widget
);
1201 g_object_ref (widget
);
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_shell_append (GTK_MENU_SHELL (win
->view_menu
), GTK_WIDGET (menuitem
));
1210 g_object_set( G_OBJECT(menuitem
), "visible", FALSE
, NULL
);
1213 g_object_set_data (G_OBJECT (widget
), "app-object", win
);
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
), win
);
1227 g_signal_connect_after (G_OBJECT (widget
), "destroy",
1228 G_CALLBACK (on_widget_destroy
), win
);
1230 gtk_widget_show (item
);
1235 anjuta_window_add_widget_full (AnjutaShell
*shell
,
1239 const char *stock_id
,
1240 AnjutaShellPlacement placement
,
1247 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1248 g_return_if_fail (GTK_IS_WIDGET (widget
));
1249 g_return_if_fail (name
!= NULL
);
1250 g_return_if_fail (title
!= NULL
);
1252 win
= ANJUTA_WINDOW (shell
);
1254 /* Add the widget to dock */
1255 if (stock_id
== NULL
)
1256 item
= gdl_dock_item_new (name
, title
, GDL_DOCK_ITEM_BEH_NORMAL
);
1258 item
= gdl_dock_item_new_with_stock (name
, title
, stock_id
,
1259 GDL_DOCK_ITEM_BEH_NORMAL
);
1263 flags
|= GDL_DOCK_ITEM_BEH_NEVER_FLOATING
;
1264 flags
|= GDL_DOCK_ITEM_BEH_CANT_CLOSE
;
1265 flags
|= GDL_DOCK_ITEM_BEH_CANT_ICONIFY
;
1266 flags
|= GDL_DOCK_ITEM_BEH_NO_GRIP
;
1267 g_object_set(G_OBJECT(item
), "behavior", flags
, NULL
);
1270 gtk_container_add (GTK_CONTAINER (item
), widget
);
1271 gdl_dock_add_item (GDL_DOCK (win
->dock
),
1272 GDL_DOCK_ITEM (item
), placement
);
1275 gdl_dock_item_set_default_position(GDL_DOCK_ITEM(item
), GDL_DOCK_OBJECT(win
->dock
));
1277 anjuta_window_setup_widget (win
, name
, widget
, item
, title
, locked
);
1281 anjuta_window_add_widget_custom (AnjutaShell
*shell
,
1285 const char *stock_id
,
1287 AnjutaShellPlacement placement
,
1294 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1295 g_return_if_fail (GTK_IS_WIDGET (widget
));
1296 g_return_if_fail (name
!= NULL
);
1297 g_return_if_fail (title
!= NULL
);
1299 win
= ANJUTA_WINDOW (shell
);
1301 /* Add the widget to dock */
1302 /* Add the widget to dock */
1303 if (stock_id
== NULL
)
1304 item
= gdl_dock_item_new (name
, title
, GDL_DOCK_ITEM_BEH_NORMAL
);
1306 item
= gdl_dock_item_new_with_stock (name
, title
, stock_id
,
1307 GDL_DOCK_ITEM_BEH_NORMAL
);
1309 gtk_container_add (GTK_CONTAINER (item
), widget
);
1310 gdl_dock_add_item (GDL_DOCK (win
->dock
),
1311 GDL_DOCK_ITEM (item
), placement
);
1313 grip
= gdl_dock_item_get_grip (GDL_DOCK_ITEM (item
));
1315 gdl_dock_item_grip_set_label (GDL_DOCK_ITEM_GRIP (grip
), label
);
1317 anjuta_window_setup_widget (win
, name
, widget
, item
, title
, FALSE
);
1321 anjuta_window_remove_widget (AnjutaShell
*shell
, GtkWidget
*widget
,
1325 GtkWidget
*dock_item
;
1327 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1328 g_return_if_fail (GTK_IS_WIDGET (widget
));
1330 win
= ANJUTA_WINDOW (shell
);
1332 g_return_if_fail (win
->widgets
!= NULL
);
1334 dock_item
= g_object_get_data (G_OBJECT (widget
), "dockitem");
1335 g_return_if_fail (dock_item
!= NULL
);
1337 /* Remove the widget from container */
1338 g_object_ref (widget
);
1339 /* It should call on_widget_remove() and clean up should happen */
1340 gtk_container_remove (GTK_CONTAINER (dock_item
), widget
);
1341 g_object_unref (widget
);
1345 anjuta_window_present_widget (AnjutaShell
*shell
, GtkWidget
*widget
,
1349 GdlDockItem
*dock_item
;
1352 g_return_if_fail (ANJUTA_IS_WINDOW (shell
));
1353 g_return_if_fail (GTK_IS_WIDGET (widget
));
1355 win
= ANJUTA_WINDOW (shell
);
1357 g_return_if_fail (win
->widgets
!= NULL
);
1359 dock_item
= g_object_get_data (G_OBJECT(widget
), "dockitem");
1360 g_return_if_fail (dock_item
!= NULL
);
1362 /* Hack to present the dock item if it's in a notebook dock item */
1363 parent
= gtk_widget_get_parent (GTK_WIDGET(dock_item
) );
1364 if (!GDL_DOCK_OBJECT_ATTACHED (dock_item
))
1366 gdl_dock_item_show_item (GDL_DOCK_ITEM (dock_item
));
1368 if (GTK_IS_NOTEBOOK (parent
))
1371 pagenum
= gtk_notebook_page_num (GTK_NOTEBOOK (parent
), GTK_WIDGET (dock_item
));
1372 gtk_notebook_set_current_page (GTK_NOTEBOOK (parent
), pagenum
);
1375 /* FIXME: If the item is floating, present the window */
1376 /* FIXME: There is no way to detect if a widget was floating before it was
1377 detached since it no longer has a parent there is no way to access the
1378 floating property of the GdlDock structure.*/
1382 anjuta_window_get_object (AnjutaShell
*shell
, const char *iface_name
,
1385 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1386 g_return_val_if_fail (iface_name
!= NULL
, NULL
);
1387 return anjuta_plugin_manager_get_plugin (ANJUTA_WINDOW (shell
)->plugin_manager
,
1391 static AnjutaStatus
*
1392 anjuta_window_get_status (AnjutaShell
*shell
, GError
**error
)
1394 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1395 return ANJUTA_WINDOW (shell
)->status
;
1399 anjuta_window_get_ui (AnjutaShell
*shell
, GError
**error
)
1401 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1402 return ANJUTA_WINDOW (shell
)->ui
;
1405 static AnjutaPreferences
*
1406 anjuta_window_get_preferences (AnjutaShell
*shell
, GError
**error
)
1408 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1409 return ANJUTA_WINDOW (shell
)->preferences
;
1412 static AnjutaPluginManager
*
1413 anjuta_window_get_plugin_manager (AnjutaShell
*shell
, GError
**error
)
1415 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1416 return ANJUTA_WINDOW (shell
)->plugin_manager
;
1419 static AnjutaProfileManager
*
1420 anjuta_window_get_profile_manager (AnjutaShell
*shell
, GError
**error
)
1422 g_return_val_if_fail (ANJUTA_IS_WINDOW (shell
), NULL
);
1423 return ANJUTA_WINDOW (shell
)->profile_manager
;
1427 anjuta_shell_iface_init (AnjutaShellIface
*iface
)
1429 iface
->add_widget_full
= anjuta_window_add_widget_full
;
1430 iface
->add_widget_custom
= anjuta_window_add_widget_custom
;
1431 iface
->remove_widget
= anjuta_window_remove_widget
;
1432 iface
->present_widget
= anjuta_window_present_widget
;
1433 iface
->iconify_dockable_widget
= anjuta_window_iconify_dockable_widget
;
1434 iface
->hide_dockable_widget
= anjuta_window_hide_dockable_widget
;
1435 iface
->show_dockable_widget
= anjuta_window_show_dockable_widget
;
1436 iface
->maximize_widget
= anjuta_window_maximize_widget
;
1437 iface
->unmaximize
= anjuta_window_unmaximize
;
1438 iface
->create_window
= anjuta_window_create_window
;
1439 iface
->add_value
= anjuta_window_add_value
;
1440 iface
->get_value
= anjuta_window_get_value
;
1441 iface
->remove_value
= anjuta_window_remove_value
;
1442 iface
->get_object
= anjuta_window_get_object
;
1443 iface
->get_status
= anjuta_window_get_status
;
1444 iface
->get_ui
= anjuta_window_get_ui
;
1445 iface
->get_preferences
= anjuta_window_get_preferences
;
1446 iface
->get_plugin_manager
= anjuta_window_get_plugin_manager
;
1447 iface
->get_profile_manager
= anjuta_window_get_profile_manager
;
1448 iface
->saving_push
= anjuta_window_saving_push
;
1449 iface
->saving_pop
= anjuta_window_saving_pop
;
1452 ANJUTA_TYPE_BEGIN(AnjutaWindow
, anjuta_window
, GTK_TYPE_WINDOW
);
1453 ANJUTA_TYPE_ADD_INTERFACE(anjuta_shell
, ANJUTA_TYPE_SHELL
);