[devhelp/wip/prefs] dh-preferences: convert it to a templated gobject



commit 08f9dd3bfffdb0b6431e209963340f513990f939
Author: Ignacio Casal Quinteiro <ignacio casal nice-software com>
Date:   Sun Sep 22 23:18:49 2013 +0200

    dh-preferences: convert it to a templated gobject

 src/dh-app.c                          |    7 +-
 src/dh-preferences.c                  |  821 ++++++++++++++++-----------------
 src/dh-preferences.h                  |   25 +-
 src/{devhelp.ui => dh-preferences.ui} |  280 ++++++------
 src/dh.gresource.xml                  |    2 +-
 5 files changed, 562 insertions(+), 573 deletions(-)
---
diff --git a/src/dh-app.c b/src/dh-app.c
index dfd8139..cd1b013 100644
--- a/src/dh-app.c
+++ b/src/dh-app.c
@@ -179,7 +179,12 @@ preferences_cb (GSimpleAction *action,
                 GVariant      *parameter,
                 gpointer       user_data)
 {
-        dh_preferences_show_dialog ();
+        DhApp *app = DH_APP (user_data);
+        GtkWindow *window;
+
+        window = dh_app_peek_first_window (app);
+
+        dh_preferences_show_dialog (window);
 }
 
 static void
diff --git a/src/dh-preferences.c b/src/dh-preferences.c
index ce4e4c5..43429dd 100644
--- a/src/dh-preferences.c
+++ b/src/dh-preferences.c
@@ -28,8 +28,18 @@
 #include "dh-app.h"
 #include "dh-settings.h"
 
+static GtkWidget *prefs_dialog = NULL;
+
+enum {
+        COLUMN_ENABLED = 0,
+        COLUMN_TITLE,
+        COLUMN_BOOK,
+        COLUMN_WEIGHT,
+        COLUMN_INCONSISTENT,
+        N_COLUMNS
+};
+
 typedef struct {
-        GtkWidget     *dialog;
         DhBookManager *book_manager;
         DhSettings    *settings;
 
@@ -39,10 +49,10 @@ typedef struct {
         gulong group_by_language_id;
 
         /* Fonts tab */
-        GtkWidget *system_fonts_button;
-        GtkWidget *fonts_table;
-        GtkWidget *variable_font_button;
-        GtkWidget *fixed_font_button;
+        GtkCheckButton *system_fonts_button;
+        GtkGrid *fonts_grid;
+        GtkFontButton *variable_font_button;
+        GtkFontButton *fixed_font_button;
         guint      use_system_fonts_id;
         guint      system_var_id;
         guint      system_fixed_id;
@@ -50,293 +60,87 @@ typedef struct {
         guint      fixed_id;
 
         /* Book Shelf tab */
+        GtkCellRendererToggle *bookshelf_enabled_toggle;
         GtkListStore *bookshelf_store;
-        GtkWidget    *bookshelf_group_by_language_button;
-} DhPreferences;
-
-/* Bookshelf-tab related */
-static void     preferences_bookshelf_tree_selection_toggled_cb    (GtkCellRendererToggle *cell_renderer,
-                                                                    gchar                 *path,
-                                                                    gpointer               user_data);
-static void     preferences_bookshelf_populate_store               (void);
-static void     preferences_bookshelf_clean_store                  (void);
-static void     preferences_bookshelf_add_book_to_store            (DhBook                *book,
-                                                                    gboolean               
group_by_language);
-static void     preferences_bookshelf_book_created_cb              (DhBookManager         *book_manager,
-                                                                    GObject               *book_object,
-                                                                    gpointer               user_data);
-static void     preferences_bookshelf_book_deleted_cb              (DhBookManager         *book_manager,
-                                                                    GObject               *book_object,
-                                                                    gpointer               user_data);
-static void     preferences_bookshelf_find_language_group          (const gchar           *language,
-                                                                    GtkTreeIter           *exact_iter,
-                                                                    gboolean              *exact_found,
-                                                                    GtkTreeIter           *next_iter,
-                                                                    gboolean              *next_found);
-static void     preferences_bookshelf_find_book                    (DhBook                *book,
-                                                                    const GtkTreeIter     *first,
-                                                                    GtkTreeIter           *exact_iter,
-                                                                    gboolean              *exact_found,
-                                                                    GtkTreeIter           *next_iter,
-                                                                    gboolean              *next_found);
-static void     preferences_bookshelf_group_by_language_cb         (GObject               *object,
-                                                                    GParamSpec            *pspec,
-                                                                    gpointer               user_data);
-
-/* Book list store columns... */
-#define LTCOLUMN_ENABLED      0
-#define LTCOLUMN_TITLE        1
-#define LTCOLUMN_BOOK         2
-#define LTCOLUMN_WEIGHT       3
-#define LTCOLUMN_INCONSISTENT 4
-
-static DhPreferences *prefs;
-
-static void
-preferences_init (void)
-{
-        GApplication *app;
-
-        if (prefs) {
-                return;
-        }
-
-        app = g_application_get_default ();
-        if (!app) {
-                g_warning ("Cannot launch Preferences: No default application found");
-                return;
-        }
+        GtkCheckButton *bookshelf_group_by_language_button;
+} DhPreferencesPrivate;
 
-        prefs = g_new0 (DhPreferences, 1);
-        prefs->settings = dh_settings_get ();
-        prefs->book_manager = g_object_ref (dh_app_peek_book_manager (DH_APP (app)));
-        prefs->book_created_id = g_signal_connect (prefs->book_manager,
-                                                   "book-created",
-                                                   G_CALLBACK (preferences_bookshelf_book_created_cb),
-                                                   NULL);
-        prefs->book_deleted_id = g_signal_connect (prefs->book_manager,
-                                                   "book-deleted",
-                                                   G_CALLBACK (preferences_bookshelf_book_deleted_cb),
-                                                   NULL);
-        prefs->group_by_language_id = g_signal_connect (prefs->book_manager,
-                                                        "notify::group-by-language",
-                                                        G_CALLBACK 
(preferences_bookshelf_group_by_language_cb),
-                                                        NULL);
-}
+G_DEFINE_TYPE_WITH_PRIVATE (DhPreferences, dh_preferences, GTK_TYPE_DIALOG)
 
 static void
-preferences_shutdown (void)
+dh_preferences_finalize (GObject *object)
 {
-        if (!prefs) {
-                return;
-        }
+        DhPreferencesPrivate *priv;
 
-        g_clear_object (&prefs->settings);
+        priv = dh_preferences_get_instance_private (DH_PREFERENCES (object));
 
-        g_signal_handler_disconnect (prefs->book_manager, prefs->book_created_id);
-        g_signal_handler_disconnect (prefs->book_manager, prefs->book_deleted_id);
-        g_signal_handler_disconnect (prefs->book_manager, prefs->group_by_language_id);
-        g_clear_object (&prefs->book_manager);
+        g_clear_object (&priv->settings);
 
-        gtk_list_store_clear (prefs->bookshelf_store);
-        gtk_widget_destroy (GTK_WIDGET (prefs->dialog));
+        g_signal_handler_disconnect (priv->book_manager, priv->book_created_id);
+        g_signal_handler_disconnect (priv->book_manager, priv->book_deleted_id);
+        g_signal_handler_disconnect (priv->book_manager, priv->group_by_language_id);
+        g_clear_object (&priv->book_manager);
 
-        g_free (prefs);
-        prefs = NULL;
+        G_OBJECT_CLASS (dh_preferences_parent_class)->finalize (object);
 }
 
 static void
-preferences_fonts_system_fonts_toggled_cb (GtkToggleButton *button,
-                                           gpointer         user_data)
+dh_preferences_response (GtkDialog *dlg,
+                         gint       response_id)
 {
-        DhPreferences *prefs = user_data;
-        gboolean       active;
-
-        active = gtk_toggle_button_get_active (button);
-
-        gtk_widget_set_sensitive (prefs->fonts_table, !active);
+        gtk_widget_destroy (GTK_WIDGET (dlg));
 }
 
 static void
-preferences_bookshelf_set_language_inconsistent (const gchar *language)
+dh_preferences_class_init (DhPreferencesClass *klass)
 {
-        GtkTreeIter loop_iter;
-        GtkTreeIter language_iter;
-        gboolean    language_iter_found;
-        gboolean    one_book_enabled = FALSE;
-        gboolean    one_book_disabled = FALSE;
-
-        preferences_bookshelf_find_language_group (language,
-                                                   &language_iter,
-                                                   &language_iter_found,
-                                                   NULL,
-                                                   NULL);
-        if (!language_iter_found) {
-                return;
-        }
-
-        loop_iter = language_iter;
-        while (gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                         &loop_iter)) {
-                DhBook   *book;
-                gboolean  enabled;
-
-                gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                    &loop_iter,
-                                    LTCOLUMN_BOOK,       &book,
-                                    LTCOLUMN_ENABLED,    &enabled,
-                                    -1);
-                if (!book) {
-                        /* Reached next language group */
-                        break;
-                }
-                g_object_unref (book);
-
-                if (enabled)
-                        one_book_enabled = TRUE;
-                else
-                        one_book_disabled = TRUE;
-
-                if (one_book_enabled == one_book_disabled)
-                        break;
-        }
-
-        /* If at least one book is enabled AND another book is disabled,
-         * we need to set inconsistent state */
-        if (one_book_enabled == one_book_disabled) {
-                gtk_list_store_set (prefs->bookshelf_store, &language_iter,
-                                    LTCOLUMN_INCONSISTENT, TRUE,
-                                    -1);
-                return;
-        }
-
-        gtk_list_store_set (prefs->bookshelf_store, &language_iter,
-                            LTCOLUMN_ENABLED, one_book_enabled,
-                            LTCOLUMN_INCONSISTENT, FALSE,
-                            -1);
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+        GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
+
+        object_class->finalize = dh_preferences_finalize;
+
+        dialog_class->response = dh_preferences_response;
+
+        /* Bind class to template */
+        gtk_widget_class_set_template_from_resource (widget_class,
+                                                     "/org/gnome/devhelp/dh-preferences.ui");
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, system_fonts_button);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, fonts_grid);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, variable_font_button);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, fixed_font_button);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, bookshelf_store);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, 
bookshelf_group_by_language_button);
+        gtk_widget_class_bind_template_child_private (widget_class, DhPreferences, bookshelf_enabled_toggle);
 }
 
 static void
