[evolution] Add private virtual methods to EShellWindowClass.



commit 793e57e24ca2ac458baa0897ad971dfbf08e8291
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Dec 1 19:38:52 2009 -0500

    Add private virtual methods to EShellWindowClass.
    
    So Anjal can override what it needs to for its own purpose.
    Also makes the EShellWindow design a little cleaner.
    
    Methods added:
    
      GtkWidget *    (*construct_menubar)   (EShellWindow *shell_window);
      GtkWidget *    (*construct_toolbar)   (EShellWindow *shell_window);
      GtkWidget *    (*construct_sidebar)   (EShellWindow *shell_window);
      GtkWidget *    (*construct_content)   (EShellWindow *shell_window);
      GtkWidget *    (*construct_taskbar)   (EShellWindow *shell_window);
      EShellView *   (*create_shell_view)   (EShellWindow *shell_window,
                                             const gchar *view_name);
    
    Also added some new GObject properties to help decouple actions from
    internal EShellWindow widgets created by these methods:
    
      EShellWindow:sidebar-visible
      EShellWindow:switcher-visible
      EShellWindow:taskbar-visible
      EShellWindow:toolbar-visible

 doc/reference/shell/eshell-docs.sgml          |    2 +-
 doc/reference/shell/eshell-sections.txt       |   53 ++-
 doc/reference/shell/tmpl/e-alert.sgml         |  173 +++++++
 doc/reference/shell/tmpl/e-error.sgml         |   19 -
 doc/reference/shell/tmpl/e-shell-taskbar.sgml |    9 +
 doc/reference/shell/tmpl/e-shell-window.sgml  |   92 ++++
 doc/reference/shell/tmpl/eshell-unused.sgml   |   31 ++
 doc/reference/shell/tmpl/shell-actions.sgml   |    4 +-
 shell/e-shell-window-actions.c                |   97 ++---
 shell/e-shell-window-actions.h                |    4 +-
 shell/e-shell-window-private.c                |  282 ++++-------
 shell/e-shell-window-private.h                |   13 +-
 shell/e-shell-window.c                        |  657 +++++++++++++++++++++----
 shell/e-shell-window.h                        |   30 ++
 ui/evolution-shell.ui                         |    2 +-
 15 files changed, 1090 insertions(+), 378 deletions(-)
---
diff --git a/doc/reference/shell/eshell-docs.sgml b/doc/reference/shell/eshell-docs.sgml
index 78a9e5a..9c4e875 100644
--- a/doc/reference/shell/eshell-docs.sgml
+++ b/doc/reference/shell/eshell-docs.sgml
@@ -28,12 +28,12 @@ url="http://mbarnes.fedorapeople.org/docs/eshell/";>http://mbarnes.fedorapeople.o
   <chapter>
     <title>Basic Utility Functions</title>
     <xi:include href="xml/e-account-utils.xml"/>
+    <xi:include href="xml/e-alert.xml"/>
     <xi:include href="xml/e-bit-array.xml"/>
     <xi:include href="xml/e-binding.xml"/>
     <xi:include href="xml/e-categories-config.xml"/>
     <xi:include href="xml/e-datetime-format.xml"/>
     <xi:include href="xml/e-dialog-utils.xml"/>
-    <xi:include href="xml/e-error.xml"/>
     <xi:include href="xml/e-html-utils.xml"/>
     <xi:include href="xml/e-icon-factory.xml"/>
     <xi:include href="xml/e-logger.xml"/>
diff --git a/doc/reference/shell/eshell-sections.txt b/doc/reference/shell/eshell-sections.txt
index 491d1b2..e43bc6d 100644
--- a/doc/reference/shell/eshell-sections.txt
+++ b/doc/reference/shell/eshell-sections.txt
@@ -202,6 +202,7 @@ e_shell_taskbar_get_shell_view
 e_shell_taskbar_get_message
 e_shell_taskbar_set_message
 e_shell_taskbar_unset_message
+e_shell_taskbar_get_activity_count
 <SUBSECTION Standard>
 E_SHELL_TASKBAR
 E_IS_SHELL_TASKBAR
@@ -279,6 +280,14 @@ e_shell_window_set_active_view
 e_shell_window_get_safe_mode
 e_shell_window_set_safe_mode
 e_shell_window_add_action_group
+e_shell_window_get_sidebar_visible
+e_shell_window_set_sidebar_visible
+e_shell_window_get_switcher_visible
+e_shell_window_set_switcher_visible
+e_shell_window_get_taskbar_visible
+e_shell_window_set_taskbar_visible
+e_shell_window_get_toolbar_visible
+e_shell_window_set_toolbar_visible
 e_shell_window_register_new_item_actions
 e_shell_window_register_new_source_actions
 <SUBSECTION Standard>
@@ -307,6 +316,29 @@ e_get_account_by_uid
 </SECTION>
 
 <SECTION>
+<FILE>e-alert</FILE>
+<TITLE>User Alert Handling</TITLE>
+E_ALERT_INFO
+E_ALERT_INFO_PRIMARY
+E_ALERT_WARNING
+E_ALERT_WARNING_PRIMARY
+E_ALERT_ERROR
+E_ALERT_ERROR_PRIMARY
+E_ALERT_ASK_FILE_EXISTS_OVERWRITE
+E_ALERT_NO_SAVE_FILE
+E_ALERT_NO_LOAD_FILE
+EAlert
+e_alert_new
+e_alert_newv
+e_alert_free
+e_alert_new_dialog
+e_alert_new_dialog_for_args
+e_alert_run_dialog
+e_alert_run_dialog_for_args
+e_alert_dialog_count_buttons
+</SECTION>
+
+<SECTION>
 <FILE>e-binding</FILE>
 <TITLE>GObject Property Bindings</TITLE>
 EBinding
@@ -383,25 +415,6 @@ e_dialog_combo_box_get
 </SECTION>
 
 <SECTION>
-<FILE>e-error</FILE>
-<TITLE>Error Dialogs</TITLE>
-E_ERROR_INFO
-E_ERROR_INFO_PRIMARY
-E_ERROR_WARNING
-E_ERROR_WARNING_PRIMARY
-E_ERROR_ERROR
-E_ERROR_ERROR_PRIMARY
-E_ERROR_ASK_FILE_EXISTS_OVERWRITE
-E_ERROR_NO_SAVE_FILE
-E_ERROR_NO_LOAD_FILE
-e_error_new
-e_error_newv
-e_error_run
-e_error_runv
-e_error_count_buttons
-</SECTION>
-
-<SECTION>
 <FILE>e-html-utils</FILE>
 <TITLE>Text to HTML Conversion</TITLE>
 E_TEXT_TO_HTML_PRE
@@ -682,8 +695,8 @@ E_SHELL_WINDOW_ACTION_SEARCH_QUICK
 E_SHELL_WINDOW_ACTION_SEARCH_SAVE
 E_SHELL_WINDOW_ACTION_SEND_RECEIVE
 E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR
-E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR
 E_SHELL_WINDOW_ACTION_SHOW_SWITCHER
+E_SHELL_WINDOW_ACTION_SHOW_TASKBAR
 E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR
 E_SHELL_WINDOW_ACTION_SUBMIT_BUG
 E_SHELL_WINDOW_ACTION_SWITCHER_INITIAL
