[evolution] Defer the load / creation of configuration UI with changes to e_preferences_window to take factory c



commit 18813ccd8f4367ac98348f08e183d858cfe963f5
Author: Michael Meeks <michael meeks novell com>
Date:   Tue Aug 10 21:17:40 2010 +0100

    Defer the load / creation of configuration UI with changes to
    e_preferences_window to take factory callbacks and store a reference
    to the shell. - This makes start-up substantially faster, particularly
    on Atom (eg.).
    
    Remove a number of idle handlers used to create these UIs in the
    first instance, cleaning the code.

 calendar/gui/dialogs/cal-prefs-dialog.c     |    5 +-
 calendar/gui/dialogs/cal-prefs-dialog.h     |    4 +-
 modules/addressbook/autocompletion-config.c |    5 +-
 modules/addressbook/autocompletion-config.h |    3 +-
 modules/addressbook/e-book-shell-backend.c  |   12 +++-
 modules/calendar/e-cal-shell-backend.c      |   34 ++++-------
 modules/mail/e-mail-shell-backend.c         |   86 +++++++++++---------------
 modules/mail/em-account-prefs.c             |    7 ++-
 modules/mail/em-account-prefs.h             |    5 +-
 modules/mail/em-composer-prefs.c            |    3 +-
 modules/mail/em-composer-prefs.h            |    9 ++-
 modules/mail/em-mailer-prefs.c              |    3 +-
 modules/mail/em-mailer-prefs.h              |    8 +-
 modules/mail/em-network-prefs.c             |    2 +-
 modules/mail/em-network-prefs.h             |    5 +-
 shell/e-shell-window-actions.c              |    1 +
 shell/e-shell.c                             |    2 +-
 smime/gui/certificate-manager.c             |   21 +++----
 smime/gui/certificate-manager.h             |    5 +-
 widgets/misc/e-preferences-window.c         |   80 +++++++++++++++++++++++--
 widgets/misc/e-preferences-window.h         |    8 ++-
 widgets/misc/test-preferences-window.c      |   60 ++++++++++++------
 22 files changed, 229 insertions(+), 139 deletions(-)
---
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c
index 410f8cb..179dd25 100644
--- a/calendar/gui/dialogs/cal-prefs-dialog.c
+++ b/calendar/gui/dialogs/cal-prefs-dialog.c
@@ -847,10 +847,13 @@ calendar_prefs_dialog_get_type (void)
 }
 
 GtkWidget *