-preferences_bookshelf_tree_selection_toggled_cb (GtkCellRendererToggle *cell_renderer,
-                                                 gchar                 *path,
-                                                 gpointer               user_data)
+preferences_bookshelf_clean_store (DhPreferences *prefs)
 {
-        GtkTreeIter iter;
-
-        if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                                 &iter,
-                                                 path))
-        {
-                gpointer book = NULL;
-                gboolean enabled;
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
 
-                gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                    &iter,
-                                    LTCOLUMN_BOOK,       &book,
-                                    LTCOLUMN_ENABLED,    &enabled,
-                                    -1);
-
-                if (book) {
-                        /* Update book conf */
-                        dh_book_set_enabled (book, !enabled);
-
-                        gtk_list_store_set (prefs->bookshelf_store, &iter,
-                                            LTCOLUMN_ENABLED, !enabled,
-                                            -1);
-                        /* Now we need to look for the language group of this item,
-                         * in order to set the inconsistent state if applies */
-                        if (dh_book_manager_get_group_by_language (prefs->book_manager)) {
-                                preferences_bookshelf_set_language_inconsistent (dh_book_get_language 
(book));
-                        }
-
-                } else {
-                        GtkTreeIter loop_iter;
-
-                        /* We should only reach this if we are grouping by language */
-                        g_assert (dh_book_manager_get_group_by_language (prefs->book_manager) == TRUE);
-
-                        /* Set new status in the language group item */
-                        gtk_list_store_set (prefs->bookshelf_store, &iter,
-                                            LTCOLUMN_ENABLED,      !enabled,
-                                            LTCOLUMN_INCONSISTENT, FALSE,
-                                            -1);
-
-                        /* And set new status in all books of the same language */
-                        loop_iter = iter;
-                        while (gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                                         &loop_iter)) {
-                                gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                                    &loop_iter,
-                                                    LTCOLUMN_BOOK, &book,
-                                                    -1);
-                                if (!book) {
-                                        /* Found next language group, finish */
-                                        return;
-                                }
-
-                                /* Update book conf */
-                                dh_book_set_enabled (book, !enabled);
-
-                                gtk_list_store_set (prefs->bookshelf_store,
-                                                    &loop_iter,
-                                                    LTCOLUMN_ENABLED, !enabled,
-                                                    -1);
-                        }
-                }
-        }
-}
-
-static void
-preferences_bookshelf_group_by_language_cb (GObject    *object,
-                                            GParamSpec *pspec,
-                                            gpointer    user_data)
-{
-        preferences_bookshelf_clean_store ();
-        preferences_bookshelf_populate_store ();
-}
-
-static void
-preferences_bookshelf_book_created_cb (DhBookManager *book_manager,
-                                       GObject       *book_object,
-                                       gpointer       user_data)
-{
-        preferences_bookshelf_add_book_to_store (DH_BOOK (book_object),
-                                                 dh_book_manager_get_group_by_language 
(prefs->book_manager));
+        gtk_list_store_clear (priv->bookshelf_store);
 }
 