diff --git a/doc/reference/shell/tmpl/e-alert.sgml b/doc/reference/shell/tmpl/e-alert.sgml
new file mode 100644
index 0000000..d61c8a5
--- /dev/null
+++ b/doc/reference/shell/tmpl/e-alert.sgml
@@ -0,0 +1,173 @@
+<!-- ##### SECTION Title ##### -->
+User Alert Handling
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### MACRO E_ALERT_INFO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_INFO_PRIMARY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_WARNING ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_WARNING_PRIMARY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_ERROR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_ERROR_PRIMARY ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_ASK_FILE_EXISTS_OVERWRITE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_NO_SAVE_FILE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO E_ALERT_NO_LOAD_FILE ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### STRUCT EAlert ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION e_alert_new ##### -->
+<para>
+
+</para>
+
+ tag: 
+ arg0: 
+ Varargs: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_newv ##### -->
+<para>
+
+</para>
+
+ tag: 
+ arg0: 
+ ap: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_free ##### -->
+<para>
+
+</para>
+
+ alert: 
+
+
+<!-- ##### FUNCTION e_alert_new_dialog ##### -->
+<para>
+
+</para>
+
+ parent: 
+ alert: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_new_dialog_for_args ##### -->
+<para>
+
+</para>
+
+ parent: 
+ tag: 
+ arg0: 
+ Varargs: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_run_dialog ##### -->
+<para>
+
+</para>
+
+ parent: 
+ alert: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_run_dialog_for_args ##### -->
+<para>
+
+</para>
+
+ parent: 
+ tag: 
+ arg0: 
+ Varargs: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_alert_dialog_count_buttons ##### -->
+<para>
+
+</para>
+
+ dialog: 
+ Returns: 
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-taskbar.sgml b/doc/reference/shell/tmpl/e-shell-taskbar.sgml
index 6aa90f1..f1bbdf0 100644
--- a/doc/reference/shell/tmpl/e-shell-taskbar.sgml
+++ b/doc/reference/shell/tmpl/e-shell-taskbar.sgml
@@ -77,3 +77,12 @@ EShellTaskbar
 @shell_taskbar: 
 
 
+<!-- ##### FUNCTION e_shell_taskbar_get_activity_count ##### -->
+<para>
+
+</para>
+
+ shell_taskbar: 
+ Returns: 
+
+
diff --git a/doc/reference/shell/tmpl/e-shell-window.sgml b/doc/reference/shell/tmpl/e-shell-window.sgml
index 0020ae1..33a5928 100644
--- a/doc/reference/shell/tmpl/e-shell-window.sgml
+++ b/doc/reference/shell/tmpl/e-shell-window.sgml
@@ -43,6 +43,26 @@ EShellWindow
 
 </para>
 
+<!-- ##### ARG EShellWindow:sidebar-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:switcher-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:taskbar-visible ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EShellWindow:toolbar-visible ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG EShellWindow:ui-manager ##### -->
 <para>
 
@@ -172,6 +192,78 @@ EShellWindow
 @group_name: 
 
 
+<!-- ##### FUNCTION e_shell_window_get_sidebar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_shell_window_set_sidebar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ sidebar_visible: 
+
+
+<!-- ##### FUNCTION e_shell_window_get_switcher_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_shell_window_set_switcher_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ switcher_visible: 
+
+
+<!-- ##### FUNCTION e_shell_window_get_taskbar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_shell_window_set_taskbar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ taskbar_visible: 
+
+
+<!-- ##### FUNCTION e_shell_window_get_toolbar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ Returns: 
+
+
+<!-- ##### FUNCTION e_shell_window_set_toolbar_visible ##### -->
+<para>
+
+</para>
+
+ shell_window: 
+ toolbar_visible: 
+
+
 <!-- ##### FUNCTION e_shell_window_register_new_item_actions ##### -->
 <para>
 
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
index 9478259..96fc342 100644
--- a/doc/reference/shell/tmpl/eshell-unused.sgml
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -70,6 +70,30 @@ EActivityHandler
 e-config-upgrade
 
 
+<!-- ##### SECTION ./tmpl/e-error.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-error.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/e-error.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-error.sgml:Stability_Level ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/e-error.sgml:Title ##### -->
+Error Dialog Functions
+
+
 <!-- ##### SECTION ./tmpl/e-shell-common.sgml:Long_Description ##### -->
 <para>
 
@@ -770,6 +794,13 @@ intelligent
 
 @window: 
 
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR ##### -->
+<para>
+
+</para>
+
+ window: 
+
 <!-- ##### MACRO E_SUMMARY_STORAGE_NAME ##### -->
 <para>
 
diff --git a/doc/reference/shell/tmpl/shell-actions.sgml b/doc/reference/shell/tmpl/shell-actions.sgml
index ff50f7a..539cdb0 100644
--- a/doc/reference/shell/tmpl/shell-actions.sgml
+++ b/doc/reference/shell/tmpl/shell-actions.sgml
@@ -193,7 +193,7 @@ Shell Actions
 @window: 
 
 
-<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR ##### -->
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SWITCHER ##### -->
 <para>
 
 </para>
@@ -201,7 +201,7 @@ Shell Actions
 @window: 
 
 