-calendar_prefs_dialog_new (EShell *shell)
+calendar_prefs_dialog_new (EPreferencesWindow *window)
 {
+	EShell *shell;
 	CalendarPrefsDialog *dialog;
 
+	shell = e_preferences_window_get_shell (window);
+
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
 	dialog = g_object_new (CALENDAR_TYPE_PREFS_DIALOG, NULL);
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h
index e01399f..869003f 100644
--- a/calendar/gui/dialogs/cal-prefs-dialog.h
+++ b/calendar/gui/dialogs/cal-prefs-dialog.h
@@ -27,7 +27,7 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <libedataserverui/e-source-selector.h>
-#include <shell/e-shell.h>
+#include <widgets/misc/e-preferences-window.h>
 
 /* Standard GObject macros */
 #define CALENDAR_TYPE_PREFS_DIALOG \
@@ -106,7 +106,7 @@ struct _CalendarPrefsDialogClass {
 };
 
 GType		calendar_prefs_dialog_get_type	(void);
-GtkWidget *	calendar_prefs_dialog_new	(EShell *shell);
+GtkWidget *	calendar_prefs_dialog_new	(EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/modules/addressbook/autocompletion-config.c b/modules/addressbook/autocompletion-config.c
index 99a8b9b..c7ee192 100644
--- a/modules/addressbook/autocompletion-config.c
+++ b/modules/addressbook/autocompletion-config.c
@@ -129,7 +129,7 @@ add_section (GtkWidget *container,
 }
 
 GtkWidget *
-autocompletion_config_new (EShell *shell)
+autocompletion_config_new (EPreferencesWindow *window)
 {
 	EShellSettings *shell_settings;
 	ESourceList *source_list;
@@ -138,6 +138,9 @@ autocompletion_config_new (EShell *shell)
 	GtkWidget *itembox;
 	GtkWidget *widget;
 	GtkWidget *vbox;
+	EShell *shell;
+
+	shell = e_preferences_window_get_shell (window);
 
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
diff --git a/modules/addressbook/autocompletion-config.h b/modules/addressbook/autocompletion-config.h
index 7f94a07..8825161 100644
--- a/modules/addressbook/autocompletion-config.h
+++ b/modules/addressbook/autocompletion-config.h
@@ -27,10 +27,11 @@
 
 #include <glib.h>
 #include <shell/e-shell.h>
+#include <widgets/misc/e-preferences-window.h>
 
 G_BEGIN_DECLS
 
-GtkWidget *	autocompletion_config_new	(EShell *shell);
+GtkWidget *autocompletion_config_new (EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
index 6f3861d..d4bf995 100644
--- a/modules/addressbook/e-book-shell-backend.c
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -301,9 +301,18 @@ book_shell_backend_init_preferences (EShell *shell)
 		"contacts",
 		"preferences-autocompletion",
 		_("Contacts"),
-		autocompletion_config_new (shell),
+		autocompletion_config_new,
 		200);
 
+	preferences_window = e_shell_get_preferences_window (shell);
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"certificates",
+		"preferences-certificates",
+		_("Certificates"),
+		certificate_manager_config_new,
+		700);
+
 	return FALSE;
 }
 
@@ -460,7 +469,6 @@ book_shell_backend_constructed (GObject *object)
 	 *     things that use S/MIME.  Maybe put it in EShell? */
 #ifdef ENABLE_SMIME
 	smime_component_init ();
-	certificate_manager_config_init (shell);
 #endif
 
 	book_shell_backend_init_importers ();
diff --git a/modules/calendar/e-cal-shell-backend.c b/modules/calendar/e-cal-shell-backend.c
index cab1f2f..8861a82 100644
--- a/modules/calendar/e-cal-shell-backend.c
+++ b/modules/calendar/e-cal-shell-backend.c
@@ -442,26 +442,6 @@ cal_shell_backend_init_importers (void)
 }
 
 static gboolean
-cal_shell_backend_init_preferences (EShell *shell)
-{
-	GtkWidget *preferences_window;
-
-	/* This is a main loop idle callback. */
-
-	preferences_window = e_shell_get_preferences_window (shell);
-
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"calendar-and-tasks",
-		"preferences-calendar-and-tasks",
-		_("Calendar and Tasks"),
-		calendar_prefs_dialog_new (shell),
-		600);
-
-	return FALSE;
-}
-
-static gboolean
 cal_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
                                  const gchar *uri)
 {
@@ -696,6 +676,7 @@ cal_shell_backend_constructed (GObject *object)
 {
 	EShell *shell;
 	EShellBackend *shell_backend;
+	GtkWidget *preferences_window;
 
 	shell_backend = E_SHELL_BACKEND (object);
 	shell = e_shell_backend_get_shell (shell_backend);
@@ -716,9 +697,16 @@ cal_shell_backend_constructed (GObject *object)
 
 	e_cal_shell_backend_init_settings (shell);
 
-	/* Initialize preferences after the main loop starts so
-	 * that all EPlugins and EPluginHooks are loaded first. */
-	g_idle_add ((GSourceFunc) cal_shell_backend_init_preferences, shell);
+	/* Setup preference widget factories */
+	preferences_window = e_shell_get_preferences_window (shell);
+
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"calendar-and-tasks",
+		"preferences-calendar-and-tasks",
+		_("Calendar and Tasks"),
+		calendar_prefs_dialog_new,
+		600);
 }
 
 static void
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 5a659cb..09f5068 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -23,7 +23,6 @@
 
 #include <glib/gi18n.h>
 