-static void
-preferences_bookshelf_book_deleted_cb (DhBookManager *book_manager,
-                                       GObject       *book_object,
-                                       gpointer       user_data)
-{
-        DhBook      *book = DH_BOOK (book_object);
-        GtkTreeIter  exact_iter;
-        gboolean     exact_iter_found;
-
-        preferences_bookshelf_find_book (book,
-                                         NULL,
-                                         &exact_iter,
-                                         &exact_iter_found,
-                                         NULL,
-                                         NULL);
-        if (exact_iter_found) {
-                gtk_list_store_remove (prefs->bookshelf_store, &exact_iter);
-                preferences_bookshelf_set_language_inconsistent (dh_book_get_language (book));
-        }
-}
-
-/* Tries to find:
- *  - An exact match of the language group
- *  - The language group which should be just after our given language group.
+/* Tries to find, starting at 'first' (if given):
+ *  - An exact match of the book
+ *  - The book which should be just after our given book:
+ *      - If first is set, the next book must be in the same language group
+ *         as the given book.
+ *      - If first is NOT set, we don't care about language groups as we're
+ *         iterating from the beginning of the list.
  *  - Both.
  */
 static void
-preferences_bookshelf_find_language_group (const gchar *language,
-                                           GtkTreeIter *exact_iter,
-                                           gboolean    *exact_found,
-                                           GtkTreeIter *next_iter,
-                                           gboolean    *next_found)
+preferences_bookshelf_find_book (DhPreferences     *prefs,
+                                 DhBook            *book,
+                                 const GtkTreeIter *first,
+                                 GtkTreeIter       *exact_iter,
+                                 gboolean          *exact_found,
+                                 GtkTreeIter       *next_iter,
+                                 gboolean          *next_found)
 {
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
         GtkTreeIter loop_iter;
 
         g_assert ((exact_iter && exact_found) || (next_iter && next_found));
@@ -347,72 +151,71 @@ preferences_bookshelf_find_language_group (const gchar *language,
         if (next_found)
                 *next_found = FALSE;
 
-        if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->bookshelf_store),
-                                            &loop_iter)) {
-                /* Store is empty, not found */
-                return;
+        /* Setup iteration start */
+        if (!first) {
+                /* If no first given, start iterating from the start of the model */
+                if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->bookshelf_store), &loop_iter)) {
+                        /* Store is empty, not found */
+                        return;
+                }
+        } else {
+                loop_iter = *first;
         }
 
         do {
-                DhBook *book = NULL;
-                gchar  *title = NULL;
+                DhBook *in_list_book = NULL;
 
-                /* Look for language titles, which are those where there
-                 * is no book object associated in the row */
-                gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
+                gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
                                     &loop_iter,
-                                    LTCOLUMN_TITLE, &title,
-                                    LTCOLUMN_BOOK,  &book,
+                                    COLUMN_BOOK, &in_list_book,
                                     -1);
 
-                /* If we got a book, it's not a language row */
-                if (book) {
-                        g_free (title);
-                        g_object_unref (book);
-                        continue;
+                /* We may have reached the start of the next language group here */
+                if (first && !in_list_book) {
+                        *next_iter = loop_iter;
+                        *next_found = TRUE;
+                        return;
                 }
 
+                /* We can compare pointers directly as we're playing with references
+                 * of the same object */
                 if (exact_iter &&
-                    g_ascii_strcasecmp (title, language) == 0) {
-                        /* Exact match found! */
+                    in_list_book == book) {
                         *exact_iter = loop_iter;
                         *exact_found = TRUE;
                         if (!next_iter) {
                                 /* If we were not requested to look for the next one, end here */
-                                g_free (title);
+                                g_object_unref (in_list_book);
                                 return;
                         }
                 } else if (next_iter &&
-                           g_ascii_strcasecmp (title, language) > 0) {
+                           dh_book_cmp_by_title (in_list_book, book) > 0) {
                         *next_iter = loop_iter;
                         *next_found = TRUE;
-                        /* There's no way to have an exact match after the next, so end here */
-                        g_free (title);
+                        g_object_unref (in_list_book);
                         return;
                 }
 
-                g_free (title);
-        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->bookshelf_store),
+                if (in_list_book)
+                        g_object_unref (in_list_book);
+        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->bookshelf_store),
                                            &loop_iter));
 }
 
-/* Tries to find, starting at 'first' (if given):
- *  - An exact match of the book
- *  - The book which should be just after our given book:
- *      - If first is set, the next book must be in the same language group
- *         as the given book.
- *      - If first is NOT set, we don't care about language groups as we're
- *         iterating from the beginning of the list.
+/* Tries to find:
+ *  - An exact match of the language group
+ *  - The language group which should be just after our given language group.
  *  - Both.
  */
 static void
-preferences_bookshelf_find_book (DhBook            *book,
-                                 const GtkTreeIter *first,
-                                 GtkTreeIter       *exact_iter,
-                                 gboolean          *exact_found,
-                                 GtkTreeIter       *next_iter,
-                                 gboolean          *next_found)
+preferences_bookshelf_find_language_group (DhPreferences *prefs,
+                                           const gchar   *language,
+                                           GtkTreeIter   *exact_iter,
+                                           gboolean      *exact_found,
+                                           GtkTreeIter   *next_iter,
+                                           gboolean      *next_found)
 {
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
         GtkTreeIter loop_iter;
 
         g_assert ((exact_iter && exact_found) || (next_iter && next_found));
@@ -423,61 +226,61 @@ preferences_bookshelf_find_book (DhBook            *book,
         if (next_found)
                 *next_found = FALSE;
 
-        /* Setup iteration start */
-        if (!first) {
-                /* If no first given, start iterating from the start of the model */
-                if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->bookshelf_store), &loop_iter)) {
-                        /* Store is empty, not found */
-                        return;
-                }
-        } else {
-                loop_iter = *first;
+        if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->bookshelf_store),
+                                            &loop_iter)) {
+                /* Store is empty, not found */
+                return;
         }
 
         do {
-                DhBook *in_list_book = NULL;
+                DhBook *book = NULL;
+                gchar  *title = NULL;
 
-                gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
+                /* Look for language titles, which are those where there
+                 * is no book object associated in the row */
+                gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
                                     &loop_iter,
-                                    LTCOLUMN_BOOK, &in_list_book,
+                                    COLUMN_TITLE, &title,
+                                    COLUMN_BOOK,  &book,
                                     -1);
 
