diff options
Diffstat (limited to 'shell/e-shell-window-private.c')
-rw-r--r-- | shell/e-shell-window-private.c | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c new file mode 100644 index 0000000000..2515f0a1eb --- /dev/null +++ b/shell/e-shell-window-private.c @@ -0,0 +1,583 @@ +/* + * e-shell-window-private.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-shell-window-private.h" + +static void +shell_window_save_switcher_style_cb (GtkRadioAction *action, + GtkRadioAction *current, + EShellWindow *shell_window) +{ + GSettings *settings; + GtkToolbarStyle style; + const gchar *string; + + settings = g_settings_new ("org.gnome.evolution.shell"); + + style = gtk_radio_action_get_current_value (action); + + switch (style) { + case GTK_TOOLBAR_ICONS: + string = "icons"; + break; + + case GTK_TOOLBAR_TEXT: + string = "text"; + break; + + case GTK_TOOLBAR_BOTH: + case GTK_TOOLBAR_BOTH_HORIZ: + string = "both"; + break; + + default: + string = "toolbar"; + break; + } + + g_settings_set_string (settings, "buttons-style", string); + g_object_unref (settings); +} + +static void +shell_window_init_switcher_style (EShellWindow *shell_window) +{ + GtkAction *action; + GSettings *settings; + GtkToolbarStyle style; + gchar *string; + + settings = g_settings_new ("org.gnome.evolution.shell"); + + action = ACTION (SWITCHER_STYLE_ICONS); + string = g_settings_get_string (settings, "buttons-style"); + g_object_unref (settings); + + if (string != NULL) { + if (strcmp (string, "icons") == 0) + style = GTK_TOOLBAR_ICONS; + else if (strcmp (string, "text") == 0) + style = GTK_TOOLBAR_TEXT; + else if (strcmp (string, "both") == 0) + style = GTK_TOOLBAR_BOTH_HORIZ; + else + style = -1; + + gtk_radio_action_set_current_value ( + GTK_RADIO_ACTION (action), style); + + g_free (string); + } + + g_signal_connect ( + action, "changed", + G_CALLBACK (shell_window_save_switcher_style_cb), + shell_window); +} + +static void +shell_window_menu_item_select_cb (EShellWindow *shell_window, + GtkWidget *widget) +{ + GtkAction *action; + GtkActivatable *activatable; + GtkLabel *label; + const gchar *tooltip; + + activatable = GTK_ACTIVATABLE (widget); + action = gtk_activatable_get_related_action (activatable); + tooltip = gtk_action_get_tooltip (action); + + if (tooltip == NULL) + return; + + label = GTK_LABEL (shell_window->priv->tooltip_label); + gtk_label_set_text (label, tooltip); + + gtk_widget_show (shell_window->priv->tooltip_label); + gtk_widget_hide (shell_window->priv->status_notebook); +} + +static void +shell_window_menu_item_deselect_cb (EShellWindow *shell_window) +{ + gtk_widget_hide (shell_window->priv->tooltip_label); + gtk_widget_show (shell_window->priv->status_notebook); +} + +static void +shell_window_connect_proxy_cb (EShellWindow *shell_window, + GtkAction *action, + GtkWidget *proxy) +{ + if (!GTK_IS_MENU_ITEM (proxy)) + return; + + g_signal_connect_swapped ( + proxy, "select", + G_CALLBACK (shell_window_menu_item_select_cb), + shell_window); + + g_signal_connect_swapped ( + proxy, "deselect", + G_CALLBACK (shell_window_menu_item_deselect_cb), + shell_window); +} + +static GtkWidget * +shell_window_construct_menubar (EShellWindow *shell_window) +{ + EShellWindowClass *class; + + class = E_SHELL_WINDOW_GET_CLASS (shell_window); + if (class->construct_menubar == NULL) + return NULL; + + return class->construct_menubar (shell_window); +} + +static GtkWidget * +shell_window_construct_toolbar (EShellWindow *shell_window) +{ + EShellWindowClass *class; + + class = E_SHELL_WINDOW_GET_CLASS (shell_window); + if (class->construct_toolbar == NULL) + return NULL; + + return class->construct_toolbar (shell_window); +} + +static GtkWidget * +shell_window_construct_sidebar (EShellWindow *shell_window) +{ + EShellWindowClass *class; + + class = E_SHELL_WINDOW_GET_CLASS (shell_window); + if (class->construct_sidebar == NULL) + return NULL; + + return class->construct_sidebar (shell_window); +} + +static GtkWidget * +shell_window_construct_content (EShellWindow *shell_window) +{ + EShellWindowClass *class; + + class = E_SHELL_WINDOW_GET_CLASS (shell_window); + if (class->construct_content == NULL) + return NULL; + + return class->construct_content (shell_window); +} + +static GtkWidget * +shell_window_construct_taskbar (EShellWindow *shell_window) +{ + EShellWindowClass *class; + + class = E_SHELL_WINDOW_GET_CLASS (shell_window); + if (class->construct_taskbar == NULL) + return NULL; + + return class->construct_taskbar (shell_window); +} + +void +e_shell_window_private_init (EShellWindow *shell_window) +{ + EShellWindowPrivate *priv = shell_window->priv; + GHashTable *loaded_views; + GArray *signal_handler_ids; + + loaded_views = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + signal_handler_ids = g_array_new (FALSE, FALSE, sizeof (gulong)); + + priv->ui_manager = gtk_ui_manager_new (); + priv->loaded_views = loaded_views; + priv->signal_handler_ids = signal_handler_ids; + + /* XXX This kind of violates the shell window being unaware + * of specific shell views, but we need a sane fallback. */ + priv->active_view = "mail"; + + e_shell_window_add_action_group (shell_window, "shell"); + e_shell_window_add_action_group (shell_window, "gal-view"); + e_shell_window_add_action_group (shell_window, "new-item"); + e_shell_window_add_action_group (shell_window, "new-source"); + e_shell_window_add_action_group (shell_window, "custom-rules"); + e_shell_window_add_action_group (shell_window, "switcher"); + e_shell_window_add_action_group (shell_window, "new-window"); + e_shell_window_add_action_group (shell_window, "lockdown-application-handlers"); + e_shell_window_add_action_group (shell_window, "lockdown-printing"); + e_shell_window_add_action_group (shell_window, "lockdown-print-setup"); + e_shell_window_add_action_group (shell_window, "lockdown-save-to-disk"); + + gtk_window_set_title (GTK_WINDOW (shell_window), _("Evolution")); + + g_signal_connect_swapped ( + priv->ui_manager, "connect-proxy", + G_CALLBACK (shell_window_connect_proxy_cb), shell_window); +} + +void +e_shell_window_private_constructed (EShellWindow *shell_window) +{ + EShellWindowPrivate *priv = shell_window->priv; + EShell *shell; + GtkAction *action; + GtkAccelGroup *accel_group; + GtkUIManager *ui_manager; + GtkBox *box; + GtkPaned *paned; + GtkWidget *widget; + GtkWindow *window; + guint merge_id; + const gchar *id; + +#ifndef G_OS_WIN32 + GSettings *settings; + GtkActionGroup *action_group; +#endif + + window = GTK_WINDOW (shell_window); + + shell = e_shell_window_get_shell (shell_window); + + ui_manager = e_shell_window_get_ui_manager (shell_window); + + /* Defer actions and menu merging until we have set express mode */ + + e_shell_window_actions_init (shell_window); + + accel_group = gtk_ui_manager_get_accel_group (ui_manager); + gtk_window_add_accel_group (GTK_WINDOW (shell_window), accel_group); + + merge_id = gtk_ui_manager_new_merge_id (ui_manager); + priv->custom_rule_merge_id = merge_id; + + merge_id = gtk_ui_manager_new_merge_id (ui_manager); + priv->gal_view_merge_id = merge_id; + + /* Construct window widgets. */ + + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (shell_window), widget); + gtk_widget_show (widget); + + box = GTK_BOX (widget); + + widget = shell_window_construct_menubar (shell_window); + if (widget != NULL) + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + + widget = shell_window_construct_toolbar (shell_window); + if (widget != NULL) + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + + widget = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); + gtk_box_pack_start (box, widget, TRUE, TRUE, 0); + priv->content_pane = g_object_ref (widget); + gtk_widget_show (widget); + + widget = shell_window_construct_taskbar (shell_window); + if (widget != NULL) + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + + paned = GTK_PANED (priv->content_pane); + + widget = shell_window_construct_sidebar (shell_window); + if (widget != NULL) + gtk_paned_pack1 (paned, widget, FALSE, FALSE); + + widget = shell_window_construct_content (shell_window); + if (widget != NULL) + gtk_paned_pack2 (paned, widget, TRUE, FALSE); + + /* Create the switcher actions before we set the initial + * shell view, because the shell view relies on them for + * default settings during construction. */ + e_shell_window_create_switcher_actions (shell_window); + + /* Bunch of chores to do when the active view changes. */ + + g_signal_connect ( + shell_window, "notify::active-view", + G_CALLBACK (e_shell_window_update_icon), NULL); + + g_signal_connect ( + shell_window, "notify::active-view", + G_CALLBACK (e_shell_window_update_title), NULL); + + g_signal_connect ( + shell_window, "notify::active-view", + G_CALLBACK (e_shell_window_update_view_menu), NULL); + + g_signal_connect ( + shell_window, "notify::active-view", + G_CALLBACK (e_shell_window_update_search_menu), NULL); + +#ifndef G_OS_WIN32 + /* Support lockdown. */ + + settings = g_settings_new ("org.gnome.desktop.lockdown"); + + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + + g_settings_bind ( + settings, "disable-printing", + action_group, "visible", + G_SETTINGS_BIND_GET | + G_SETTINGS_BIND_INVERT_BOOLEAN); + + action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP); + + g_settings_bind ( + settings, "disable-print-setup", + action_group, "visible", + G_SETTINGS_BIND_GET | + G_SETTINGS_BIND_INVERT_BOOLEAN); + + action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK); + + g_settings_bind ( + settings, "disable-save-to-disk", + action_group, "visible", + G_SETTINGS_BIND_GET | + G_SETTINGS_BIND_INVERT_BOOLEAN); + + g_object_unref (settings); +#endif /* G_OS_WIN32 */ + + /* Bind GObject properties to GObject properties. */ + + action = ACTION (WORK_OFFLINE); + + g_object_bind_property ( + shell, "online", + action, "visible", + G_BINDING_SYNC_CREATE); + + g_object_bind_property ( + shell, "network-available", + action, "sensitive", + G_BINDING_SYNC_CREATE); + + action = ACTION (WORK_ONLINE); + + g_object_bind_property ( + shell, "online", + action, "visible", + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); + + g_object_bind_property ( + shell, "network-available", + action, "sensitive", + G_BINDING_SYNC_CREATE); + + /* Bind GObject properties to GSettings keys. */ + + settings = g_settings_new ("org.gnome.evolution.shell"); + + /* Use G_SETTINGS_BIND_GET_NO_CHANGES so shell windows + * are initialized to the most recently used shell view, + * but still allows different windows to show different + * views at once. */ + g_settings_bind ( + settings, "default-component-id", + shell_window, "active-view", + G_SETTINGS_BIND_DEFAULT | + G_SETTINGS_BIND_GET_NO_CHANGES); + + g_settings_bind ( + settings, "folder-bar-width", + priv->content_pane, "position", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind ( + settings, "sidebar-visible", + shell_window, "sidebar-visible", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind ( + settings, "statusbar-visible", + shell_window, "taskbar-visible", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind ( + settings, "buttons-visible", + shell_window, "switcher-visible", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind ( + settings, "toolbar-visible", + shell_window, "toolbar-visible", + G_SETTINGS_BIND_DEFAULT); + + /* Configure the initial size and position of the window by way + * of either a user-supplied geometry string or the last recorded + * values. Note that if a geometry string is applied, the window + * size and position are -not- recorded. */ + if (priv->geometry != NULL) { + if (!gtk_window_parse_geometry (window, priv->geometry)) + g_printerr ( + "Failed to parse geometry '%s'\n", + priv->geometry); + g_free (priv->geometry); + priv->geometry = NULL; + } else { + gtk_window_set_default_size (window, 640, 480); + e_restore_window ( + window, "/org/gnome/evolution/shell/window/", + E_RESTORE_WINDOW_SIZE | E_RESTORE_WINDOW_POSITION); + } + + shell_window_init_switcher_style (shell_window); + + id = "org.gnome.evolution.shell"; + e_plugin_ui_register_manager (ui_manager, id, shell_window); + e_plugin_ui_enable_manager (ui_manager, id); + + gtk_application_add_window (GTK_APPLICATION (shell), window); + + g_object_unref (settings); +} + +void +e_shell_window_private_dispose (EShellWindow *shell_window) +{ + EShellWindowPrivate *priv = shell_window->priv; + + /* Need to disconnect handlers before we unref the shell. */ + if (priv->signal_handler_ids != NULL) { + GArray *array = priv->signal_handler_ids; + gulong handler_id; + guint ii; + + for (ii = 0; ii < array->len; ii++) { + handler_id = g_array_index (array, gulong, ii); + g_signal_handler_disconnect (priv->shell, handler_id); + } + + g_array_free (array, TRUE); + priv->signal_handler_ids = NULL; + } + + if (priv->shell != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->shell), &priv->shell); + priv->shell = NULL; + } + + g_clear_object (&priv->focus_tracker); + g_clear_object (&priv->ui_manager); + + g_hash_table_remove_all (priv->loaded_views); + + g_clear_object (&priv->alert_bar); + g_clear_object (&priv->content_pane); + g_clear_object (&priv->content_notebook); + g_clear_object (&priv->sidebar_notebook); + g_clear_object (&priv->switcher); + g_clear_object (&priv->tooltip_label); + g_clear_object (&priv->status_notebook); + + priv->destroyed = TRUE; +} + +void +e_shell_window_private_finalize (EShellWindow *shell_window) +{ + EShellWindowPrivate *priv = shell_window->priv; + + g_hash_table_destroy (priv->loaded_views); + + g_free (priv->geometry); +} + +void +e_shell_window_switch_to_view (EShellWindow *shell_window, + const gchar *view_name) +{ + EShellView *shell_view; + + g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); + g_return_if_fail (view_name != NULL); + + if (shell_window->priv->active_view == view_name) + return; + + shell_view = e_shell_window_get_shell_view (shell_window, view_name); + + shell_window->priv->active_view = view_name; + g_object_notify (G_OBJECT (shell_window), "active-view"); + + e_shell_view_update_actions (shell_view); +} + +void +e_shell_window_update_icon (EShellWindow *shell_window) +{ + EShellView *shell_view; + GtkAction *action; + const gchar *view_name; + gchar *icon_name = NULL; + + g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); + + view_name = e_shell_window_get_active_view (shell_window); + shell_view = e_shell_window_get_shell_view (shell_window, view_name); + + action = e_shell_view_get_action (shell_view); + g_object_get (action, "icon-name", &icon_name, NULL); + gtk_window_set_icon_name (GTK_WINDOW (shell_window), icon_name); + g_free (icon_name); +} + +void +e_shell_window_update_title (EShellWindow *shell_window) +{ + EShellView *shell_view; + const gchar *view_title; + const gchar *view_name; + gchar *window_title; + + g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); + + view_name = e_shell_window_get_active_view (shell_window); + shell_view = e_shell_window_get_shell_view (shell_window, view_name); + view_title = e_shell_view_get_title (shell_view); + + /* Translators: This is used for the main window title. */ + window_title = g_strdup_printf (_("%s - Evolution"), view_title); + gtk_window_set_title (GTK_WINDOW (shell_window), window_title); + g_free (window_title); +} |