-#include "e-util/e-account-utils.h"
 #include "e-util/e-binding.h"
 #include "e-util/e-import.h"
 #include "e-util/e-util.h"
@@ -182,52 +181,6 @@ static GtkActionEntry source_entries[] = {
 	  G_CALLBACK (action_mail_folder_new_cb) }
 };
 
-static gboolean
-mail_shell_backend_init_preferences (EShell *shell)
-{
-	EAccountList *account_list;
-	GtkWidget *preferences_window;
-
-	/* This is a main loop idle callback. */
-
-	account_list = e_get_account_list ();
-	preferences_window = e_shell_get_preferences_window (shell);
-
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"mail-accounts",
-		"preferences-mail-accounts",
-		_("Mail Accounts"),
-		em_account_prefs_new (account_list),
-		100);
-
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"mail",
-		"preferences-mail",
-		_("Mail Preferences"),
-		em_mailer_prefs_new (shell),
-		300);
-
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"composer",
-		"preferences-composer",
-		_("Composer Preferences"),
-		em_composer_prefs_new (shell),
-		400);
-
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"system-network-proxy",
-		"preferences-system-network-proxy",
-		_("Network Preferences"),
-		em_network_prefs_new (),
-		500);
-
-	return FALSE;
-}
-
 static void
 mail_shell_backend_sync_store_done_cb (CamelStore *store,
                                        gpointer user_data)
@@ -474,6 +427,7 @@ mail_shell_backend_constructed (GObject *object)
 {
 	EShell *shell;
 	EShellBackend *shell_backend;
+	GtkWidget *preferences_window;
 
 	shell_backend = E_SHELL_BACKEND (object);
 	shell = e_shell_backend_get_shell (shell_backend);
@@ -513,9 +467,41 @@ mail_shell_backend_constructed (GObject *object)
 
 	e_mail_shell_settings_init (shell);
 
-	/* Initialize preferences after the main loop starts so
-	 * that all EPlugins and EPluginHooks are loaded first. */
-	g_idle_add ((GSourceFunc) mail_shell_backend_init_preferences, shell);
+
+	/* Setup preference widget factories */
+	preferences_window = e_shell_get_preferences_window (shell);
+
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"mail-accounts",
+		"preferences-mail-accounts",
+		_("Mail Accounts"),
+		em_account_prefs_new,
+		100);
+
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"mail",
+		"preferences-mail",
+		_("Mail Preferences"),
+		em_mailer_prefs_new,
+		300);
+
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"composer",
+		"preferences-composer",
+		_("Composer Preferences"),
+		em_composer_prefs_new,
+		400);
+
+	e_preferences_window_add_page (
+		E_PREFERENCES_WINDOW (preferences_window),
+		"system-network-proxy",
+		"preferences-system-network-proxy",
+		_("Network Preferences"),
+		em_network_prefs_new,
+		500);
 }
 
 static void
diff --git a/modules/mail/em-account-prefs.c b/modules/mail/em-account-prefs.c
index 90aaa96..310f18e 100644
--- a/modules/mail/em-account-prefs.c
+++ b/modules/mail/em-account-prefs.c
@@ -33,6 +33,7 @@
 #include <glib/gi18n.h>
 
 #include "e-util/e-alert-dialog.h"
+#include "e-util/e-account-utils.h"
 
 #include "e-mail-store.h"
 #include "em-config.h"
@@ -326,8 +327,12 @@ em_account_prefs_get_type (void)
 }
 
 GtkWidget *