-                /* We may have reached the start of the next language group here */
-                if (first && !in_list_book) {
-                        *next_iter = loop_iter;
-                        *next_found = TRUE;
-                        return;
+                /* If we got a book, it's not a language row */
+                if (book) {
+                        g_free (title);
+                        g_object_unref (book);
+                        continue;
                 }
 
-                /* We can compare pointers directly as we're playing with references
-                 * of the same object */
                 if (exact_iter &&
-                    in_list_book == book) {
+                    g_ascii_strcasecmp (title, language) == 0) {
+                        /* Exact match found! */
                         *exact_iter = loop_iter;
                         *exact_found = TRUE;
                         if (!next_iter) {
                                 /* If we were not requested to look for the next one, end here */
-                                g_object_unref (in_list_book);
+                                g_free (title);
                                 return;
                         }
                 } else if (next_iter &&
-                           dh_book_cmp_by_title (in_list_book, book) > 0) {
+                           g_ascii_strcasecmp (title, language) > 0) {
                         *next_iter = loop_iter;
                         *next_found = TRUE;
-                        g_object_unref (in_list_book);
+                        /* There's no way to have an exact match after the next, so end here */
+                        g_free (title);
                         return;
                 }
 
-                if (in_list_book)
-                        g_object_unref (in_list_book);
-        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->bookshelf_store),
+                g_free (title);
+        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->bookshelf_store),
                                            &loop_iter));
 }
 
 static void
