diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/e-shell-sidebar.c | 167 | ||||
-rw-r--r-- | shell/e-shell-view.c | 95 | ||||
-rw-r--r-- | shell/e-shell-view.h | 1 | ||||
-rw-r--r-- | shell/e-shell-window-actions.c | 54 | ||||
-rw-r--r-- | shell/e-shell-window-private.c | 140 | ||||
-rw-r--r-- | shell/e-shell-window-private.h | 17 | ||||
-rw-r--r-- | shell/e-shell-window.c | 98 | ||||
-rw-r--r-- | shell/test/e-test-shell-view.c | 45 |
8 files changed, 320 insertions, 297 deletions
diff --git a/shell/e-shell-sidebar.c b/shell/e-shell-sidebar.c index 560c20c278..e802523aee 100644 --- a/shell/e-shell-sidebar.c +++ b/shell/e-shell-sidebar.c @@ -31,7 +31,6 @@ struct _EShellSidebarPrivate { gpointer shell_view; /* weak pointer */ GtkWidget *event_box; - GtkWidget *image; GtkWidget *primary_label; GtkWidget *secondary_label; gchar *primary_text; @@ -40,7 +39,6 @@ struct _EShellSidebarPrivate { enum { PROP_0, - PROP_ICON_NAME, PROP_PRIMARY_TEXT, PROP_SECONDARY_TEXT, PROP_SHELL_VIEW @@ -49,34 +47,55 @@ enum { static gpointer parent_class; static void -shell_sidebar_init_icon_and_text (EShellSidebar *shell_sidebar) -{ - EShellView *shell_view; - EShellViewClass *shell_view_class; - const gchar *icon_name; - const gchar *primary_text; - - shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); - shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); - - icon_name = shell_view_class->icon_name; - e_shell_sidebar_set_icon_name (shell_sidebar, icon_name); - - primary_text = shell_view_class->label; - e_shell_sidebar_set_primary_text (shell_sidebar, primary_text); -} - -static void shell_sidebar_set_shell_view (EShellSidebar *shell_sidebar, EShellView *shell_view) { + GtkAction *action; + GtkWidget *container; + GtkWidget *widget; + gchar *label; + g_return_if_fail (shell_sidebar->priv->shell_view == NULL); shell_sidebar->priv->shell_view = shell_view; + action = e_shell_view_get_action (shell_view); g_object_add_weak_pointer ( G_OBJECT (shell_view), &shell_sidebar->priv->shell_view); + + /* Initialize the rest of the internal widgets. */ + + container = shell_sidebar->priv->event_box; + + widget = gtk_hbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (widget), 6); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + shell_sidebar->priv->primary_label = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_MIDDLE); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + shell_sidebar->priv->secondary_label = g_object_ref (widget); + gtk_widget_show (widget); + + g_object_get (action, "label", &label, NULL); + e_shell_sidebar_set_primary_text (shell_sidebar, label); + g_free (label); } static void @@ -86,12 +105,6 @@ shell_sidebar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_ICON_NAME: - e_shell_sidebar_set_icon_name ( - E_SHELL_SIDEBAR (object), - g_value_get_string (value)); - return; - case PROP_PRIMARY_TEXT: e_shell_sidebar_set_primary_text ( E_SHELL_SIDEBAR (object), @@ -121,12 +134,6 @@ shell_sidebar_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_ICON_NAME: - g_value_set_string ( - value, e_shell_sidebar_get_icon_name ( - E_SHELL_SIDEBAR (object))); - return; - case PROP_PRIMARY_TEXT: g_value_set_string ( value, e_shell_sidebar_get_primary_text ( @@ -167,11 +174,6 @@ shell_sidebar_dispose (GObject *object) priv->event_box = NULL; } - if (priv->image != NULL) { - g_object_unref (priv->image); - priv->image = NULL; - } - if (priv->primary_label != NULL) { g_object_unref (priv->primary_label); priv->primary_label = NULL; @@ -201,25 +203,6 @@ shell_sidebar_finalize (GObject *object) } static void -shell_sidebar_realize (GtkWidget *widget) -{ - EShellSidebar *shell_sidebar; - - /* We can't call this during object construction because the - * shell view is still in its instance initialization phase, - * and so its GET_CLASS() macro won't work correctly. So we - * delay the bits of our own initialization that require the - * E_SHELL_VIEW_GET_CLASS() macro until after the shell view - * is fully constructed. */ - - shell_sidebar = E_SHELL_SIDEBAR (widget); - shell_sidebar_init_icon_and_text (shell_sidebar); - - /* Chain up to parent's realize() method. */ - GTK_WIDGET_CLASS (parent_class)->realize (widget); -} - -static void shell_sidebar_size_request (GtkWidget *widget, GtkRequisition *requisition) { @@ -328,7 +311,6 @@ shell_sidebar_class_init (EShellSidebarClass *class) object_class->finalize = shell_sidebar_finalize; widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = shell_sidebar_realize; widget_class->size_request = shell_sidebar_size_request; widget_class->size_allocate = shell_sidebar_size_allocate; @@ -338,16 +320,6 @@ shell_sidebar_class_init (EShellSidebarClass *class) g_object_class_install_property ( object_class, - PROP_ICON_NAME, - g_param_spec_string ( - "icon-name", - NULL, - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, PROP_PRIMARY_TEXT, g_param_spec_string ( "primary-text", @@ -382,7 +354,6 @@ static void shell_sidebar_init (EShellSidebar *shell_sidebar) { GtkStyle *style; - GtkWidget *container; GtkWidget *widget; const GdkColor *color; @@ -399,33 +370,7 @@ shell_sidebar_init (EShellSidebar *shell_sidebar) shell_sidebar->priv->event_box = g_object_ref (widget); gtk_widget_show (widget); - container = widget; - - widget = gtk_hbox_new (FALSE, 6); - gtk_container_set_border_width (GTK_CONTAINER (widget), 6); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - shell_sidebar->priv->image = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - shell_sidebar->priv->primary_label = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_MIDDLE); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - shell_sidebar->priv->secondary_label = g_object_ref (widget); - gtk_widget_show (widget); + /* Finish initialization once we have a shell view. */ } GType @@ -472,38 +417,6 @@ e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar) } const gchar * -e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar) -{ - GtkImage *image; - const gchar *icon_name; - - g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL); - - image = GTK_IMAGE (shell_sidebar->priv->image); - gtk_image_get_icon_name (image, &icon_name, NULL); - - return icon_name; -} - -void -e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar, - const gchar *icon_name) -{ - GtkImage *image; - - g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar)); - - if (icon_name == NULL) - icon_name = "image-missing"; - - image = GTK_IMAGE (shell_sidebar->priv->image); - gtk_image_set_from_icon_name (image, icon_name, GTK_ICON_SIZE_MENU); - - gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar)); - g_object_notify (G_OBJECT (shell_sidebar), "icon-name"); -} - -const gchar * e_shell_sidebar_get_primary_text (EShellSidebar *shell_sidebar) { g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL); diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 4b388e3c93..b12f4c86f2 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -40,6 +40,7 @@ struct _EShellViewPrivate { gchar *title; gint page_num; + GtkAction *action; GtkWidget *content; GtkWidget *sidebar; GtkWidget *taskbar; @@ -49,6 +50,7 @@ struct _EShellViewPrivate { enum { PROP_0, + PROP_ACTION, PROP_PAGE_NUM, PROP_TITLE, PROP_SHELL_WINDOW, @@ -64,6 +66,21 @@ static gpointer parent_class; static gulong signals[LAST_SIGNAL]; static void +shell_view_set_action (EShellView *shell_view, + GtkAction *action) +{ + gchar *label; + + g_return_if_fail (shell_view->priv->action == NULL); + + shell_view->priv->action = g_object_ref (action); + + g_object_get (action, "label", &label, NULL); + e_shell_view_set_title (shell_view, label); + g_free (label); +} + +static void shell_view_set_page_num (EShellView *shell_view, gint page_num) { @@ -90,6 +107,12 @@ shell_view_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_ACTION: + shell_view_set_action ( + E_SHELL_VIEW (object), + g_value_get_object (value)); + return; + case PROP_PAGE_NUM: shell_view_set_page_num ( E_SHELL_VIEW (object), @@ -125,6 +148,12 @@ shell_view_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_ACTION: + g_value_set_object ( + value, e_shell_view_get_action ( + E_SHELL_VIEW (object))); + return; + case PROP_PAGE_NUM: g_value_set_int ( value, e_shell_view_get_page_num ( @@ -206,6 +235,23 @@ shell_view_finalize (GObject *object) static void shell_view_constructed (GObject *object) { + EShellView *shell_view; + GtkWidget *widget; + + shell_view = E_SHELL_VIEW (object); + + widget = e_shell_content_new (shell_view); + shell_view->priv->content = g_object_ref_sink (widget); + gtk_widget_show (widget); + + widget = e_shell_sidebar_new (shell_view); + shell_view->priv->sidebar = g_object_ref_sink (widget); + gtk_widget_show (widget); + + widget = e_shell_taskbar_new (shell_view); + shell_view->priv->taskbar = g_object_ref_sink (widget); + gtk_widget_show (widget); + /* XXX GObjectClass doesn't implement constructed(), so we will. * Then subclasses won't have to check the function pointer * before chaining up. @@ -230,6 +276,17 @@ shell_view_class_init (EShellViewClass *class) g_object_class_install_property ( object_class, + PROP_ACTION, + g_param_spec_object ( + "action", + _("Switcher Action"), + _("The switcher action for this shell view"), + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, PROP_PAGE_NUM, g_param_spec_int ( "page-num", @@ -249,8 +306,7 @@ shell_view_class_init (EShellViewClass *class) _("Title"), _("The title of the shell view"), NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); g_object_class_install_property ( object_class, @@ -286,22 +342,7 @@ shell_view_class_init (EShellViewClass *class) static void shell_view_init (EShellView *shell_view) { - GtkWidget *widget; - shell_view->priv = E_SHELL_VIEW_GET_PRIVATE (shell_view); - - widget = e_shell_content_new (shell_view); - shell_view->priv->content = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = e_shell_sidebar_new (shell_view); - shell_view->priv->sidebar = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = e_shell_taskbar_new (shell_view); - shell_view->priv->taskbar = g_object_ref_sink (widget); - gtk_widget_show (widget); - } GType @@ -331,21 +372,27 @@ e_shell_view_get_type (void) return type; } +GtkAction * +e_shell_view_get_action (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->action; +} + const gchar * e_shell_view_get_name (EShellView *shell_view) { - EShellViewClass *class; + GtkAction *action; g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); - /* A shell view's name is taken from the name of the - * module that registered the shell view subclass. */ + /* Switcher actions have a secret "view-name" data value. + * This gets set in e_shell_window_create_switcher_actions(). */ - class = E_SHELL_VIEW_GET_CLASS (shell_view); - g_return_val_if_fail (class->type_module != NULL, NULL); - g_return_val_if_fail (class->type_module->name != NULL, NULL); + action = e_shell_view_get_action (shell_view); - return class->type_module->name; + return g_object_get_data (G_OBJECT (action), "view-name"); } const gchar * diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 1654b9c6c6..cb4ffcfda0 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -76,6 +76,7 @@ struct _EShellViewClass { GType e_shell_view_get_type (void); const gchar * e_shell_view_get_name (EShellView *shell_view); +GtkAction * e_shell_view_get_action (EShellView *shell_view); const gchar * e_shell_view_get_icon_name (EShellView *shell_view); void e_shell_view_set_icon_name (EShellView *shell_view, const gchar *icon_name); diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c index c785b9bc92..090bee4025 100644 --- a/shell/e-shell-window-actions.c +++ b/shell/e-shell-window-actions.c @@ -20,12 +20,9 @@ #include "e-shell-window-private.h" -#include <string.h> - -#include <e-dialog-utils.h> -#include <e-error.h> -#include <e-print.h> -#include <e-util.h> +#include <e-util/e-dialog-utils.h> +#include <e-util/e-error.h> +#include <e-util/e-print.h> #include <gal-define-views-dialog.h> #include <libedataserverui/e-passwords.h> @@ -934,17 +931,6 @@ action_send_receive_cb (GtkAction *action, } static void -action_shell_view_cb (GtkRadioAction *action, - GtkRadioAction *current, - EShellWindow *shell_window) -{ - const gchar *view_name; - - view_name = g_object_get_data (G_OBJECT (current), "view-name"); - e_shell_window_set_current_view (shell_window, view_name); -} - -static void action_show_sidebar_cb (GtkToggleAction *action, EShellWindow *shell_window) { @@ -1020,6 +1006,17 @@ action_submit_bug_cb (GtkAction *action, } static void +action_switcher_cb (GtkRadioAction *action, + GtkRadioAction *current, + EShellWindow *shell_window) +{ + const gchar *view_name; + + view_name = g_object_get_data (G_OBJECT (current), "view-name"); + e_shell_window_switch_to_view (shell_window, view_name); +} + +static void action_switcher_style_cb (GtkRadioAction *action, GtkRadioAction *current, EShellWindow *shell_window) @@ -1528,8 +1525,8 @@ e_shell_window_actions_init (EShellWindow *shell_window) gtk_action_group_set_translation_domain (action_group, domain); gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - /* Shell View Actions (empty) */ - action_group = shell_window->priv->shell_view_actions; + /* Switcher Actions (empty) */ + action_group = shell_window->priv->switcher_actions; gtk_action_group_set_translation_domain (action_group, domain); gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); } @@ -1608,7 +1605,7 @@ e_shell_window_create_new_menu (EShellWindow *shell_window) } void -e_shell_window_create_shell_view_actions (EShellWindow *shell_window) +e_shell_window_create_switcher_actions (EShellWindow *shell_window) { GType *children; GSList *group = NULL; @@ -1616,15 +1613,12 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) GtkUIManager *ui_manager; EShellSwitcher *switcher; GList *list; - const gchar *current_view; - gint current_value = 0; guint n_children, ii; guint merge_id; g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); - action_group = shell_window->priv->shell_view_actions; - current_view = e_shell_window_get_current_view (shell_window); + action_group = shell_window->priv->switcher_actions; children = g_type_children (E_TYPE_SHELL_VIEW, &n_children); switcher = E_SHELL_SWITCHER (shell_window->priv->switcher); ui_manager = e_shell_window_get_ui_manager (shell_window); @@ -1664,13 +1658,9 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) } view_name = class->type_module->name; - action_name = g_strdup_printf ("shell-view-%s", view_name); + action_name = g_strdup_printf (SWITCHER_FORMAT, view_name); tooltip = g_strdup_printf (_("Switch to %s"), class->label); - /* Does this action represent the current view? */ - if (strcmp (view_name, current_view) == 0) - current_value = ii; - /* Note, we have to set "icon-name" separately because * gtk_radio_action_new() expects a "stock-id". Sadly, * GTK+ still distinguishes between the two. */ @@ -1720,11 +1710,8 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) g_signal_connect ( action, "changed", - G_CALLBACK (action_shell_view_cb), + G_CALLBACK (action_switcher_cb), shell_window); - - /* Sync up with the current shell view. */ - gtk_radio_action_set_current_value (action, current_value); } g_list_free (list); @@ -1754,6 +1741,7 @@ e_shell_window_update_gal_view_menu (EShellWindow *shell_window) view_name = e_shell_window_get_current_view (shell_window); shell_view = e_shell_window_get_view (shell_window, view_name); instance = e_shell_view_get_view_instance (shell_view); + g_debug ("GalViewInstance: %p", instance); action_group = shell_window->priv->gal_view_actions; merge_id = shell_window->priv->gal_view_merge_id; diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index e3c515b4b4..07b32a14f5 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -20,30 +20,6 @@ #include "e-shell-window-private.h" -#include <string.h> -#include <e-util/e-util.h> -#include <e-util/gconf-bridge.h> - -static void -shell_window_notify_current_view_cb (EShellWindow *shell_window) -{ - GtkWidget *menu; - GtkWidget *widget; - const gchar *path; - - /* Update the "File -> New" submenu. */ - path = "/main-menu/file-menu/new-menu"; - menu = e_shell_window_create_new_menu (shell_window); - widget = e_shell_window_get_managed_widget (shell_window, path); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu); - gtk_widget_show (widget); - - /* Update the "New" menu tool button submenu. */ - menu = e_shell_window_create_new_menu (shell_window); - widget = shell_window->priv->menu_tool_button; - gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), menu); -} - static void shell_window_save_switcher_style_cb (GtkRadioAction *action, GtkRadioAction *current, @@ -215,7 +191,7 @@ e_shell_window_private_init (EShellWindow *shell_window) priv->gal_view_actions = gtk_action_group_new ("gal-view"); priv->new_item_actions = gtk_action_group_new ("new-item"); priv->new_source_actions = gtk_action_group_new ("new-source"); - priv->shell_view_actions = gtk_action_group_new ("shell-view"); + priv->switcher_actions = gtk_action_group_new ("switcher"); priv->loaded_views = loaded_views; merge_id = gtk_ui_manager_new_merge_id (priv->ui_manager); @@ -332,6 +308,11 @@ e_shell_window_private_init (EShellWindow *shell_window) priv->status_notebook = g_object_ref (widget); gtk_widget_show (widget); + /* 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); + /* Bind GObject properties to GConf keys. */ bridge = gconf_bridge_get (); @@ -369,14 +350,6 @@ e_shell_window_private_init (EShellWindow *shell_window) /* Fine tuning. */ g_object_set (ACTION (SEND_RECEIVE), "is-important", TRUE, NULL); - - g_signal_connect ( - shell_window, "notify::current-view", - G_CALLBACK (shell_window_notify_current_view_cb), NULL); - - /* Initialize shell views. */ - - e_shell_window_create_shell_view_actions (shell_window); } void @@ -391,7 +364,7 @@ e_shell_window_private_dispose (EShellWindow *shell_window) DISPOSE (priv->gal_view_actions); DISPOSE (priv->new_item_actions); DISPOSE (priv->new_source_actions); - DISPOSE (priv->shell_view_actions); + DISPOSE (priv->switcher_actions); g_hash_table_remove_all (priv->loaded_views); @@ -417,3 +390,102 @@ e_shell_window_private_finalize (EShellWindow *shell_window) g_hash_table_destroy (priv->loaded_views); } + +void +e_shell_window_switch_to_view (EShellWindow *shell_window, + const gchar *view_name) +{ + GtkNotebook *notebook; + EShellView *shell_view; + GList *list; + gint page_num; + + shell_view = e_shell_window_get_view (shell_window, view_name); + + page_num = e_shell_view_get_page_num (shell_view); + g_return_if_fail (page_num >= 0); + + notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook); + gtk_notebook_set_current_page (notebook, page_num); + + notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook); + gtk_notebook_set_current_page (notebook, page_num); + + notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook); + gtk_notebook_set_current_page (notebook, page_num); + + shell_window->priv->current_view = view_name; + g_object_notify (G_OBJECT (shell_window), "current-view"); + + e_shell_window_update_icon (shell_window); + e_shell_window_update_title (shell_window); + e_shell_window_update_new_menu (shell_window); + e_shell_window_update_gal_view_menu (shell_window); + + /* Notify all loaded views. */ + list = g_hash_table_get_values (shell_window->priv->loaded_views); + g_list_foreach (list, (GFunc) e_shell_view_changed, NULL); + g_list_free (list); +} + +void +e_shell_window_update_icon (EShellWindow *shell_window) +{ + EShellView *shell_view; + GtkAction *action; + const gchar *view_name; + gchar *icon_name; + + view_name = e_shell_window_get_current_view (shell_window); + shell_view = e_shell_window_get_view (shell_window, view_name); + + if (!e_shell_view_is_selected (shell_view)) + return; + + 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; + + view_name = e_shell_window_get_current_view (shell_window); + shell_view = e_shell_window_get_view (shell_window, view_name); + view_title = e_shell_view_get_title (shell_view); + + if (!e_shell_view_is_selected (shell_view)) + return; + + /* 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); +} + +void +e_shell_window_update_new_menu (EShellWindow *shell_window) +{ + GtkWidget *menu; + GtkWidget *widget; + const gchar *path; + + /* Update the "File -> New" submenu. */ + path = "/main-menu/file-menu/new-menu"; + menu = e_shell_window_create_new_menu (shell_window); + widget = e_shell_window_get_managed_widget (shell_window, path); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu); + gtk_widget_show (widget); + + /* Update the "New" menu tool button submenu. */ + menu = e_shell_window_create_new_menu (shell_window); + widget = shell_window->priv->menu_tool_button; + gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (widget), menu); +} + diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h index ef4fa2a728..67cd51458b 100644 --- a/shell/e-shell-window-private.h +++ b/shell/e-shell-window-private.h @@ -23,8 +23,11 @@ #include "e-shell-window.h" +#include <string.h> #include <glib/gi18n.h> +#include <e-util/e-util.h> +#include <e-util/gconf-bridge.h> #include <filter/rule-editor.h> #include <widgets/misc/e-menu-tool-button.h> #include <widgets/misc/e-online-button.h> @@ -53,6 +56,11 @@ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ } G_STMT_END +/* Format for switcher action names. + * The last part is the shell view name. + * (e.g. switch-to-mail, switch-to-calendar) */ +#define SWITCHER_FORMAT "switch-to-%s" + G_BEGIN_DECLS struct _EShellWindowPrivate { @@ -66,7 +74,7 @@ struct _EShellWindowPrivate { GtkActionGroup *gal_view_actions; GtkActionGroup *new_item_actions; GtkActionGroup *new_source_actions; - GtkActionGroup *shell_view_actions; + GtkActionGroup *switcher_actions; guint gal_view_merge_id; /*** Shell Views ***/ @@ -101,9 +109,14 @@ void e_shell_window_private_finalize (EShellWindow *shell_window); /* Private Utilities */ void e_shell_window_actions_init (EShellWindow *shell_window); +void e_shell_window_switch_to_view (EShellWindow *shell_window, + const gchar *view_name); GtkWidget * e_shell_window_create_new_menu (EShellWindow *shell_window); -void e_shell_window_create_shell_view_actions +void e_shell_window_create_switcher_actions (EShellWindow *shell_window); +void e_shell_window_update_icon (EShellWindow *shell_window); +void e_shell_window_update_title (EShellWindow *shell_window); +void e_shell_window_update_new_menu (EShellWindow *shell_window); void e_shell_window_update_gal_view_menu (EShellWindow *shell_window); diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index ce144da5fa..d2b1f36ff6 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -20,70 +20,56 @@ #include "e-shell-window-private.h" -#include <string.h> -#include <glib/gi18n.h> #include <gconf/gconf-client.h> #include <es-event.h> #include <e-util/e-plugin-ui.h> #include <e-util/e-util-private.h> -#include <e-util/gconf-bridge.h> -#include <widgets/misc/e-online-button.h> enum { PROP_0, PROP_CURRENT_VIEW, + PROP_ICON_NAME, PROP_SAFE_MODE, PROP_SHELL }; static gpointer parent_class; -static void -shell_window_update_title (EShellWindow *shell_window) -{ - EShellView *shell_view; - const gchar *view_title; - const gchar *view_name; - gchar *window_title; - - view_name = e_shell_window_get_current_view (shell_window); - shell_view = e_shell_window_get_view (shell_window, view_name); - view_title = e_shell_view_get_title (shell_view); - - if (!e_shell_view_is_selected (shell_view)) - return; - - /* 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); -} - static EShellView * shell_window_new_view (EShellWindow *shell_window, GType shell_view_type, + const gchar *view_name, const gchar *title) { GHashTable *loaded_views; EShellView *shell_view; GtkNotebook *notebook; + GtkAction *action; GtkWidget *widget; - const gchar *name; + gchar *action_name; gint page_num; /* Determine the page number for the new shell view. */ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook); page_num = gtk_notebook_get_n_pages (notebook); + /* Get the switcher action for this view. */ + action_name = g_strdup_printf (SWITCHER_FORMAT, view_name); + action = e_shell_window_get_action (shell_window, action_name); + g_free (action_name); + + /* Create the shell view. */ shell_view = g_object_new ( - shell_view_type, "page-num", page_num, - "title", title, "shell-window", shell_window, NULL); + shell_view_type, "action", action, "page-num", + page_num, "shell-window", shell_window, NULL); - name = e_shell_view_get_name (shell_view); + /* Register the shell view. */ loaded_views = shell_window->priv->loaded_views; - g_hash_table_insert (loaded_views, g_strdup (name), shell_view); + g_hash_table_insert (loaded_views, g_strdup (view_name), shell_view); + + g_message ("Creating view \"%s\" on page %d", view_name, page_num); /* Add pages to the various shell window notebooks. */ @@ -99,9 +85,15 @@ shell_window_new_view (EShellWindow *shell_window, widget = GTK_WIDGET (e_shell_view_get_taskbar (shell_view)); gtk_notebook_append_page (notebook, widget, NULL); + /* Listen for changes that affect the shell window. */ + + g_signal_connect_swapped ( + action, "notify::icon_name", + G_CALLBACK (e_shell_window_update_icon), shell_window); + g_signal_connect_swapped ( shell_view, "notify::title", - G_CALLBACK (shell_window_update_title), shell_window); + G_CALLBACK (e_shell_window_update_title), shell_window); return shell_view; } @@ -352,7 +344,8 @@ e_shell_window_get_view (EShellWindow *shell_window, if (strcmp (view_name, class->type_module->name) == 0) shell_view = shell_window_new_view ( - shell_window, shell_view_type, class->label); + shell_window, shell_view_type, + view_name, class->label); g_type_class_unref (class); } @@ -463,11 +456,10 @@ void e_shell_window_set_current_view (EShellWindow *shell_window, const gchar *name_or_alias) { - GtkNotebook *notebook; + GtkAction *action; EShellView *shell_view; GList *list; const gchar *view_name; - gint page_num; g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); @@ -483,28 +475,16 @@ e_shell_window_set_current_view (EShellWindow *shell_window, g_return_if_fail (view_name != NULL); shell_view = e_shell_window_get_view (shell_window, view_name); - page_num = e_shell_view_get_page_num (shell_view); - g_return_if_fail (page_num >= 0); - - notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook); - gtk_notebook_set_current_page (notebook, page_num); - - notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook); - gtk_notebook_set_current_page (notebook, page_num); - - notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook); - gtk_notebook_set_current_page (notebook, page_num); - - shell_window->priv->current_view = view_name; - g_object_notify (G_OBJECT (shell_window), "current-view"); - - shell_window_update_title (shell_window); - e_shell_window_update_gal_view_menu (shell_window); - - /* Notify all loaded views. */ - list = g_hash_table_get_values (shell_window->priv->loaded_views); - g_list_foreach (list, (GFunc) e_shell_view_changed, NULL); - g_list_free (list); + action = e_shell_view_get_action (shell_view); + gtk_action_activate (action); + + /* XXX Radio actions refuse to activate if they're already active. + * This causes problems during intialization if we're trying to + * switch to the shell view whose corresponding radio action is + * already active. Fortunately we can detect that and force + * the switch. */ + if (shell_window->priv->current_view == NULL) + e_shell_window_switch_to_view (shell_window, view_name); } gboolean @@ -569,8 +549,7 @@ e_shell_window_register_new_item_actions (EShellWindow *shell_window, "module-name", (gpointer) module_name); } - /* Force a rebuild of the "New" menu. */ - g_object_notify (G_OBJECT (shell_window), "current-view"); + e_shell_window_update_new_menu (shell_window); } void @@ -616,6 +595,5 @@ e_shell_window_register_new_source_actions (EShellWindow *shell_window, "module-name", (gpointer) module_name); } - /* Force a rebuild of the "New" menu. */ - g_object_notify (G_OBJECT (shell_window), "current-view"); + e_shell_window_update_new_menu (shell_window); } diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c index ea771e0982..be2a747354 100644 --- a/shell/test/e-test-shell-view.c +++ b/shell/test/e-test-shell-view.c @@ -43,14 +43,42 @@ test_shell_view_changed (EShellView *shell_view) } static void +test_shell_view_constructed (GObject *object) +{ + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellView *shell_view; + GtkWidget *widget; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_view = E_SHELL_VIEW (object); + shell_content = e_shell_view_get_content (shell_view); + shell_sidebar = e_shell_view_get_sidebar (shell_view); + + widget = gtk_label_new ("Content Widget"); + gtk_container_add (GTK_CONTAINER (shell_content), widget); + gtk_widget_show (widget); + + widget = gtk_label_new ("Sidebar Widget"); + gtk_container_add (GTK_CONTAINER (shell_sidebar), widget); + gtk_widget_show (widget); +} + +static void test_shell_view_class_init (ETestShellViewClass *class, GTypeModule *type_module) { + GObjectClass *object_class; EShellViewClass *shell_view_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (ETestShellViewPrivate)); + object_class = G_OBJECT_CLASS (class); + object_class->constructed = test_shell_view_constructed; + shell_view_class = E_SHELL_VIEW_CLASS (class); shell_view_class->label = "Test"; shell_view_class->icon_name = "face-monkey"; @@ -61,25 +89,8 @@ test_shell_view_class_init (ETestShellViewClass *class, static void test_shell_view_init (ETestShellView *test_shell_view) { - EShellContent *shell_content; - EShellSidebar *shell_sidebar; - EShellView *shell_view; - GtkWidget *widget; - test_shell_view->priv = E_TEST_SHELL_VIEW_GET_PRIVATE (test_shell_view); - - shell_view = E_SHELL_VIEW (test_shell_view); - shell_content = e_shell_view_get_content (shell_view); - shell_sidebar = e_shell_view_get_sidebar (shell_view); - - widget = gtk_label_new ("Content Widget"); - gtk_container_add (GTK_CONTAINER (shell_content), widget); - gtk_widget_show (widget); - - widget = gtk_label_new ("Sidebar Widget"); - gtk_container_add (GTK_CONTAINER (shell_sidebar), widget); - gtk_widget_show (widget); } GType |