-<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_SWITCHER ##### -->
+<!-- ##### MACRO E_SHELL_WINDOW_ACTION_SHOW_TASKBAR ##### -->
 <para>
 
 </para>
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index d961ebe..fdaac72 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -1192,60 +1192,24 @@ action_send_receive_cb (GtkAction *action,
  *
  * Main menu item: View -> Layout -> Show Side Bar
  **/
-static void
-action_show_sidebar_cb (GtkToggleAction *action,
-                        EShellWindow *shell_window)
-{
-	GtkPaned *paned;
-	GtkWidget *widget;
-	gboolean active;
-
-	paned = GTK_PANED (shell_window->priv->content_pane);
-
-	widget = gtk_paned_get_child1 (paned);
-	active = gtk_toggle_action_get_active (action);
-	g_object_set (widget, "visible", active, NULL);
-}
 
 /**
- * E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR:
+ * E_SHELL_WINDOW_ACTION_SHOW_SWITCHER:
  * @window: an #EShellWindow
  *
- * This toggle action controls whether the status bar is visible.
+ * This toggle action controls whether the switcher buttons are visible.
  *
- * Main menu item: View -> Layout -> Show Status Bar
+ * Main menu item: View -> Switcher Appearance -> Show Buttons
  **/
-static void
-action_show_statusbar_cb (GtkToggleAction *action,
-                          EShellWindow *shell_window)
-{
-	GtkWidget *widget;
-	gboolean active;
-
-	widget = shell_window->priv->status_area;
-	active = gtk_toggle_action_get_active (action);
-	g_object_set (widget, "visible", active, NULL);
-}
 
 /**
- * E_SHELL_WINDOW_ACTION_SHOW_SWITCHER:
+ * E_SHELL_WINDOW_ACTION_SHOW_TASKBAR:
  * @window: an #EShellWindow
  *
- * This toggle action controls whether the switcher buttons are visible.
+ * This toggle action controls whether the task bar is visible.
  *
- * Main menu item: View -> Switcher Appearance -> Show Buttons
+ * Main menu item: View -> Layout -> Show Status Bar
  **/
-static void
-action_show_switcher_cb (GtkToggleAction *action,
-                         EShellWindow *shell_window)
-{
-	EShellSwitcher *switcher;
-	gboolean active;
-
-	switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
-	active = gtk_toggle_action_get_active (action);
-	e_shell_switcher_set_visible (switcher, active);
-}
 
 /**
  * E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR:
@@ -1255,17 +1219,6 @@ action_show_switcher_cb (GtkToggleAction *action,
  *
  * Main menu item: View -> Layout -> Show Tool Bar
  **/
-static void
-action_show_toolbar_cb (GtkToggleAction *action,
-                        EShellWindow *shell_window)
-{
-	GtkWidget *widget;
-	gboolean active;
-
-	widget = shell_window->priv->main_toolbar;
-	active = gtk_toggle_action_get_active (action);
-	g_object_set (widget, "visible", active, NULL);
-}
 
 /**
  * E_SHELL_WINDOW_ACTION_SUBMIT_BUG:
@@ -1708,15 +1661,7 @@ static GtkToggleActionEntry shell_toggle_entries[] = {
 	  N_("Show Side _Bar"),
 	  NULL,
 	  N_("Show the side bar"),
-	  G_CALLBACK (action_show_sidebar_cb),
-	  TRUE },
-
-	{ "show-statusbar",
-	  NULL,
-	  N_("Show _Status Bar"),
 	  NULL,
-	  N_("Show the status bar"),
-	  G_CALLBACK (action_show_statusbar_cb),
 	  TRUE },
 
 	{ "show-switcher",
@@ -1724,15 +1669,23 @@ static GtkToggleActionEntry shell_toggle_entries[] = {
 	  N_("Show _Buttons"),
 	  NULL,
 	  N_("Show the switcher buttons"),
-	  G_CALLBACK (action_show_switcher_cb),
+	  NULL,
+	  TRUE },
+
+	{ "show-taskbar",
+	  NULL,
+	  N_("Show _Status Bar"),
+	  NULL,
+	  N_("Show the status bar"),
+	  NULL,
 	  TRUE },
 
 	{ "show-toolbar",
 	  NULL,
 	  N_("Show _Tool Bar"),
 	  NULL,
-	  N_("Show the toolbar"),
-	  G_CALLBACK (action_show_toolbar_cb),
+	  N_("Show the tool bar"),
+	  NULL,
 	  TRUE }
 };
 
@@ -1932,6 +1885,22 @@ e_shell_window_actions_init (EShellWindow *shell_window)
 
 	g_object_set (ACTION (SEND_RECEIVE), "is-important", TRUE, NULL);
 
+	e_mutual_binding_new (
+		shell_window, "sidebar-visible",
+		ACTION (SHOW_SIDEBAR), "active");
+
+	e_mutual_binding_new (
+		shell_window, "switcher-visible",
+		ACTION (SHOW_SWITCHER), "active");
+
+	e_mutual_binding_new (
+		shell_window, "taskbar-visible",
+		ACTION (SHOW_TASKBAR), "active");
+
+	e_mutual_binding_new (
+		shell_window, "toolbar-visible",
+		ACTION (SHOW_TOOLBAR), "active");
+
 	e_binding_new (
 		ACTION (SHOW_SIDEBAR), "active",
 		ACTION (SHOW_SWITCHER), "sensitive");
diff --git a/shell/e-shell-window-actions.h b/shell/e-shell-window-actions.h
index dec9160..8636b69 100644
--- a/shell/e-shell-window-actions.h
+++ b/shell/e-shell-window-actions.h
@@ -73,10 +73,10 @@
 	E_SHELL_WINDOW_ACTION ((window), "send-receive")
 #define E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR(window) \
 	E_SHELL_WINDOW_ACTION ((window), "show-sidebar")
-#define E_SHELL_WINDOW_ACTION_SHOW_STATUSBAR(window) \
-	E_SHELL_WINDOW_ACTION ((window), "show-statusbar")
 #define E_SHELL_WINDOW_ACTION_SHOW_SWITCHER(window) \
 	E_SHELL_WINDOW_ACTION ((window), "show-switcher")
+#define E_SHELL_WINDOW_ACTION_SHOW_TASKBAR(window) \
+	E_SHELL_WINDOW_ACTION ((window), "show-taskbar")
 #define E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR(window) \
 	E_SHELL_WINDOW_ACTION ((window), "show-toolbar")
 #define E_SHELL_WINDOW_ACTION_SUBMIT_BUG(window) \
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
index e3d6854..57f5b32 100644
--- a/shell/e-shell-window-private.c
+++ b/shell/e-shell-window-private.c
@@ -154,14 +154,59 @@ shell_window_connect_proxy_cb (EShellWindow *shell_window,
 		shell_window);
 }
 
-static void
-shell_window_online_button_clicked_cb (EOnlineButton *button,
-                                       EShellWindow *shell_window)
+static GtkWidget *
+shell_window_construct_menubar (EShellWindow *shell_window)
+{
+	EShellWindowClass *class;
+
+	class = E_SHELL_WINDOW_GET_CLASS (shell_window);
+	g_return_val_if_fail (class->construct_menubar != NULL, 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);
+	g_return_val_if_fail (class->construct_toolbar != NULL, NULL);
+
+	return class->construct_toolbar (shell_window);
+}
+
+static GtkWidget *
+shell_window_construct_sidebar (EShellWindow *shell_window)
 {
-	if (e_online_button_get_online (button))
-		gtk_action_activate (ACTION (WORK_OFFLINE));
-	else
-		gtk_action_activate (ACTION (WORK_ONLINE));
+	EShellWindowClass *class;
+
+	class = E_SHELL_WINDOW_GET_CLASS (shell_window);
+	g_return_val_if_fail (class->construct_sidebar != NULL, 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);
+	g_return_val_if_fail (class->construct_content != NULL, 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);
+	g_return_val_if_fail (class->construct_taskbar != NULL, NULL);
+
+	return class->construct_taskbar (shell_window);
 }
 
 void
@@ -171,11 +216,7 @@ e_shell_window_private_init (EShellWindow *shell_window)
 	GHashTable *loaded_views;
 	GArray *signal_handler_ids;
 	GtkAccelGroup *accel_group;
-	GtkToolItem *item;
-	GtkWidget *container;
-	GtkWidget *widget;
 	guint merge_id;
-	gint height;
 
 	loaded_views = g_hash_table_new_full (
 		g_str_hash, g_str_equal,
@@ -216,6 +257,31 @@ e_shell_window_private_init (EShellWindow *shell_window)
 	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;
+	EShellSettings *shell_settings;
+	EShell *shell;
+	GConfBridge *bridge;
+	GtkAction *action;
+	GtkActionGroup *action_group;
+	GtkUIManager *ui_manager;
+	GtkWidget *container;
+	GtkWidget *widget;
+	GtkWindow *window;
+	GObject *object;
+	const gchar *key;
+	const gchar *id;
+
+	window = GTK_WINDOW (shell_window);
+
+	shell = e_shell_window_get_shell (shell_window);
+	shell_settings = e_shell_get_shell_settings (shell);
+
+	e_shell_watch_window (shell, window);
 
 	/* Construct window widgets. */
 
@@ -225,131 +291,50 @@ e_shell_window_private_init (EShellWindow *shell_window)
 
 	container = widget;
 
-	widget = e_shell_window_get_managed_widget (
-		shell_window, "/main-menu");
+	widget = shell_window_construct_menubar (shell_window);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
-	priv->main_menu = g_object_ref (widget);
-	gtk_widget_show (widget);
 
-	widget = e_shell_window_get_managed_widget (
-		shell_window, "/main-toolbar");
+	widget = shell_window_construct_toolbar (shell_window);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
-	priv->main_toolbar = g_object_ref (widget);
-	gtk_widget_show (widget);
-
-	/* XXX Having this separator in the UI definition doesn't work
-	 *     because GtkUIManager is unaware of the "New" button, so
-	 *     it makes the separator invisible.  One possibility is to
-	 *     define a GtkAction subclass for which create_tool_item()
-	 *     returns an EMenuToolButton.  Then both this separator
-	 *     and the "New" button could be added to the UI definition.
-	 *     Tempting, but the "New" button and its dynamically
-	 *     generated menu is already a complex beast, and I'm not
-	 *     convinced having it proxy some new type of GtkAction
-	 *     is worth the extra effort. */
-	item = gtk_separator_tool_item_new ();
-	gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
-	gtk_widget_show (GTK_WIDGET (item));
-
-	item = e_menu_tool_button_new (_("New"));
-	gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
-	gtk_widget_add_accelerator (
-		GTK_WIDGET (item), "clicked",
-		gtk_ui_manager_get_accel_group (priv->ui_manager),
-		GDK_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
-	gtk_toolbar_insert (GTK_TOOLBAR (widget), item, 0);
-	priv->menu_tool_button = g_object_ref (item);
-	gtk_widget_show (GTK_WIDGET (item));
 
 	widget = gtk_hpaned_new ();
 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
 	priv->content_pane = g_object_ref (widget);
 	gtk_widget_show (widget);
 
-	widget = gtk_hbox_new (FALSE, 3);
-	gtk_container_set_border_width (GTK_CONTAINER (widget), 3);
+	widget = shell_window_construct_taskbar (shell_window);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
-	priv->status_area = g_object_ref (widget);
-	gtk_widget_show (widget);
-
-	/* Make the status area as large as the task bar. */
-	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
-	gtk_widget_set_size_request (widget, -1, (height * 2) + 6);
 
 	container = priv->content_pane;
 
-	widget = e_shell_switcher_new ();
+	widget = shell_window_construct_sidebar (shell_window);
 	gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE);
-	priv->switcher = g_object_ref (widget);
-	gtk_widget_show (widget);
 
-	widget = gtk_notebook_new ();
-	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
-	gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
+	widget = shell_window_construct_content (shell_window);
 	gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE);