-preferences_bookshelf_add_book_to_store (DhBook   *book,
-                                         gboolean  group_by_language)
+preferences_bookshelf_add_book_to_store (DhPreferences *prefs,
+                                         DhBook        *book,
+                                         gboolean       group_by_language)
 {
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
         GtkTreeIter  book_iter;
 
         /* If grouping by language we need to add the language categories */
@@ -493,7 +296,8 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
                 language_title = dh_book_get_language (book);
 
                 /* Look for the proper language group */
-                preferences_bookshelf_find_language_group (language_title,
+                preferences_bookshelf_find_language_group (prefs,
+                                                           language_title,
                                                            &language_iter,
                                                            &language_iter_found,
                                                            &next_language_iter,
@@ -501,21 +305,21 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
                 /* New language group needs to be created? */
                 if (!language_iter_found) {
                         if (!next_language_iter_found) {
-                                gtk_list_store_append (prefs->bookshelf_store,
+                                gtk_list_store_append (priv->bookshelf_store,
                                                        &language_iter);
                         } else {
-                                gtk_list_store_insert_before (prefs->bookshelf_store,
+                                gtk_list_store_insert_before (priv->bookshelf_store,
                                                               &language_iter,
                                                               &next_language_iter);
                         }
 
-                        gtk_list_store_set (prefs->bookshelf_store,
+                        gtk_list_store_set (priv->bookshelf_store,
                                             &language_iter,
-                                            LTCOLUMN_ENABLED,      dh_book_get_enabled (book),
-                                            LTCOLUMN_TITLE,        language_title,
-                                            LTCOLUMN_BOOK,         NULL,
-                                            LTCOLUMN_WEIGHT,       PANGO_WEIGHT_BOLD,
-                                            LTCOLUMN_INCONSISTENT, FALSE,
+                                            COLUMN_ENABLED,      dh_book_get_enabled (book),
+                                            COLUMN_TITLE,        language_title,
+                                            COLUMN_BOOK,         NULL,
+                                            COLUMN_WEIGHT,       PANGO_WEIGHT_BOLD,
+                                            COLUMN_INCONSISTENT, FALSE,
                                             -1);
 
                         first_in_language = TRUE;
@@ -523,7 +327,7 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
 
                 /* If we got to add first book in a given language group, just append it. */
                 if (first_in_language) {
-                        gtk_list_store_insert_after (prefs->bookshelf_store,
+                        gtk_list_store_insert_after (priv->bookshelf_store,
                                                      &book_iter,
                                                      &language_iter);
                 } else {
@@ -534,37 +338,38 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
                         gboolean    language_enabled = FALSE;
 
                         /* We may need to reset the inconsistent status of the language item */
-                        gtk_tree_model_get (GTK_TREE_MODEL (prefs->bookshelf_store),
+                        gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
                                             &language_iter,
-                                            LTCOLUMN_ENABLED, &language_enabled,
-                                            LTCOLUMN_INCONSISTENT, &language_inconsistent,
+                                            COLUMN_ENABLED, &language_enabled,
+                                            COLUMN_INCONSISTENT, &language_inconsistent,
                                             -1);
                         /* If inconsistent already, do nothing */
                         if (!language_inconsistent) {
                                 if (language_enabled != dh_book_get_enabled (book)) {
-                                        gtk_list_store_set (prefs->bookshelf_store,
+                                        gtk_list_store_set (priv->bookshelf_store,
                                                             &language_iter,
-                                                            LTCOLUMN_INCONSISTENT, TRUE,
+                                                            COLUMN_INCONSISTENT, TRUE,
                                                             -1);
                                 }
                         }
 
                         /* The language will have at least one book, so we move iter to it */
                         first_book_iter = language_iter;
-                        gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->bookshelf_store), &first_book_iter);
+                        gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->bookshelf_store), &first_book_iter);
 
                         /* Find next possible book in language group */
-                        preferences_bookshelf_find_book (book,
+                        preferences_bookshelf_find_book (prefs,
+                                                         book,
                                                          &first_book_iter,
                                                          NULL,
                                                          NULL,
                                                          &next_book_iter,
                                                          &next_book_iter_found);
                         if (!next_book_iter_found) {
-                                gtk_list_store_append (prefs->bookshelf_store,
+                                gtk_list_store_append (priv->bookshelf_store,
                                                        &book_iter);
                         } else {
-                                gtk_list_store_insert_before (prefs->bookshelf_store,
+                                gtk_list_store_insert_before (priv->bookshelf_store,
                                                               &book_iter,
                                                               &next_book_iter);
                         }
@@ -572,13 +377,13 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
 
                 /* Add new item with indented title */
                 indented_title = g_strdup_printf ("     %s", dh_book_get_title (book));
-                gtk_list_store_set (prefs->bookshelf_store,
+                gtk_list_store_set (priv->bookshelf_store,
                                     &book_iter,
-                                    LTCOLUMN_ENABLED,      dh_book_get_enabled (book),
-                                    LTCOLUMN_TITLE,        indented_title,
-                                    LTCOLUMN_BOOK,         book,
-                                    LTCOLUMN_WEIGHT,       PANGO_WEIGHT_NORMAL,
-                                    LTCOLUMN_INCONSISTENT, FALSE,
+                                    COLUMN_ENABLED,      dh_book_get_enabled (book),
+                                    COLUMN_TITLE,        indented_title,
+                                    COLUMN_BOOK,         book,
+                                    COLUMN_WEIGHT,       PANGO_WEIGHT_NORMAL,
+                                    COLUMN_INCONSISTENT, FALSE,
                                     -1);
                 g_free (indented_title);
         } else {
@@ -586,134 +391,302 @@ preferences_bookshelf_add_book_to_store (DhBook   *book,
                 GtkTreeIter next_book_iter;
                 gboolean    next_book_iter_found;
 
-                preferences_bookshelf_find_book (book,
+                preferences_bookshelf_find_book (prefs,
+                                                 book,
                                                  NULL,
                                                  NULL,
                                                  NULL,
                                                  &next_book_iter,
                                                  &next_book_iter_found);
                 if (!next_book_iter_found) {
-                        gtk_list_store_append (prefs->bookshelf_store,
+                        gtk_list_store_append (priv->bookshelf_store,
                                                &book_iter);
                 } else {
-                        gtk_list_store_insert_before (prefs->bookshelf_store,
+                        gtk_list_store_insert_before (priv->bookshelf_store,
                                                       &book_iter,
                                                       &next_book_iter);
                 }
 
-                gtk_list_store_set (prefs->bookshelf_store,
+                gtk_list_store_set (priv->bookshelf_store,
                                     &book_iter,
-                                    LTCOLUMN_ENABLED,  dh_book_get_enabled (book),
-                                    LTCOLUMN_TITLE,    dh_book_get_title (book),
-                                    LTCOLUMN_BOOK,     book,
-                                    LTCOLUMN_WEIGHT,   PANGO_WEIGHT_NORMAL,
+                                    COLUMN_ENABLED,  dh_book_get_enabled (book),
+                                    COLUMN_TITLE,    dh_book_get_title (book),
+                                    COLUMN_BOOK,     book,
+                                    COLUMN_WEIGHT,   PANGO_WEIGHT_NORMAL,
                                     -1);
         }
 }
 
 static void
-preferences_bookshelf_populate_store (void)
+preferences_bookshelf_populate_store (DhPreferences *prefs)
 {
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
         GList *l;
         gboolean group_by_language;
 
-        group_by_language = dh_book_manager_get_group_by_language (prefs->book_manager);
+        group_by_language = dh_book_manager_get_group_by_language (priv->book_manager);
 
         /* This list already comes ordered, but we don't care */
-        for (l = dh_book_manager_get_books (prefs->book_manager);
+        for (l = dh_book_manager_get_books (priv->book_manager);
              l;
              l = g_list_next (l)) {
-                preferences_bookshelf_add_book_to_store (DH_BOOK (l->data),
+                preferences_bookshelf_add_book_to_store (prefs,
+                                                         DH_BOOK (l->data),
                                                          group_by_language);
         }
 }
 
 static void
-preferences_dialog_response (GtkDialog *dialog,
-                             gint       response_id,
-                             gpointer   user_data)
+preferences_bookshelf_group_by_language_cb (GObject       *object,
+                                            GParamSpec    *pspec,
+                                            DhPreferences *prefs)
 {
-        preferences_shutdown ();
+        preferences_bookshelf_clean_store (prefs);
+        preferences_bookshelf_populate_store (prefs);
 }
 
 static void
-preferences_bookshelf_clean_store (void)
+preferences_bookshelf_set_language_inconsistent (DhPreferences *prefs,
+                                                 const gchar *language)
 {
-        gtk_list_store_clear (prefs->bookshelf_store);
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
+        GtkTreeIter loop_iter;
+        GtkTreeIter language_iter;
+        gboolean    language_iter_found;
+        gboolean    one_book_enabled = FALSE;
+        gboolean    one_book_disabled = FALSE;
+
+        preferences_bookshelf_find_language_group (prefs,
+                                                   language,
+                                                   &language_iter,
+                                                   &language_iter_found,
+                                                   NULL,
+                                                   NULL);
+        if (!language_iter_found) {
+                return;
+        }
+
+        loop_iter = language_iter;
+        while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->bookshelf_store),
+                                         &loop_iter)) {
+                DhBook   *book;
+                gboolean  enabled;
+
+                gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
+                                    &loop_iter,
+                                    COLUMN_BOOK,       &book,
+                                    COLUMN_ENABLED,    &enabled,
+                                    -1);
+                if (!book) {
+                        /* Reached next language group */
+                        break;
+                }
+                g_object_unref (book);
+
+                if (enabled)
+                        one_book_enabled = TRUE;
+                else
+                        one_book_disabled = TRUE;
+
+                if (one_book_enabled == one_book_disabled)
+                        break;
+        }
+
+        /* If at least one book is enabled AND another book is disabled,
+         * we need to set inconsistent state */
+        if (one_book_enabled == one_book_disabled) {
+                gtk_list_store_set (priv->bookshelf_store, &language_iter,
+                                    COLUMN_INCONSISTENT, TRUE,
+                                    -1);
+                return;
+        }
+
+        gtk_list_store_set (priv->bookshelf_store, &language_iter,
+                            COLUMN_ENABLED, one_book_enabled,
+                            COLUMN_INCONSISTENT, FALSE,
+                            -1);
 }
 
-void
-dh_preferences_show_dialog (void)
+static void
+preferences_bookshelf_book_deleted_cb (DhBookManager *book_manager,
+                                       GObject       *book_object,
+                                       DhPreferences *prefs)
 {
-        gchar      *path;
-        GtkBuilder *builder;
-        gboolean    use_system_fonts;
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
+        DhBook      *book = DH_BOOK (book_object);
+        GtkTreeIter  exact_iter;
+        gboolean     exact_iter_found;
 
-        preferences_init ();
+        preferences_bookshelf_find_book (prefs,
+                                         book,
+                                         NULL,
+                                         &exact_iter,
+                                         &exact_iter_found,
+                                         NULL,
+                                         NULL);
+        if (exact_iter_found) {
+                gtk_list_store_remove (priv->bookshelf_store, &exact_iter);
+                preferences_bookshelf_set_language_inconsistent (prefs, dh_book_get_language (book));
+        }
+}
 
-        if (prefs->dialog != NULL) {
-                gtk_window_present (GTK_WINDOW (prefs->dialog));
-                return;
+static void
+preferences_bookshelf_book_created_cb (DhBookManager *book_manager,
+                                       GObject       *book_object,
+                                       DhPreferences *prefs)
+{
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
+
+        preferences_bookshelf_add_book_to_store (prefs,
+                                                 DH_BOOK (book_object),
+                                                 dh_book_manager_get_group_by_language (priv->book_manager));
+}
+
+static void
+preferences_bookshelf_tree_selection_toggled_cb (GtkCellRendererToggle *cell_renderer,
+                                                 gchar                 *path,
+                                                 DhPreferences         *prefs)
+{
+        DhPreferencesPrivate *priv = dh_preferences_get_instance_private (prefs);
+        GtkTreeIter iter;
+
+        if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (priv->bookshelf_store),
+                                                 &iter,
+                                                 path)) {
+                gpointer book = NULL;
+                gboolean enabled;
+
+                gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
+                                    &iter,
+                                    COLUMN_BOOK,       &book,
+                                    COLUMN_ENABLED,    &enabled,
+                                    -1);
+
+                if (book) {
+                        /* Update book conf */
+                        dh_book_set_enabled (book, !enabled);
+
+                        gtk_list_store_set (priv->bookshelf_store, &iter,
+                                            COLUMN_ENABLED, !enabled,
+                                            -1);
+                        /* Now we need to look for the language group of this item,
+                         * in order to set the inconsistent state if applies */
+                        if (dh_book_manager_get_group_by_language (priv->book_manager)) {
+                                preferences_bookshelf_set_language_inconsistent (prefs, dh_book_get_language 
(book));
+                        }
+
+                } else {
+                        GtkTreeIter loop_iter;
+
+                        /* We should only reach this if we are grouping by language */
+                        g_assert (dh_book_manager_get_group_by_language (priv->book_manager) == TRUE);
+
+                        /* Set new status in the language group item */
+                        gtk_list_store_set (priv->bookshelf_store, &iter,
+                                            COLUMN_ENABLED,      !enabled,
+                                            COLUMN_INCONSISTENT, FALSE,
+                                            -1);
+
+                        /* And set new status in all books of the same language */
+                        loop_iter = iter;
+                        while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->bookshelf_store),
+                                                         &loop_iter)) {
+                                gtk_tree_model_get (GTK_TREE_MODEL (priv->bookshelf_store),
+                                                    &loop_iter,
+                                                    COLUMN_BOOK, &book,
+                                                    -1);
+                                if (!book) {
+                                        /* Found next language group, finish */
+                                        return;
+                                }
+
+                                /* Update book conf */
+                                dh_book_set_enabled (book, !enabled);
+
+                                gtk_list_store_set (priv->bookshelf_store,
+                                                    &loop_iter,
+                                                    COLUMN_ENABLED, !enabled,
+                                                    -1);
+                        }
+                }
         }
+}
+
+static void
+dh_preferences_init (DhPreferences *prefs)
+{
+        DhPreferencesPrivate *priv;
+        GApplication *app;
+        GSettings *settings_fonts;
+        GSettings *settings_contents;
 
-        path = dh_util_build_data_filename ("devhelp", "ui",
-                                            "devhelp.builder",
-                                            NULL);
-        builder = dh_util_builder_get_file (
-                path,
-                "preferences_dialog",
-                NULL,
-                "preferences_dialog", &prefs->dialog,
-                "fonts_table", &prefs->fonts_table,
-                "system_fonts_button", &prefs->system_fonts_button,
-                "variable_font_button", &prefs->variable_font_button,
-                "fixed_font_button", &prefs->fixed_font_button,
-                "bookshelf_store", &prefs->bookshelf_store,
-                "bookshelf_group_by_language_button", &prefs->bookshelf_group_by_language_button,
-                NULL);
-        g_free (path);
+        priv = dh_preferences_get_instance_private (prefs);
+
+        gtk_widget_init_template (GTK_WIDGET (prefs));
+
+        app = g_application_get_default ();
+
+        priv->settings = dh_settings_get ();
+        priv->book_manager = g_object_ref (dh_app_peek_book_manager (DH_APP (app)));
+        priv->book_created_id = g_signal_connect (priv->book_manager,
+                                                  "book-created",
+                                                  G_CALLBACK (preferences_bookshelf_book_created_cb),
+                                                  prefs);
+        priv->book_deleted_id = g_signal_connect (priv->book_manager,
+                                                  "book-deleted",
+                                                  G_CALLBACK (preferences_bookshelf_book_deleted_cb),
+                                                  prefs);
+        priv->group_by_language_id = g_signal_connect (priv->book_manager,
+                                                       "notify::group-by-language",
+                                                       G_CALLBACK 
(preferences_bookshelf_group_by_language_cb),
+                                                       prefs);
 
         /* setup GSettings bindings */
-        GSettings *settings_fonts = dh_settings_peek_fonts_settings (prefs->settings);
-        GSettings *settings_contents = dh_settings_peek_contents_settings (prefs->settings);
+        settings_fonts = dh_settings_peek_fonts_settings (priv->settings);
+        settings_contents = dh_settings_peek_contents_settings (priv->settings);
         g_settings_bind (settings_fonts, "use-system-fonts",
-                         prefs->system_fonts_button,
+                         priv->system_fonts_button,
                          "active", G_SETTINGS_BIND_DEFAULT);
+        g_settings_bind (settings_fonts, "use-system-fonts",
+                         priv->fonts_grid,
+                         "sensitive", G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);
         g_settings_bind (settings_fonts, "fixed-font",
-                         prefs->fixed_font_button,
+                         priv->fixed_font_button,
                          "font-name", G_SETTINGS_BIND_DEFAULT);
         g_settings_bind (settings_fonts, "variable-font",
-                         prefs->variable_font_button,
+                         priv->variable_font_button,
                          "font-name", G_SETTINGS_BIND_DEFAULT);
 
         g_settings_bind (settings_contents,
                          "group-books-by-language",
-                         prefs->bookshelf_group_by_language_button,
+                         priv->bookshelf_group_by_language_button,
                          "active", G_SETTINGS_BIND_DEFAULT);
 
-        dh_util_builder_connect (
-                builder,
-                prefs,
-                "system_fonts_button", "toggled", preferences_fonts_system_fonts_toggled_cb,
-                "bookshelf_enabled_toggle", "toggled", preferences_bookshelf_tree_selection_toggled_cb,
-                NULL);
-
-        /* set initial sensitive */
-        use_system_fonts = g_settings_get_boolean (settings_fonts, "use-system-fonts");
-        gtk_widget_set_sensitive (prefs->fonts_table, !use_system_fonts);
+        g_signal_connect (priv->bookshelf_enabled_toggle,
+                          "toggled",
+                          G_CALLBACK (preferences_bookshelf_tree_selection_toggled_cb),
+                          prefs);
 
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->bookshelf_group_by_language_button),
-                                      dh_book_manager_get_group_by_language (prefs->book_manager));
-        preferences_bookshelf_populate_store ();
+        preferences_bookshelf_populate_store (prefs);
+}
 
-        g_object_unref (builder);
+void
+dh_preferences_show_dialog (GtkWindow *parent)
+{
+        g_return_if_fail (GTK_IS_WINDOW (parent));
+
+        if (prefs_dialog == NULL) {
+                prefs_dialog = GTK_WIDGET (g_object_new (DH_TYPE_PREFERENCES, NULL));
+                g_signal_connect (prefs_dialog,
+                                  "destroy",
+                                  G_CALLBACK (gtk_widget_destroyed),
+                                  &prefs_dialog);
+        }
 
-        /* Connect to the response signal to get notified when the dialog is
-         * closed or deleted */
-        g_signal_connect (prefs->dialog,
-                          "response",
-                          G_CALLBACK (preferences_dialog_response),
-                          NULL);
+        if (parent != gtk_window_get_transient_for (GTK_WINDOW (prefs_dialog))) {
+                gtk_window_set_transient_for (GTK_WINDOW (prefs_dialog),
+                                              parent);
+        }
 
-        gtk_widget_show_all (prefs->dialog);
+        gtk_window_present (GTK_WINDOW (prefs_dialog));
 }
diff --git a/src/dh-preferences.h b/src/dh-preferences.h
index c7f6670..ba95852 100644
--- a/src/dh-preferences.h
+++ b/src/dh-preferences.h
@@ -26,7 +26,30 @@
 
 G_BEGIN_DECLS
 
-void dh_preferences_show_dialog (void);
+#define DH_TYPE_PREFERENCES                (dh_preferences_get_type ())
+#define DH_PREFERENCES(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), DH_TYPE_PREFERENCES, 
DhPreferences))
+#define DH_PREFERENCES_CONST(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), DH_TYPE_PREFERENCES, 
DhPreferences const))
+#define DH_PREFERENCES_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), DH_TYPE_PREFERENCES, 
DhPreferencesClass))
+#define DH_IS_PREFERENCES(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DH_TYPE_PREFERENCES))
+#define DH_IS_PREFERENCES_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), DH_TYPE_PREFERENCES))
+#define DH_PREFERENCES_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), DH_TYPE_PREFERENCES, 
DhPreferencesClass))
+
+typedef struct _DhPreferences             DhPreferences;
+typedef struct _DhPreferencesClass        DhPreferencesClass;
+
+struct _DhPreferences
+{
+        GtkDialog parent;
+};
+
+struct _DhPreferencesClass
+{
+        GtkDialogClass parent_class;
+};
+
+GType dh_preferences_get_type (void) G_GNUC_CONST;
+
+void dh_preferences_show_dialog (GtkWindow *parent);
 
 G_END_DECLS
 