-em_account_prefs_new (EAccountList *account_list)
+em_account_prefs_new (EPreferencesWindow *window)
 {
+	EAccountList *account_list;
+
+	account_list = e_get_account_list ();
+
 	g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL);
 
 	return g_object_new (
diff --git a/modules/mail/em-account-prefs.h b/modules/mail/em-account-prefs.h
index 82df8fa..5fe49b6 100644
--- a/modules/mail/em-account-prefs.h
+++ b/modules/mail/em-account-prefs.h
@@ -26,6 +26,7 @@
 #include <table/e-table.h>
 #include <libedataserver/e-account-list.h>
 #include <misc/e-account-manager.h>
+#include <widgets/misc/e-preferences-window.h>
 
 /* Standard GObject macros */
 #define EM_TYPE_ACCOUNT_PREFS \
@@ -61,8 +62,8 @@ struct _EMAccountPrefsClass {
 	EAccountManagerClass parent_class;
 };
 
-GType		em_account_prefs_get_type	(void);
-GtkWidget *	em_account_prefs_new		(EAccountList *account_list);
+GType      em_account_prefs_get_type (void);
+GtkWidget *em_account_prefs_new (EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/modules/mail/em-composer-prefs.c b/modules/mail/em-composer-prefs.c
index a975a3a..a87be9e 100644
--- a/modules/mail/em-composer-prefs.c
+++ b/modules/mail/em-composer-prefs.c
@@ -592,9 +592,10 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
 }
 
 GtkWidget *
-em_composer_prefs_new (EShell *shell)
+em_composer_prefs_new (EPreferencesWindow *window)
 {
 	EMComposerPrefs *prefs;
+	EShell *shell = e_preferences_window_get_shell (window);
 
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
diff --git a/modules/mail/em-composer-prefs.h b/modules/mail/em-composer-prefs.h
index af4979a..4cbcb31 100644
--- a/modules/mail/em-composer-prefs.h
+++ b/modules/mail/em-composer-prefs.h
@@ -27,6 +27,7 @@
 #include <gtkhtml/gtkhtml.h>
 
 #include <shell/e-shell.h>
+#include <widgets/misc/e-preferences-window.h>
 
 /* Standard GObject macros */
 #define EM_TYPE_COMPOSER_PREFS \
@@ -75,10 +76,10 @@ struct _EMComposerPrefsClass {
 	GtkVBoxClass parent_class;
 };
 
-GType		em_composer_prefs_get_type	(void);
-GtkWidget *	em_composer_prefs_new		(EShell *shell);
-void		em_composer_prefs_new_signature (GtkWindow *parent,
-						 gboolean html_mode);
+GType      em_composer_prefs_get_type      (void);
+GtkWidget *em_composer_prefs_new           (EPreferencesWindow *window);
+void       em_composer_prefs_new_signature (GtkWindow *parent,
+					    gboolean html_mode);
 
 G_END_DECLS
 
diff --git a/modules/mail/em-mailer-prefs.c b/modules/mail/em-mailer-prefs.c
index 80163a4..7a6b86d 100644
--- a/modules/mail/em-mailer-prefs.c
+++ b/modules/mail/em-mailer-prefs.c
@@ -1237,9 +1237,10 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs,
 }
 
 GtkWidget *
-em_mailer_prefs_new (EShell *shell)
+em_mailer_prefs_new (EPreferencesWindow *window)
 {
 	EMMailerPrefs *new;
+	EShell *shell = e_preferences_window_get_shell (window);
 
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
diff --git a/modules/mail/em-mailer-prefs.h b/modules/mail/em-mailer-prefs.h
index db77493..a6b3f18 100644
--- a/modules/mail/em-mailer-prefs.h
+++ b/modules/mail/em-mailer-prefs.h
@@ -26,6 +26,7 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <shell/e-shell.h>
+#include <widgets/misc/e-preferences-window.h>
 
 /* Standard GObject macros */
 #define EM_TYPE_MAILER_PREFS \
@@ -108,10 +109,9 @@ struct _EMMailerPrefsClass {
 	GtkVBoxClass parent_class;
 };
 
-GType		em_mailer_prefs_get_type	(void);
-GtkWidget *	create_combo_text_widget	(void);
-
-GtkWidget *	em_mailer_prefs_new		(EShell *shell);
+GType      em_mailer_prefs_get_type (void);
+GtkWidget *create_combo_text_widget (void);
+GtkWidget *em_mailer_prefs_new      (EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/modules/mail/em-network-prefs.c b/modules/mail/em-network-prefs.c
index 85a0a82..efa9e0a 100644
--- a/modules/mail/em-network-prefs.c
+++ b/modules/mail/em-network-prefs.c
@@ -488,7 +488,7 @@ em_network_prefs_construct (EMNetworkPrefs *prefs)
 }
 
 GtkWidget *
-em_network_prefs_new (void)
+em_network_prefs_new (EPreferencesWindow *window)
 {
 	EMNetworkPrefs *new;
 
diff --git a/modules/mail/em-network-prefs.h b/modules/mail/em-network-prefs.h
index c7a70a8..4196686 100644
--- a/modules/mail/em-network-prefs.h
+++ b/modules/mail/em-network-prefs.h
@@ -25,6 +25,7 @@
 
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
+#include <widgets/misc/e-preferences-window.h>
 
 /* Standard GObject macros */
 #define EM_TYPE_NETWORK_PREFS \
@@ -93,8 +94,8 @@ struct _EMNetworkPrefsClass {
 	GtkVBoxClass parent_class;
 };
 
-GType		em_network_prefs_get_type	(void);
-GtkWidget *	em_network_prefs_new		(void);
+GType	   em_network_prefs_get_type (void);
+GtkWidget *em_network_prefs_new      (EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index 0e421c0..c619ac2 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -915,6 +915,7 @@ action_preferences_cb (GtkAction *action,
 
 	shell = e_shell_window_get_shell (shell_window);
 	preferences_window = e_shell_get_preferences_window (shell);
+	e_preferences_window_setup (E_PREFERENCES_WINDOW (preferences_window));
 
 	gtk_window_set_transient_for (
 		GTK_WINDOW (preferences_window),
diff --git a/shell/e-shell.c b/shell/e-shell.c
index a97bc24..9ed43fc 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -1146,7 +1146,7 @@ e_shell_init (EShell *shell)
 
 	shell->priv->settings = g_object_new (E_TYPE_SHELL_SETTINGS, NULL);
 	shell->priv->gconf_client = gconf_client_get_default ();
-	shell->priv->preferences_window = e_preferences_window_new ();
+	shell->priv->preferences_window = e_preferences_window_new (shell);
 	shell->priv->backends_by_name = backends_by_name;
 	shell->priv->backends_by_scheme = backends_by_scheme;
 	shell->priv->safe_mode = e_file_lock_exists ();
diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c
index e35bb1d..35dd650 100644
--- a/smime/gui/certificate-manager.c
+++ b/smime/gui/certificate-manager.c
@@ -1090,15 +1090,18 @@ populate_ui (CertificateManagerData *cfm)
 	return FALSE;
 }
 
-void
-certificate_manager_config_init (EShell *shell)
+
+GtkWidget *
+certificate_manager_config_new (EPreferencesWindow *window)
 {
-	CertificateManagerData *cfm_data;
-	GtkWidget *preferences_window;
+	EShell *shell;
 	GtkWidget *parent;
 	GtkWidget *widget;
+	CertificateManagerData *cfm_data;
+
+	shell = e_preferences_window_get_shell (window);
 
-	g_return_if_fail (E_IS_SHELL (shell));
+	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
 	/* We need to peek the db here to make sure it (and NSS) are fully initialized. */
 	e_cert_db_peek ();
@@ -1148,11 +1151,5 @@ certificate_manager_config_init (EShell *shell)
 	gtk_widget_set_sensitive(cfm_data->backup_your_button, FALSE);
 	gtk_widget_set_sensitive(cfm_data->backup_all_your_button, FALSE);
 
-	preferences_window = e_shell_get_preferences_window (shell);
-	e_preferences_window_add_page (
-		E_PREFERENCES_WINDOW (preferences_window),
-		"certificates",
-		"preferences-certificates",
-		_("Certificates"),
-		widget, 700);
+	return widget;
 }
diff --git a/smime/gui/certificate-manager.h b/smime/gui/certificate-manager.h
index 9107e20..ebe7111 100644
--- a/smime/gui/certificate-manager.h
+++ b/smime/gui/certificate-manager.h
@@ -23,12 +23,13 @@
 #ifndef _CERTIFICATE_MANAGER_H_
 #define _CERTIFICATE_MANAGER_H
 
-#include <glib.h>
+#include <gtk/gtk.h>
 #include <shell/e-shell.h>
+#include <widgets/misc/e-preferences-window.h>
 
 G_BEGIN_DECLS
 
-void		certificate_manager_config_init	(EShell *shell);
+GtkWidget *certificate_manager_config_new (EPreferencesWindow *window);
 
 G_END_DECLS
 
diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c
index 9203855..493727c 100644
--- a/widgets/misc/e-preferences-window.c
+++ b/widgets/misc/e-preferences-window.c
@@ -32,6 +32,9 @@
 	((obj), E_TYPE_PREFERENCES_WINDOW, EPreferencesWindowPrivate))
 
 struct _EPreferencesWindowPrivate {
+	gboolean   setup;
+	gpointer   shell;
+
 	GtkWidget *icon_view;
 	GtkWidget *scroll;
 	GtkWidget *notebook;
@@ -138,6 +141,11 @@ preferences_window_dispose (GObject *object)
 		priv->notebook = NULL;
 	}
 
+	if (priv->shell) {
+		g_object_remove_weak_pointer (priv->shell, &priv->shell);
+		priv->shell = NULL;
+	}
+
 	g_hash_table_remove_all (priv->index);
 
 	/* Chain up to parent's dispose() method. */
@@ -165,6 +173,8 @@ preferences_window_show (GtkWidget *widget)
 	GtkTreePath *path;
 
 	priv = E_PREFERENCES_WINDOW_GET_PRIVATE (widget);
+	if (!priv->setup)
+		g_warning ("Error - preferences window has not been setup correctly");
 
 	icon_view = GTK_ICON_VIEW (priv->icon_view);
 
@@ -375,9 +385,27 @@ e_preferences_window_get_type (void)
 }
 
 GtkWidget *
-e_preferences_window_new (void)
+e_preferences_window_new (gpointer shell)
+{
+	EPreferencesWindow *window;
+
+	window = g_object_new (E_TYPE_PREFERENCES_WINDOW, NULL);
+
+	/* ideally should be an object property */
+	window->priv->shell = shell;
+	if (shell)
+		g_object_add_weak_pointer (shell, &window->priv->shell);
+
+	return GTK_WIDGET (window);
+}
+
+gpointer
+e_preferences_window_get_shell (EPreferencesWindow *window)
 {
-	return g_object_new (E_TYPE_PREFERENCES_WINDOW, NULL);
+	g_return_val_if_fail (E_IS_PREFERENCES_WINDOW (window), NULL);
+	g_return_val_if_fail (window->priv != NULL, NULL);
+
+	return window->priv->shell;
 }
 
 void
@@ -385,7 +413,7 @@ e_preferences_window_add_page (EPreferencesWindow *window,
                                const gchar *page_name,
                                const gchar *icon_name,
                                const gchar *caption,
-                               GtkWidget *widget,
+			       EPreferencesWindowCreatePageFn create_fn,
                                gint sort_order)
 {
 	GtkTreeRowReference *reference;
@@ -396,13 +424,14 @@ e_preferences_window_add_page (EPreferencesWindow *window,
 	GHashTable *index;
 	GdkPixbuf *pixbuf;
 	GtkTreeIter iter;
+	GtkWidget *align;
 	gint page;
 
 	g_return_if_fail (E_IS_PREFERENCES_WINDOW (window));
+	g_return_if_fail (create_fn != NULL);
 	g_return_if_fail (page_name != NULL);
 	g_return_if_fail (icon_name != NULL);
 	g_return_if_fail (caption != NULL);
-	g_return_if_fail (GTK_IS_WIDGET (widget));
 
 	icon_view = GTK_ICON_VIEW (window->priv->icon_view);
 	notebook = GTK_NOTEBOOK (window->priv->notebook);
@@ -425,8 +454,10 @@ e_preferences_window_add_page (EPreferencesWindow *window,
 	g_hash_table_insert (index, g_strdup (page_name), reference);
 	gtk_tree_path_free (path);
 
-	gtk_widget_show (widget);
-	gtk_notebook_append_page (notebook, widget, NULL);
+	align = g_object_new (GTK_TYPE_ALIGNMENT, NULL);
+	gtk_widget_show (GTK_WIDGET (align));
+	g_object_set_data (G_OBJECT (align), "create_fn", create_fn);
+	gtk_notebook_append_page (notebook, align, NULL);
 
 	/* Force GtkIconView to recalculate the text wrap width,
 	 * otherwise we get a really narrow icon list on the left
@@ -445,6 +476,7 @@ e_preferences_window_show_page (EPreferencesWindow *window,
 
 	g_return_if_fail (E_IS_PREFERENCES_WINDOW (window));
 	g_return_if_fail (page_name != NULL);
+	g_return_if_fail (window->priv->setup);
 
 	icon_view = GTK_ICON_VIEW (window->priv->icon_view);
 	reference = g_hash_table_lookup (window->priv->index, page_name);
@@ -466,6 +498,7 @@ e_preferences_window_filter_page (EPreferencesWindow *window,
 
 	g_return_if_fail (E_IS_PREFERENCES_WINDOW (window));
 	g_return_if_fail (page_name != NULL);
+	g_return_if_fail (window->priv->setup);
 
 	icon_view = GTK_ICON_VIEW (window->priv->icon_view);
 	reference = g_hash_table_lookup (window->priv->index, page_name);
@@ -487,3 +520,38 @@ e_preferences_window_filter_page (EPreferencesWindow *window,
 		gtk_widget_show (window->priv->scroll);
 }
 
+/*
+ * Create all the deferred configuration pages.
+ */
+void
+e_preferences_window_setup (EPreferencesWindow *window)
+{
+	gint i, num;
+	GtkNotebook *notebook;
+	EPreferencesWindowPrivate *priv;
+
+	priv = E_PREFERENCES_WINDOW_GET_PRIVATE (window);
+	notebook = GTK_NOTEBOOK (priv->notebook);
+	num = gtk_notebook_get_n_pages (notebook);
+
+	for (i = 0; i < num; i++) {
+		GtkBin *align;
+		GtkWidget *content;
+		EPreferencesWindowCreatePageFn create_fn;
+
+		align = GTK_BIN (gtk_notebook_get_nth_page (notebook, i));
+		create_fn = g_object_get_data (G_OBJECT (align), "create_fn");
+
+		if (!create_fn || gtk_bin_get_child (align))
+			continue;
+
+		
+		content = create_fn (window);
+		if (content) {
+			gtk_widget_show (content);
+			gtk_container_add (GTK_CONTAINER (align), content);
+		}
+	}
+	
+	priv->setup = TRUE;
+}
diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h
index 00b51b8..3606d6e 100644
--- a/widgets/misc/e-preferences-window.h
+++ b/widgets/misc/e-preferences-window.h
@@ -58,13 +58,17 @@ struct _EPreferencesWindowClass {
 	GtkWindowClass parent_class;
 };
 
+typedef GtkWidget *(*EPreferencesWindowCreatePageFn) (EPreferencesWindow *window);
+
 GType		e_preferences_window_get_type	(void);
-GtkWidget *	e_preferences_window_new	(void);
+GtkWidget *	e_preferences_window_new	(gpointer shell);
+gpointer	e_preferences_window_get_shell	(EPreferencesWindow *window);
+void		e_preferences_window_setup	(EPreferencesWindow *window);
 void		e_preferences_window_add_page	(EPreferencesWindow *window,
 						 const gchar *page_name,
 						 const gchar *icon_name,
 						 const gchar *caption,
-						 GtkWidget *widget,
+						 EPreferencesWindowCreatePageFn create_fn,
 						 gint sort_order);
 void		e_preferences_window_show_page	(EPreferencesWindow *window,
 						 const gchar *page_name);
diff --git a/widgets/misc/test-preferences-window.c b/widgets/misc/test-preferences-window.c
index dec6b85..c737964 100644
--- a/widgets/misc/test-preferences-window.c
+++ b/widgets/misc/test-preferences-window.c
@@ -23,31 +23,50 @@
 
 #include <gtk/gtk.h>
 
-#define NUM_PAGES 10
-
-static void
-add_pages (EPreferencesWindow *preferences_window)
+static GtkWidget *
+create_page_number (gint i)
 {
-	gint i;
+	gchar *caption;
+	GtkWidget *widget;
+	
+	caption = g_strdup_printf ("Title of page %d", i);
 
-	for (i = 0; i < NUM_PAGES; i++) {
-		GtkWidget *widget;
-		gchar *caption;
-		gchar *page_name;
+	widget = gtk_label_new (caption);
+	gtk_widget_show (widget);
 
-		caption = g_strdup_printf ("Title of page %d", i);
-		page_name = g_strdup_printf ("page-%d", i);
+	g_free (caption);
 
-		widget = gtk_label_new (caption);
-		gtk_widget_show (widget);
+	return widget;
+}
 
-		e_preferences_window_add_page (
-			preferences_window, page_name,
-			"gtk-properties", caption, widget, i);
+static GtkWidget *
+create_page_zero (EPreferencesWindow *preferences_window)
+{
+	return create_page_number (0);
+}
+static GtkWidget *
+create_page_one (EPreferencesWindow *preferences_window)
+{
+	return create_page_number (1);
+}
+static GtkWidget *
+create_page_two (EPreferencesWindow *preferences_window)
+{
+	return create_page_number (2);
+}
 
-		g_free (caption);
-		g_free (page_name);
-	}
+static void
+add_pages (EPreferencesWindow *preferences_window)
+{
+	e_preferences_window_add_page (preferences_window, "page-0",
+				       "gtk-properties", "title 0",
+				       create_page_zero, 0);
+	e_preferences_window_add_page (preferences_window, "page-1",
+				       "gtk-properties", "title 1",
+				       create_page_one, 1);
+	e_preferences_window_add_page (preferences_window, "page-2",
+				       "gtk-properties", "title 2",
+				       create_page_two, 2);
 }
 
 static gint
@@ -67,7 +86,7 @@ main (gint argc, gchar **argv)
 
 	gtk_init (&argc, &argv);
 
-	window = e_preferences_window_new ();
+	window = e_preferences_window_new (NULL);
 	gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
 
 	g_signal_connect(
@@ -75,6 +94,7 @@ main (gint argc, gchar **argv)
 		G_CALLBACK (delete_event_callback), NULL);
 
 	add_pages (E_PREFERENCES_WINDOW (window));
+	e_preferences_window_setup (E_PREFERENCES_WINDOW (window));
 
 	gtk_widget_show (window);
 



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