-	priv->content_notebook = g_object_ref (widget);
-	gtk_widget_show (widget);
 
-	container = priv->switcher;
-
-	widget = gtk_notebook_new ();
-	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
-	gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
-	gtk_container_add (GTK_CONTAINER (container), widget);
-	priv->sidebar_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);
 
-	container = priv->status_area;
+	/* Bunch of chores to do when the active view changes. */
 
-	widget = e_online_button_new ();
 	g_signal_connect (
-		widget, "clicked",
-		G_CALLBACK (shell_window_online_button_clicked_cb),
-		shell_window);
-	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
-	priv->online_button = g_object_ref (widget);
-	gtk_widget_show (widget);
-
-	widget = gtk_label_new ("");
-	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
-	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
-	priv->tooltip_label = g_object_ref (widget);
-	gtk_widget_hide (widget);
-
-	widget = gtk_notebook_new ();
-	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
-	gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
-	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
-	priv->status_notebook = g_object_ref (widget);
-	gtk_widget_show (widget);
-}
+		shell_window, "notify::active-view",
+		G_CALLBACK (e_shell_window_update_icon), NULL);
 
-void
-e_shell_window_private_constructed (EShellWindow *shell_window)
-{
-	EShellWindowPrivate *priv = shell_window->priv;
-	EShellSettings *shell_settings;
-	EShell *shell;
-	GConfBridge *bridge;
-	GtkAction *action;
-	GtkActionGroup *action_group;
-	GtkUIManager *ui_manager;
-	GtkWindow *window;
-	GObject *object;
-	const gchar *key;
-	const gchar *id;
-
-	window = GTK_WINDOW (shell_window);
-
-	shell = e_shell_window_get_shell (shell_window);
-	shell_settings = e_shell_get_shell_settings (shell);
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (e_shell_window_update_title), NULL);
 
-	e_shell_watch_window (shell, window);
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (e_shell_window_update_view_menu), NULL);
 
-	/* 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);
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (e_shell_window_update_search_menu), NULL);
 
 	/* Support lockdown. */
 
@@ -399,14 +384,6 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
 		shell, "network-available",
 		action, "sensitive");
 
-	e_binding_new (
-		shell, "online",
-		priv->online_button, "online");
-
-	e_binding_new (
-		shell, "network-available",
-		priv->online_button, "sensitive");
-
 	/* Bind GObject properties to GConf keys. */
 
 	bridge = gconf_bridge_get ();
@@ -419,21 +396,21 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
 	key = "/apps/evolution/shell/view_defaults/folder_bar/width";
 	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
 
-	object = G_OBJECT (ACTION (SHOW_SIDEBAR));
+	object = G_OBJECT (shell_window);
 	key = "/apps/evolution/shell/view_defaults/sidebar_visible";
-	gconf_bridge_bind_property (bridge, key, object, "active");
+	gconf_bridge_bind_property (bridge, key, object, "sidebar-visible");
 
-	object = G_OBJECT (ACTION (SHOW_STATUSBAR));
+	object = G_OBJECT (shell_window);
 	key = "/apps/evolution/shell/view_defaults/statusbar_visible";
-	gconf_bridge_bind_property (bridge, key, object, "active");
+	gconf_bridge_bind_property (bridge, key, object, "taskbar-visible");
 
-	object = G_OBJECT (ACTION (SHOW_SWITCHER));
+	object = G_OBJECT (shell_window);
 	key = "/apps/evolution/shell/view_defaults/buttons_visible";
-	gconf_bridge_bind_property (bridge, key, object, "active");
+	gconf_bridge_bind_property (bridge, key, object, "switcher-visible");
 
-	object = G_OBJECT (ACTION (SHOW_TOOLBAR));
+	object = G_OBJECT (shell_window);
 	key = "/apps/evolution/shell/view_defaults/toolbar_visible";