diff --git a/src/devhelp.ui b/src/dh-preferences.ui
similarity index 61%
rename from src/devhelp.ui
rename to src/dh-preferences.ui
index e936c03..90f70c1 100644
--- a/src/devhelp.ui
+++ b/src/dh-preferences.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-
+<!-- Generated with glade 3.15.2 on Mon Sep 23 00:02:21 2013 -->
 <!--
   Copyright (C) 2010 Imendio AB
   Copyright (C) 2012 Aleksander Morgado <aleksander gnu org>
@@ -19,37 +19,8 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301
   USA
 -->
-
 <interface>
-  <requires lib="gtk+" version="3.0"/>
-
-  <menu id="app-menu">
-    <section>
-      <item>
-        <attribute name="label" translatable="yes">New _Window</attribute>
-        <attribute name="action">app.new-window</attribute>
-        <attribute name="accel">&lt;Primary&gt;n</attribute>
-      </item>
-    </section>
-    <section>
-      <item>
-        <attribute name="label" translatable="yes">_Preferences</attribute>
-        <attribute name="action">app.preferences</attribute>
-      </item>
-    </section>
-    <section>
-      <item>
-        <attribute name="label" translatable="yes">_About Devhelp</attribute>
-        <attribute name="action">app.about</attribute>
-      </item>
-      <item>
-        <attribute name="label" translatable="yes">_Quit</attribute>
-        <attribute name="action">app.quit</attribute>
-        <attribute name="accel">&lt;Primary&gt;q</attribute>
-      </item>
-    </section>
-  </menu>
-
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkListStore" id="bookshelf_store">
     <columns>
       <!-- column-name enabled -->
@@ -64,20 +35,51 @@
       <column type="gboolean"/>
     </columns>
   </object>
-
-  <object class="GtkDialog" id="preferences_dialog">
+  <template class="DhPreferences" parent="GtkDialog">
+    <property name="can_focus">False</property>
     <property name="border_width">5</property>
     <property name="title" translatable="yes">Preferences</property>
     <property name="default_width">500</property>
     <property name="default_height">400</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+      <object class="GtkBox" id="dialog-vbox1">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="preferences_close_button">
+                <property name="label">gtk-close</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
         <child>
           <object class="GtkAlignment" id="alignment1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="right_padding">6</property>
             <child>
               <object class="GtkNotebook" id="notebook1">
@@ -86,96 +88,96 @@
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
                 <child>
-                  <object class="GtkVBox" id="outer_vbox1">
+                  <object class="GtkAlignment" id="alignment3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="top_padding">8</property>
+                    <property name="bottom_padding">8</property>
+                    <property name="left_padding">8</property>
+                    <property name="right_padding">8</property>
                     <child>
-                      <object class="GtkAlignment" id="alignment3">
+                      <object class="GtkBox" id="vbox1">
                         <property name="visible">True</property>
-                        <property name="top_padding">8</property>
-                        <property name="bottom_padding">8</property>
-                        <property name="left_padding">8</property>
-                        <property name="right_padding">8</property>
+                        <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
                         <child>
-                          <object class="GtkVBox" id="vbox1">
+                          <object class="GtkCheckButton" id="bookshelf_group_by_language_button">
+                            <property name="label" translatable="yes">_Group by language</property>
                             <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="bookshelf_group_by_language_button">
-                                <property name="label" translatable="yes">_Group by language</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="draw_indicator">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="xalign">0</property>
+                            <property name="draw_indicator">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkScrolledWindow" id="scrolledwindow1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="shadow_type">in</property>
                             <child>
-                              <object class="GtkScrolledWindow" id="scrolledwindow1">
+                              <object class="GtkTreeView" id="bookshelf_treeview">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="hscrollbar_policy">automatic</property>
-                                <property name="vscrollbar_policy">automatic</property>
-                                <property name="shadow-type">in</property>
+                                <property name="model">bookshelf_store</property>
+                                <property name="headers_clickable">False</property>
+                                <property name="search_column">0</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="treeview-selection"/>
+                                </child>
                                 <child>