-	gconf_bridge_bind_property (bridge, key, object, "active");
+	gconf_bridge_bind_property (bridge, key, object, "toolbar-visible");
 
 	/* Configure the initial size and position of the window by way
 	 * of either a user-supplied geometry string or the last recorded
@@ -489,15 +466,10 @@ e_shell_window_private_dispose (EShellWindow *shell_window)
 
 	g_hash_table_remove_all (priv->loaded_views);
 
-	DISPOSE (priv->main_menu);
-	DISPOSE (priv->main_toolbar);
-	DISPOSE (priv->menu_tool_button);
 	DISPOSE (priv->content_pane);
 	DISPOSE (priv->content_notebook);
 	DISPOSE (priv->sidebar_notebook);
 	DISPOSE (priv->switcher);
-	DISPOSE (priv->status_area);
-	DISPOSE (priv->online_button);
 	DISPOSE (priv->tooltip_label);
 	DISPOSE (priv->status_notebook);
 
@@ -518,36 +490,16 @@ void
 e_shell_window_switch_to_view (EShellWindow *shell_window,
                                const gchar *view_name)
 {
-	GtkNotebook *notebook;
 	EShellView *shell_view;
-	gint page_num;
 
 	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
 	g_return_if_fail (view_name != NULL);
 
 	shell_view = e_shell_window_get_shell_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->active_view = view_name;
 	g_object_notify (G_OBJECT (shell_window), "active-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_view_menu (shell_window);
-	e_shell_window_update_search_menu (shell_window);
-
 	e_shell_view_update_actions (shell_view);
 }
 
@@ -589,25 +541,3 @@ e_shell_window_update_title (EShellWindow *shell_window)
 	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;
-
-	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
-
-	/* 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 4570aba..635b6b6 100644
--- a/shell/e-shell-window-private.h
+++ b/shell/e-shell-window-private.h
@@ -81,15 +81,10 @@ struct _EShellWindowPrivate {
 
 	/*** Widgetry ***/
 
-	GtkWidget *main_menu;
-	GtkWidget *main_toolbar;
-	GtkWidget *menu_tool_button;
 	GtkWidget *content_pane;
 	GtkWidget *content_notebook;
 	GtkWidget *sidebar_notebook;
 	GtkWidget *switcher;
-	GtkWidget *status_area;
-	GtkWidget *online_button;
 	GtkWidget *tooltip_label;
 	GtkWidget *status_notebook;
 
@@ -100,8 +95,12 @@ struct _EShellWindowPrivate {
 
 	gchar *geometry;
 
-	guint destroyed : 1;  /* XXX Do we still need this? */
-	guint safe_mode : 1;
+	guint destroyed        : 1;  /* XXX Do we still need this? */
+	guint safe_mode        : 1;
+	guint sidebar_visible  : 1;
+	guint switcher_visible : 1;
+	guint taskbar_visible  : 1;
+	guint toolbar_visible  : 1;
 };
 
 void		e_shell_window_private_init	(EShellWindow *shell_window);
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 737d9dc..25b56ca 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -32,92 +32,68 @@ enum {
 	PROP_GEOMETRY,
 	PROP_SAFE_MODE,
 	PROP_SHELL,
+	PROP_SIDEBAR_VISIBLE,
+	PROP_SWITCHER_VISIBLE,
+	PROP_TASKBAR_VISIBLE,
+	PROP_TOOLBAR_VISIBLE,
 	PROP_UI_MANAGER
 };
 
 static gpointer parent_class;
 
-static EShellView *
-shell_window_new_view (EShellBackend *shell_backend,
-                       EShellWindow *shell_window)
+static void
+shell_window_menubar_update_new_menu (EShellWindow *shell_window)
 {
-	GHashTable *loaded_views;
-	EShellView *shell_view;
-	GtkUIManager *ui_manager;
-	GtkNotebook *notebook;
-	GtkAction *action;
+	GtkWidget *menu;
 	GtkWidget *widget;
-	const gchar *name;
-	const gchar *id;
-	gint page_num;
-	GType type;
-
-	name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
-	type = E_SHELL_BACKEND_GET_CLASS (shell_backend)->shell_view_type;
-
-	/* First off, start the shell backend. */
-	e_shell_backend_start (shell_backend);
-
-	/* 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 = e_shell_window_get_shell_view_action (shell_window, name);
-
-	/* Create the shell view. */
-	shell_view = g_object_new (
-		type, "action", action, "page-num",page_num,
-		"shell-window", shell_window, NULL);
-
-	/* Register the shell view. */
-	loaded_views = shell_window->priv->loaded_views;
-	g_hash_table_insert (loaded_views, g_strdup (name), shell_view);
-
-	/* Register the GtkUIManager ID for the shell view. */
-	id = E_SHELL_VIEW_GET_CLASS (shell_view)->ui_manager_id;
-	ui_manager = e_shell_window_get_ui_manager (shell_window);
-	e_plugin_ui_register_manager (ui_manager, id, shell_view);
-
-	/* Add pages to the various shell window notebooks. */
-
-	/* We can't determine the shell view's page number until after the
-	 * shell view is fully initialized because the shell view may load
-	 * other shell views during initialization, and those other shell
-	 * views will append their widgets to the notebooks before us. */
-	page_num = gtk_notebook_get_n_pages (notebook);
-	e_shell_view_set_page_num (shell_view, page_num);
-
-	notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
-	widget = GTK_WIDGET (e_shell_view_get_shell_content (shell_view));
-	gtk_notebook_append_page (notebook, widget, NULL);
-
-	notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
-	widget = GTK_WIDGET (e_shell_view_get_shell_sidebar (shell_view));
-	gtk_notebook_append_page (notebook, widget, NULL);
+	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);
+}
 
-	notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
-	widget = GTK_WIDGET (e_shell_view_get_shell_taskbar (shell_view));
-	gtk_notebook_append_page (notebook, widget, NULL);
+static void
+shell_window_toolbar_update_new_menu (EShellWindow *shell_window,
+                                      GParamSpec *pspec,
+                                      GtkMenuToolButton *menu_tool_button)
+{
+	GtkWidget *menu;
 
-	/* Listen for changes that affect the shell window. */
+	/* Update the "New" menu tool button submenu. */
+	menu = e_shell_window_create_new_menu (shell_window);
+	gtk_menu_tool_button_set_menu (menu_tool_button, menu);
+}
 
-	g_signal_connect_swapped (
-		action, "notify::icon-name",
-		G_CALLBACK (e_shell_window_update_icon), shell_window);
+static void
+shell_window_set_notebook_page (EShellWindow *shell_window,
+                                GParamSpec *pspec,
+                                GtkNotebook *notebook)
+{
+	EShellView *shell_view;
+	const gchar *view_name;
+	gint page_num;
 
-	g_signal_connect_swapped (
-		shell_view, "notify::title",
-		G_CALLBACK (e_shell_window_update_title), shell_window);
+	view_name = e_shell_window_get_active_view (shell_window);
+	shell_view = e_shell_window_get_shell_view (shell_window, view_name);
 
-	g_signal_connect_swapped (
-		shell_view, "notify::view-id",
-		G_CALLBACK (e_shell_window_update_view_menu), shell_window);
+	page_num = e_shell_view_get_page_num (shell_view);
+	g_return_if_fail (page_num >= 0);
 
-	/* Execute an initial search. */
-	e_shell_view_execute_search (shell_view);
+	gtk_notebook_set_current_page (notebook, page_num);
+}
 
-	return shell_view;
+static void
+shell_window_online_button_clicked_cb (EOnlineButton *button,
+                                       EShellWindow *shell_window)
+{
+	if (e_online_button_get_online (button))
+		gtk_action_activate (ACTION (WORK_OFFLINE));
+	else
+		gtk_action_activate (ACTION (WORK_ONLINE));
 }
 
 static void
@@ -216,6 +192,30 @@ shell_window_set_property (GObject *object,
 				E_SHELL_WINDOW (object),
 				g_value_get_object (value));
 			return;
+
+		case PROP_SIDEBAR_VISIBLE:
+			e_shell_window_set_sidebar_visible (
+				E_SHELL_WINDOW (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_SWITCHER_VISIBLE:
+			e_shell_window_set_switcher_visible (
+				E_SHELL_WINDOW (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_TASKBAR_VISIBLE:
+			e_shell_window_set_taskbar_visible (
+				E_SHELL_WINDOW (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_TOOLBAR_VISIBLE:
+			e_shell_window_set_toolbar_visible (
+				E_SHELL_WINDOW (object),
+				g_value_get_boolean (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -246,6 +246,30 @@ shell_window_get_property (GObject *object,
 				E_SHELL_WINDOW (object)));
 			return;
 
+		case PROP_SIDEBAR_VISIBLE:
+			g_value_set_boolean (
+				value, e_shell_window_get_sidebar_visible (
+				E_SHELL_WINDOW (object)));
+			return;
+
+		case PROP_SWITCHER_VISIBLE:
+			g_value_set_boolean (
+				value, e_shell_window_get_switcher_visible (
+				E_SHELL_WINDOW (object)));
+			return;
+
+		case PROP_TASKBAR_VISIBLE:
+			g_value_set_boolean (
+				value, e_shell_window_get_taskbar_visible (
+				E_SHELL_WINDOW (object)));
+			return;
+
+		case PROP_TOOLBAR_VISIBLE:
+			g_value_set_boolean (
+				value, e_shell_window_get_toolbar_visible (
+				E_SHELL_WINDOW (object)));
+			return;
+
 		case PROP_UI_MANAGER:
 			g_value_set_object (
 				value, e_shell_window_get_ui_manager (
@@ -280,6 +304,273 @@ shell_window_constructed (GObject *object)
 	e_shell_window_private_constructed (E_SHELL_WINDOW (object));
 }
 
+static GtkWidget *
+shell_window_construct_menubar (EShellWindow *shell_window)
+{
+	GtkWidget *main_menu;
+
+	main_menu = e_shell_window_get_managed_widget (
+		shell_window, "/main-menu");
+	gtk_widget_show (main_menu);
+
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (shell_window_menubar_update_new_menu), NULL);
+
+	return main_menu;
+}
+
+static GtkWidget *
+shell_window_construct_toolbar (EShellWindow *shell_window)
+{
+	GtkUIManager *ui_manager;
+	GtkWidget *main_toolbar;
+	GtkToolItem *item;
+
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+	main_toolbar = e_shell_window_get_managed_widget (
+		shell_window, "/main-toolbar");
+
+	e_binding_new (
+		shell_window, "toolbar-visible",
+		main_toolbar, "visible");
+
+	/* XXX Having this separator in the UI definition doesn't work
+	 *     because GtkUIManager is unaware of the "New" button, so
+	 *     it makes the separator invisible.  One possibility is to
+	 *     define a GtkAction subclass for which create_tool_item()
+	 *     return an EMenuToolButton.  Then both this separator
+	 *     and the "New" button could be added to the UI definition.
+	 *     Tempting, but the "New" button and its dynamically
+	 *     generated menu is already a complex beast, and I'm not
+	 *     convinced having it proxy some new type of GtkAction
+	 *     is worth the extra effort. */
+	item = gtk_separator_tool_item_new ();
+	gtk_toolbar_insert (GTK_TOOLBAR (main_toolbar), item, 0);
+	gtk_widget_show (GTK_WIDGET (item));
+
+	item = e_menu_tool_button_new (_("New"));
+	gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
+	gtk_widget_add_accelerator (
+		GTK_WIDGET (item), "clicked",
+		gtk_ui_manager_get_accel_group (ui_manager),
+		GDK_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+	gtk_toolbar_insert (GTK_TOOLBAR (main_toolbar), item, 0);
+	gtk_widget_show (GTK_WIDGET (item));
+
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (shell_window_toolbar_update_new_menu),
+		GTK_MENU_TOOL_BUTTON (item));
+
+	return main_toolbar;
+}
+
+static GtkWidget *
+shell_window_construct_sidebar (EShellWindow *shell_window)
+{
+	GtkWidget *notebook;
+	GtkWidget *switcher;
+
+	switcher = e_shell_switcher_new ();
+	shell_window->priv->switcher = g_object_ref_sink (switcher);
+
+	e_binding_new (
+		shell_window, "sidebar-visible",
+		switcher, "visible");
+
+	e_binding_new (
+		shell_window, "switcher-visible",
+		switcher, "toolbar-visible");
+
+	notebook = gtk_notebook_new ();
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_container_add (GTK_CONTAINER (switcher), notebook);
+	shell_window->priv->sidebar_notebook = g_object_ref (notebook);
+	gtk_widget_show (notebook);
+
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (shell_window_set_notebook_page), notebook);
+
+	return switcher;
+}
+
+static GtkWidget *
+shell_window_construct_content (EShellWindow *shell_window)
+{
+	GtkWidget *notebook;
+
+	notebook = gtk_notebook_new ();
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+	shell_window->priv->content_notebook = g_object_ref_sink (notebook);
+	gtk_widget_show (notebook);
+
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (shell_window_set_notebook_page), notebook);
+
+	return notebook;
+}
+
+static GtkWidget *
+shell_window_construct_taskbar (EShellWindow *shell_window)
+{
+	EShell *shell;
+	GtkWidget *notebook;
+	GtkWidget *status_area;
+	GtkWidget *online_button;
+	GtkWidget *tooltip_label;
+	gint height;
+
+	shell = e_shell_window_get_shell (shell_window);
+
+	status_area = gtk_hbox_new (FALSE, 3);
+	gtk_container_set_border_width (GTK_CONTAINER (status_area), 3);
+
+	e_binding_new (
+		shell_window, "taskbar-visible",
+		status_area, "visible");
+
+	/* Make the status area as large as the task bar. */
+	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
+	gtk_widget_set_size_request (status_area, -1, (height * 2) + 6);
+
+	online_button = e_online_button_new ();
+	gtk_box_pack_start (
+		GTK_BOX (status_area), online_button, FALSE, TRUE, 0);
+	gtk_widget_show (online_button);
+
+	e_binding_new (
+		shell, "online",
+		online_button, "online");
+
+	e_binding_new (
+		shell, "network-available",
+		online_button, "sensitive");
+
+	g_signal_connect (
+		online_button, "clicked",
+		G_CALLBACK (shell_window_online_button_clicked_cb),
+		shell_window);
+
+	tooltip_label = gtk_label_new ("");
+	gtk_misc_set_alignment (GTK_MISC (tooltip_label), 0.0, 0.5);
+	gtk_box_pack_start (
+		GTK_BOX (status_area), tooltip_label, TRUE, TRUE, 0);
+	shell_window->priv->tooltip_label = g_object_ref (tooltip_label);
+	gtk_widget_hide (tooltip_label);
+
+	notebook = gtk_notebook_new ();
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_box_pack_start (GTK_BOX (status_area), notebook, TRUE, TRUE, 0);
+	shell_window->priv->status_notebook = g_object_ref (notebook);
+	gtk_widget_show (notebook);
+
+	g_signal_connect (
+		shell_window, "notify::active-view",
+		G_CALLBACK (shell_window_set_notebook_page), notebook);
+
+	return status_area;
+}
+
+static EShellView *
+shell_window_create_shell_view (EShellWindow *shell_window,
+                                const gchar *view_name)
+{
+	EShell *shell;
+	EShellView *shell_view;
+	EShellBackend *shell_backend;
+	GHashTable *loaded_views;
+	GtkUIManager *ui_manager;
+	GtkNotebook *notebook;
+	GtkAction *action;
+	GtkWidget *widget;
+	const gchar *name;
+	const gchar *id;
+	gint page_num;
+	GType type;
+
+	shell = e_shell_window_get_shell (shell_window);
+	shell_backend = e_shell_get_backend_by_name (shell, view_name);
+
+	if (shell_backend == NULL) {
+		g_critical ("Unknown shell view name: %s", view_name);
+		return NULL;
+	}
+
+	name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
+	type = E_SHELL_BACKEND_GET_CLASS (shell_backend)->shell_view_type;
+
+	/* First off, start the shell backend. */
+	e_shell_backend_start (shell_backend);
+
+	/* 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 = e_shell_window_get_shell_view_action (shell_window, name);
+
+	/* Create the shell view. */
+	shell_view = g_object_new (
+		type, "action", action, "page-num", page_num,
+		"shell-window", shell_window, NULL);
+
+	/* Register the shell view. */
+	loaded_views = shell_window->priv->loaded_views;
+	g_hash_table_insert (loaded_views, g_strdup (name), shell_view);
+
+	/* Register the GtkUIManager ID for the shell view. */
+	id = E_SHELL_VIEW_GET_CLASS (shell_view)->ui_manager_id;
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+	e_plugin_ui_register_manager (ui_manager, id, shell_view);
+
+	/* Add pages to the various shell window notebooks. */
+
+	/* We can't determine the shell view's page number until after the
+	 * shell view is fully initialized because the shell view may load
+	 * other shell views during initialization, and those other shell
+	 * views will append their widgets to the notebooks before us. */
+	page_num = gtk_notebook_get_n_pages (notebook);
+	e_shell_view_set_page_num (shell_view, page_num);
+
+	notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
+	widget = GTK_WIDGET (e_shell_view_get_shell_content (shell_view));
+	gtk_notebook_append_page (notebook, widget, NULL);
+
+	notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
+	widget = GTK_WIDGET (e_shell_view_get_shell_sidebar (shell_view));
+	gtk_notebook_append_page (notebook, widget, NULL);
+
+	notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
+	widget = GTK_WIDGET (e_shell_view_get_shell_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 (e_shell_window_update_title), shell_window);
+
+	g_signal_connect_swapped (
+		shell_view, "notify::view-id",
+		G_CALLBACK (e_shell_window_update_view_menu), shell_window);
+
+	/* Execute an initial search. */
+	e_shell_view_execute_search (shell_view);
+
+	return shell_view;
+}
+
 static void
 shell_window_class_init (EShellWindowClass *class)
 {
@@ -295,6 +586,13 @@ shell_window_class_init (EShellWindowClass *class)
 	object_class->finalize = shell_window_finalize;
 	object_class->constructed = shell_window_constructed;
 
+	class->construct_menubar = shell_window_construct_menubar;
+	class->construct_toolbar = shell_window_construct_toolbar;
+	class->construct_sidebar = shell_window_construct_sidebar;
+	class->construct_content = shell_window_construct_content;
+	class->construct_taskbar = shell_window_construct_taskbar;
+	class->create_shell_view = shell_window_create_shell_view;
+
 	/**
 	 * EShellWindow:active-view
 	 *
@@ -359,6 +657,67 @@ shell_window_class_init (EShellWindowClass *class)
 			G_PARAM_CONSTRUCT_ONLY));
 
 	/**
+	 * EShellWindow:sidebar-visible
+	 *
+	 * Whether the shell window's side bar is visible.
+	 **/
+	g_object_class_install_property (
+		object_class,
+		PROP_SIDEBAR_VISIBLE,
+		g_param_spec_boolean (
+			"sidebar-visible",
+			_("Sidebar Visible"),
+			_("Whether the shell window's side bar is visible"),
+			TRUE,
+			G_PARAM_READWRITE));
+
+	/**
+	 * EShellWindow:switcher-visible
+	 *
+	 * Whether the shell window's switcher buttons are visible.
+	 **/
+	g_object_class_install_property (
+		object_class,
+		PROP_SWITCHER_VISIBLE,
+		g_param_spec_boolean (
+			"switcher-visible",
+			_("Switcher Visible"),
+			_("Whether the shell window's "
+			  "switcher buttons are visible"),
+			TRUE,
+			G_PARAM_READWRITE));
+
+	/**
+	 * EShellWindow:taskbar-visible
+	 *
+	 * Whether the shell window's task bar is visible.
+	 **/
+	g_object_class_install_property (
+		object_class,
+		PROP_TASKBAR_VISIBLE,
+		g_param_spec_boolean (
+			"taskbar-visible",
+			_("Taskbar Visible"),
+			_("Whether the shell window's task bar is visible"),
+			TRUE,
+			G_PARAM_READWRITE));
+
+	/**
+	 * EShellWindow:toolbar-visible
+	 *
+	 * Whether the shell window's tool bar is visible.
+	 **/
+	g_object_class_install_property (
+		object_class,
+		PROP_TOOLBAR_VISIBLE,
+		g_param_spec_boolean (
+			"toolbar-visible",
+			_("Toolbar Visible"),
+			_("Whether the shell window's tool bar is visible"),
+			TRUE,
+			G_PARAM_READWRITE));
+
+	/**
 	 * EShellWindow:ui-manager
 	 *
 	 * The shell window's #GtkUIManager.
@@ -475,9 +834,8 @@ EShellView *
 e_shell_window_get_shell_view (EShellWindow *shell_window,
                                const gchar *view_name)
 {
-	EShell *shell;
 	EShellView *shell_view;
-	EShellBackend *shell_backend;
+	EShellWindowClass *class;
 	GHashTable *loaded_views;
 
 	g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
@@ -489,15 +847,10 @@ e_shell_window_get_shell_view (EShellWindow *shell_window,
 	if (shell_view != NULL)
 		return shell_view;
 
-	shell = e_shell_window_get_shell (shell_window);
-	shell_backend = e_shell_get_backend_by_name (shell, view_name);
-
-	if (shell_backend == NULL) {
-		g_critical ("Unknown shell view name: %s", view_name);
-		return NULL;
-	}
+	class = E_SHELL_WINDOW_GET_CLASS (shell_window);
+	g_return_val_if_fail (class->create_shell_view != NULL, NULL);
 
-	return shell_window_new_view (shell_backend, shell_window);
+	return class->create_shell_view (shell_window, view_name);
 }
 
 /**
@@ -750,6 +1103,142 @@ e_shell_window_add_action_group (EShellWindow *shell_window,
 }
 
 /**
+ * e_shell_window_get_sidebar_visible:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window<!-- -->'s side bar is visible.
+ *
+ * Returns: %TRUE is the side bar is visible
+ **/
+gboolean
+e_shell_window_get_sidebar_visible (EShellWindow *shell_window)
+{
+	g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+
+	return shell_window->priv->sidebar_visible;
+}
+
+/**
+ * e_shell_window_set_sidebar_visible:
+ * @shell_window: an #EShellWindow
+ * @sidebar_visible: whether the side bar should be visible
+ *
+ * Makes @shell_window<!-- -->'s side bar visible or invisible.
+ **/
+void
+e_shell_window_set_sidebar_visible (EShellWindow *shell_window,
+                                    gboolean sidebar_visible)
+{
+	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+	shell_window->priv->sidebar_visible = sidebar_visible;
+
+	g_object_notify (G_OBJECT (shell_window), "sidebar-visible");
+}
+
+/**
+ * e_shell_window_get_switcher_visible:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window<!-- -->'s switcher buttons are visible.
+ *
+ * Returns: %TRUE is the switcher buttons are visible
+ **/
+gboolean
+e_shell_window_get_switcher_visible (EShellWindow *shell_window)
+{
+	g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+
+	return shell_window->priv->switcher_visible;
+}
+
+/**
+ * e_shell_window_set_switcher_visible:
+ * @shell_window: an #EShellWindow
+ * @switcher_visible: whether the switcher buttons should be visible
+ *
+ * Makes @shell_window<!-- -->'s switcher buttons visible or invisible.
+ **/
+void
+e_shell_window_set_switcher_visible (EShellWindow *shell_window,
+                                     gboolean switcher_visible)
+{
+	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+	shell_window->priv->switcher_visible = switcher_visible;
+
+	g_object_notify (G_OBJECT (shell_window), "switcher-visible");
+}
+
+/**
+ * e_shell_window_get_taskbar_visible:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window<!-- -->'s task bar is visible.
+ *
+ * Returns: %TRUE is the task bar is visible
+ **/
+gboolean
+e_shell_window_get_taskbar_visible (EShellWindow *shell_window)
+{
+	g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+
+	return shell_window->priv->taskbar_visible;
+}
+
+/**
+ * e_shell_window_set_taskbar_visible:
+ * @shell_window: an #EShellWindow
+ * @taskbar_visible: whether the task bar should be visible
+ *
+ * Makes @shell_window<!-- -->'s task bar visible or invisible.
+ **/
+void
+e_shell_window_set_taskbar_visible (EShellWindow *shell_window,
+                                    gboolean taskbar_visible)
+{
+	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+	shell_window->priv->taskbar_visible = taskbar_visible;
+
+	g_object_notify (G_OBJECT (shell_window), "taskbar-visible");
+}
+
+/**
+ * e_shell_window_get_toolbar_visible:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window<!-- -->'s tool bar is visible.
+ *
+ * Returns: %TRUE if the tool bar is visible
+ **/
+gboolean
+e_shell_window_get_toolbar_visible (EShellWindow *shell_window)
+{
+	g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
+
+	return shell_window->priv->toolbar_visible;
+}
+
+/**
+ * e_shell_window_set_toolbar_visible:
+ * @shell_window: an #EShellWindow
+ * @toolbar_visible: whether the tool bar should be visible
+ *
+ * Makes @shell_window<!-- -->'s tool bar visible or invisible.
+ **/
+void
+e_shell_window_set_toolbar_visible (EShellWindow *shell_window,
+                                    gboolean toolbar_visible)
+{
+	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
+
+	shell_window->priv->toolbar_visible = toolbar_visible;
+
+	g_object_notify (G_OBJECT (shell_window), "toolbar-visible");
+}
+
+/**
  * e_shell_window_register_new_item_actions:
  * @shell_window: an #EShellWindow
  * @backend_name: name of an #EShellBackend
@@ -834,8 +1323,6 @@ e_shell_window_register_new_item_actions (EShellWindow *shell_window,
 				G_OBJECT (action),
 				"primary", GINT_TO_POINTER (TRUE));
 	}
-
-	e_shell_window_update_new_menu (shell_window);
 }
 
 /**
@@ -913,6 +1400,4 @@ e_shell_window_register_new_source_actions (EShellWindow *shell_window,
 			G_OBJECT (action),
 			"backend-name", (gpointer) backend_name);
 	}
-
-	e_shell_window_update_new_menu (shell_window);
 }
diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h
index c9ba928..bb88003 100644
--- a/shell/e-shell-window.h
+++ b/shell/e-shell-window.h
@@ -71,6 +71,16 @@ struct _EShellWindow {
 
 struct _EShellWindowClass {
 	GtkWindowClass parent_class;
+
+	/* These are all protected methods.  Not for public use. */
+	GtkWidget *	(*construct_menubar)	(EShellWindow *shell_window);
+	GtkWidget *	(*construct_toolbar)	(EShellWindow *shell_window);
+	GtkWidget *	(*construct_sidebar)	(EShellWindow *shell_window);
+	GtkWidget *	(*construct_content)	(EShellWindow *shell_window);
+	GtkWidget *	(*construct_taskbar)	(EShellWindow *shell_window);
+	struct _EShellView *
+			(*create_shell_view)	(EShellWindow *shell_window,
+						 const gchar *view_name);
 };
 
 GType		e_shell_window_get_type		(void);
@@ -100,6 +110,26 @@ void		e_shell_window_set_safe_mode	(EShellWindow *shell_window,
 						 gboolean safe_mode);
 void		e_shell_window_add_action_group (EShellWindow *shell_window,
 						 const gchar *group_name);
+gboolean	e_shell_window_get_sidebar_visible
+						(EShellWindow *shell_window);
+void		e_shell_window_set_sidebar_visible
+						(EShellWindow *shell_window,
+						 gboolean sidebar_visible);
+gboolean	e_shell_window_get_switcher_visible
+						(EShellWindow *shell_window);
+void		e_shell_window_set_switcher_visible
+						(EShellWindow *shell_window,
+						 gboolean switcher_visible);
+gboolean	e_shell_window_get_taskbar_visible
+						(EShellWindow *shell_window);
+void		e_shell_window_set_taskbar_visible
+						(EShellWindow *shell_window,
+						 gboolean taskbar_visible);
+gboolean	e_shell_window_get_toolbar_visible
+						(EShellWindow *shell_window);
+void		e_shell_window_set_toolbar_visible
+						(EShellWindow *shell_window,
+						 gboolean toolbar_visible);
 
 /* These should be called from the shell backend's window_created() handler. */
 
diff --git a/ui/evolution-shell.ui b/ui/evolution-shell.ui
index 609a8fe..ccfeb86 100644
--- a/ui/evolution-shell.ui
+++ b/ui/evolution-shell.ui
@@ -38,7 +38,7 @@
       <menu action='window-menu'/>
       <menu action='layout-menu'>
         <menuitem action='show-toolbar'/>
-        <menuitem action='show-statusbar'/>
+        <menuitem action='show-taskbar'/>
         <menuitem action='show-sidebar'/>
       </menu>
       <placeholder name='view-custom-menus'/>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]