-                                  <object class="GtkTreeView" id="bookshelf_treeview">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="model">bookshelf_store</property>
-                                    <property name="headers_clickable">False</property>
-                                    <property name="search_column">0</property>
+                                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                                    <property name="min_width">60</property>
+                                    <property name="title" translatable="yes">Enabled</property>
+                                    <property name="expand">True</property>
                                     <child>
-                                      <object class="GtkTreeViewColumn" id="treeviewcolumn1">
-                                        <property name="min_width">60</property>
-                                        <property name="title" translatable="yes">Enabled</property>
-                                        <property name="expand">True</property>
-                                        <child>
-                                          <object class="GtkCellRendererToggle" 
id="bookshelf_enabled_toggle">
-                                            <property name="width">60</property>
-                                          </object>
-                                          <attributes>
-                                            <attribute name="active">0</attribute>
-                                            <attribute name="inconsistent">4</attribute>
-                                          </attributes>
-                                        </child>
+                                      <object class="GtkCellRendererToggle" id="bookshelf_enabled_toggle">
+                                        <property name="width">60</property>
                                       </object>
+                                      <attributes>
+                                        <attribute name="active">0</attribute>
+                                        <attribute name="inconsistent">4</attribute>
+                                      </attributes>
                                     </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                                    <property name="title" translatable="yes">Title</property>
+                                    <property name="expand">True</property>
                                     <child>
-                                      <object class="GtkTreeViewColumn" id="treeviewcolumn2">
-                                        <property name="title" translatable="yes">Title</property>
-                                        <property name="expand">True</property>
-                                        <child>
-                                          <object class="GtkCellRendererText" id="bookshelf_title_text"/>
-                                          <attributes>
-                                            <attribute name="text">1</attribute>
-                                            <attribute name="weight">3</attribute>
-                                          </attributes>
-                                        </child>
-                                      </object>
+                                      <object class="GtkCellRendererText" id="bookshelf_title_text"/>
+                                      <attributes>
+                                        <attribute name="text">1</attribute>
+                                        <attribute name="weight">3</attribute>
+                                      </attributes>
                                     </child>
                                   </object>
                                 </child>
                               </object>
-                              <packing>
-                                <property name="position">2</property>
-                              </packing>
                             </child>
                           </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
                         </child>
                       </object>
-                      <packing>
-                        <property name="position">0</property>
-                      </packing>
                     </child>
                   </object>
                 </child>
                 <child type="tab">
                   <object class="GtkLabel" id="label_bookshelf">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="label" translatable="yes">Book Shelf</property>
                   </object>
                   <packing>
@@ -183,18 +185,22 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="outer_vbox2">
+                  <object class="GtkBox" id="outer_vbox2">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <child>
                       <object class="GtkAlignment" id="alignment2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="top_padding">8</property>
                         <property name="bottom_padding">8</property>
                         <property name="left_padding">8</property>
                         <property name="right_padding">8</property>
                         <child>
-                          <object class="GtkVBox" id="vbox4">
+                          <object class="GtkBox" id="vbox4">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
                             <property name="spacing">6</property>
                             <child>
                               <object class="GtkCheckButton" id="system_fonts_button">
@@ -203,6 +209,7 @@
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_underline">True</property>
+                                <property name="xalign">0.5</property>
                                 <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -213,39 +220,41 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkTable" id="fonts_table">
+                              <object class="GtkGrid" id="fonts_grid">
                                 <property name="visible">True</property>
-                                <property name="sensitive">False</property>
-                                <property name="n_rows">2</property>
-                                <property name="n_columns">2</property>
-                                <property name="column_spacing">6</property>
+                                <property name="can_focus">False</property>
                                 <property name="row_spacing">6</property>
+                                <property name="column_spacing">6</property>
                                 <child>
                                   <object class="GtkLabel" id="label4">
                                     <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
                                     <property name="xalign">0</property>
                                     <property name="label" translatable="yes">_Variable width: </property>
                                     <property name="use_underline">True</property>
                                     <property name="mnemonic_widget">variable_font_button</property>
                                   </object>
                                   <packing>
-                                    <property name="x_options"></property>
-                                    <property name="y_options"></property>
+                                    <property name="left_attach">0</property>
+                                    <property name="top_attach">0</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
                                   </packing>
                                 </child>
                                 <child>
                                   <object class="GtkLabel" id="label5">
                                     <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
                                     <property name="xalign">0</property>
                                     <property name="label" translatable="yes">_Fixed width:</property>
                                     <property name="use_underline">True</property>
                                     <property name="mnemonic_widget">fixed_font_button</property>
                                   </object>
                                   <packing>
+                                    <property name="left_attach">0</property>
                                     <property name="top_attach">1</property>
-                                    <property name="bottom_attach">2</property>
-                                    <property name="x_options">GTK_FILL</property>
-                                    <property name="y_options"></property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -253,13 +262,15 @@
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="receives_default">True</property>
+                                    <property name="font">Sans 12</property>
+                                    <property name="preview_text"/>
                                     <property name="use_font">True</property>
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                    <property name="x_options">GTK_FILL</property>
-                                    <property name="y_options">GTK_FILL</property>
+                                    <property name="top_attach">0</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -267,22 +278,21 @@
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="receives_default">True</property>
-                                    <property name="font_name">Monospace 12</property>
+                                    <property name="font">Sans 12</property>
+                                    <property name="preview_text"/>
                                     <property name="use_font">True</property>
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
                                     <property name="top_attach">1</property>
-                                    <property name="bottom_attach">2</property>
-                                    <property name="x_options"></property>
-                                    <property name="y_options"></property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
                                   </packing>
                                 </child>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
-                                <property name="fill">False</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
@@ -290,6 +300,8 @@
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
@@ -301,6 +313,7 @@
                 <child type="tab">
                   <object class="GtkLabel" id="label_fonts">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="label" translatable="yes">Fonts</property>
                   </object>
                   <packing>
@@ -318,33 +331,9 @@
             </child>
           </object>
           <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="preferences_close_button">
-                <property name="label">gtk-close</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
             <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
@@ -352,6 +341,5 @@
     <action-widgets>
       <action-widget response="-7">preferences_close_button</action-widget>
     </action-widgets>
-  </object>
-
+  </template>
 </interface>
diff --git a/src/dh.gresource.xml b/src/dh.gresource.xml
index 71674ab..b2360eb 100644
--- a/src/dh.gresource.xml
+++ b/src/dh.gresource.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/devhelp">
-    <file>devhelp.ui</file>
     <file preprocess="xml-stripblanks">devhelp-menu.ui</file>
     <file preprocess="xml-stripblanks">dh-assistant.ui</file>
     <file preprocess="xml-stripblanks">dh-window.ui</file>
+    <file preprocess="xml-stripblanks">dh-preferences.ui</file>
   </gresource>
 </gresources>


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