Blob Blame History Raw
From e9f92661d413ff90e43f34735585fe50f5f06591 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 00:00:51 -0800
Subject: [PATCH 01/14] Pull upstream fixes for gtk and gtksourceview changes

* fix errors in xed-metadata-manager
* upstream changes for file loading and saving
* modernize some code in xed-document

Closes https://github.com/linuxmint/xed/issues/146
---
 configure.ac                        |   4 +-
 xed/Makefile.am                     |  11 +-
 xed/xed-close-confirmation-dialog.c |   5 +-
 xed/xed-commands-file.c             | 584 ++++++++++++++---------
 xed/xed-commands.h                  |   2 +
 xed/xed-document-private.h          |  21 +
 xed/xed-document.c                  | 895 +++++++++++++++++++-----------------
 xed/xed-document.h                  |  41 +-
 xed/xed-metadata-manager.c          | 614 +++++++++++++------------
 xed/xed-metadata-manager.h          |   2 +-
 xed/xed-tab.c                       |  26 +-
 xed/xed-window.c                    |   2 +
 12 files changed, 1199 insertions(+), 1008 deletions(-)
 create mode 100644 xed/xed-document-private.h

diff --git a/configure.ac b/configure.ac
index fe8d570..90d461b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -149,8 +149,8 @@ PKG_CHECK_MODULES(XED, [
 	$GMODULE_ADD
 	gthread-2.0 >= 2.13.0
 	gio-2.0 >= 2.40.0
-	gtk+-3.0 >= 3.18.0
-	gtksourceview-3.0 >= 3.18.0
+	gtk+-3.0 >= 3.19.3
+	gtksourceview-3.0 >= 3.19.0
 	libpeas-1.0 >= 1.12.0
 	libpeas-gtk-1.0 >= 1.12.0
 ])
diff --git a/xed/Makefile.am b/xed/Makefile.am
index bbaec9c..763df73 100644
--- a/xed/Makefile.am
+++ b/xed/Makefile.am
@@ -40,10 +40,12 @@ NOINST_H_FILES =						\
 	xed-close-button.h					\
 	xed-close-confirmation-dialog.h 	\
 	xed-dirs.h							\
+	xed-document-private.h 				\
 	xed-documents-panel.h				\
 	xed-encodings-dialog.h 				\
 	xed-history-entry.h					\
 	xed-io-error-info-bar.h				\
+	xed-metadata-manager.h 				\
 	xed-paned.h 						\
 	xed-plugins-engine.h				\
 	xed-preferences-dialog.h 			\
@@ -80,10 +82,6 @@ INST_H_FILES =							\
 	xed-window.h 						\
 	xed-window-activatable.h
 
-if !ENABLE_GVFS_METADATA
-NOINST_H_FILES += xed-metadata-manager.h
-endif
-
 headerdir = $(prefix)/include/xed
 
 header_DATA = 							\
@@ -119,6 +117,7 @@ libxed_c_files = 						\
 	xed-message-bus.c					\
 	xed-message-type.c					\
 	xed-message.c						\
+	xed-metadata-manager.c 				\
 	xed-notebook.c						\
 	xed-paned.c 						\
 	xed-panel.c							\
@@ -146,10 +145,6 @@ libxed_la_SOURCES = 					\
 	$(NOINST_H_FILES)					\
 	$(INST_H_FILES)
 
-if !ENABLE_GVFS_METADATA
-libxed_la_SOURCES += xed-metadata-manager.c
-endif
-
 xed-enum-types.h: xed-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
 	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-enum-types.h.template $(INST_H_FILES)) > $@
 
diff --git a/xed/xed-close-confirmation-dialog.c b/xed/xed-close-confirmation-dialog.c
index e667ad5..b72f16e 100755
--- a/xed/xed-close-confirmation-dialog.c
+++ b/xed/xed-close-confirmation-dialog.c
@@ -32,10 +32,13 @@
 #include <config.h>
 #endif
 
+#include "xed-close-confirmation-dialog.h"
+
 #include <glib/gi18n.h>
 
-#include "xed-close-confirmation-dialog.h"
 #include <xed/xed-app.h>
+#include <xed/xed-document.h>
+#include <xed/xed-document-private.h>
 #include <xed/xed-utils.h>
 #include <xed/xed-window.h>
 
diff --git a/xed/xed-commands-file.c b/xed/xed-commands-file.c
index 2323cab..098dcb4 100644
--- a/xed/xed-commands-file.c
+++ b/xed/xed-commands-file.c
@@ -38,31 +38,27 @@
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 
+#include "xed-debug.h"
+#include "xed-document.h"
+#include "xed-document-private.h"
 #include "xed-commands.h"
 #include "xed-window.h"
 #include "xed-window-private.h"
 #include "xed-statusbar.h"
-#include "xed-debug.h"
 #include "xed-utils.h"
 #include "xed-file-chooser-dialog.h"
 #include "xed-close-confirmation-dialog.h"
 
 /* Defined constants */
 #define XED_OPEN_DIALOG_KEY         "xed-open-dialog-key"
-#define XED_TAB_TO_SAVE_AS          "xed-tab-to-save-as"
-#define XED_LIST_OF_TABS_TO_SAVE_AS   "xed-list-of-tabs-to-save-as"
 #define XED_IS_CLOSING_ALL            "xed-is-closing-all"
 #define XED_IS_QUITTING             "xed-is-quitting"
-#define XED_IS_CLOSING_TAB      "xed-is-closing-tab"
 #define XED_IS_QUITTING_ALL     "xed-is-quitting-all"
 
 static void tab_state_changed_while_saving (XedTab    *tab,
                                             GParamSpec  *pspec,
                                             XedWindow *window);
 
-static void save_as_tab (XedTab    *tab,
-                         XedWindow *window);
-
 void
 _xed_cmd_file_new (GtkAction   *action,
                    XedWindow *window)
@@ -521,110 +517,73 @@ replace_read_only_file (GtkWindow *parent,
 }
 
 static void
-save_finish_cb (XedTab       *tab,
-                GAsyncResult *result,
-                gpointer      user_data)
+tab_save_as_ready_cb (XedTab     *tab,
+                      GAsyncResult *result,
+                      GTask        *task)
 {
-    _xed_tab_save_finish (tab, result);
+    gboolean success = _xed_tab_save_finish (tab, result);
+    g_task_return_boolean (task, success);
+    g_object_unref (task);
 }
 
 static void
 save_dialog_response_cb (XedFileChooserDialog *dialog,
                          gint                  response_id,
-                         XedWindow            *window)
+                         GTask                *task)
 {
     XedTab *tab;
-    gpointer data;
-    GSList *tabs_to_save_as;
+    XedWindow *window;
+    XedDocument *doc;
+    GtkSourceFile *file;
+    GFile *location;
+    gchar *parse_name;
+    GtkSourceNewlineType newline_type;
+    const GtkSourceEncoding *encoding;
 
     xed_debug (DEBUG_COMMANDS);
 
-    tab = XED_TAB (g_object_get_data (G_OBJECT (dialog), XED_TAB_TO_SAVE_AS));
+    tab = g_task_get_source_object (task);
+    window = g_task_get_task_data (task);
 
     if (response_id != GTK_RESPONSE_OK)
     {
         gtk_widget_destroy (GTK_WIDGET (dialog));
 
-        goto save_next_tab;
-    }
-
-    if (tab != NULL)
-    {
-        GFile *location;
-        XedDocument *doc;
-        gchar *parse_name;
-        GtkSourceNewlineType newline_type;
-        const GtkSourceEncoding *encoding;
-
-        doc = xed_tab_get_document (tab);
-
-        location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
-        g_return_if_fail (location != NULL);
-
-        encoding = xed_file_chooser_dialog_get_encoding (dialog);
-        newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
-
-        gtk_widget_destroy (GTK_WIDGET (dialog));
-
-        doc = xed_tab_get_document (tab);
-        g_return_if_fail (XED_IS_DOCUMENT (doc));
-
-        parse_name = g_file_get_parse_name (location);
-
-        xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
-                                     window->priv->generic_message_cid,
-                                     _("Saving file '%s'\342\200\246"),
-                                     parse_name);
-
-        g_free (parse_name);
-
-        /* let's remember the dir we navigated too,
-         * even if the saving fails... */
-         _xed_window_set_default_location (window, location);
-
-        _xed_tab_save_as_async (tab,
-                                location,
-                                encoding,
-                                newline_type,
-                                NULL,
-                                (GAsyncReadyCallback) save_finish_cb,
-                                NULL);
-
-        g_object_unref (location);
+        g_task_return_boolean (task, FALSE);
+        g_object_unref (task);
+        return;
     }
 
-save_next_tab:
+    doc = xed_tab_get_document (tab);
+    location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+    g_return_if_fail (location != NULL);
 
-    data = g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS);
-    if (data == NULL)
-    {
-        return;
-    }
+    encoding = xed_file_chooser_dialog_get_encoding (dialog);
+    newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
 
-    /* Save As the next tab of the list (we are Saving All files) */
-    tabs_to_save_as = (GSList *)data;
-    g_return_if_fail (tab == XED_TAB (tabs_to_save_as->data));
+    gtk_widget_destroy (GTK_WIDGET (dialog));
 
-    /* Remove the first item of the list */
-    tabs_to_save_as = g_slist_delete_link (tabs_to_save_as, tabs_to_save_as);
+    parse_name = g_file_get_parse_name (location);
 
-    g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
+    xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
+                                 window->priv->generic_message_cid,
+                                 _("Saving file '%s'\342\200\246"),
+                                 parse_name);
 
-    if (tabs_to_save_as != NULL)
-    {
-        tab = XED_TAB (tabs_to_save_as->data);
+    g_free (parse_name);
 
-        if (GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (tab), XED_IS_CLOSING_TAB)) == TRUE)
-        {
-            g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL);
+        /* let's remember the dir we navigated too, even if the saving fails... */
+    _xed_window_set_default_location (window, location);
 
-            /* Trace tab state changes */
-            g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
-        }
+    _xed_tab_save_as_async (tab,
+                            location,
+                            encoding,
+                            newline_type,
+                            g_task_get_cancellable (task),
+                            (GAsyncReadyCallback) tab_save_as_ready_cb,
+                            task);
 
-        xed_window_set_active_tab (window, tab);
-        save_as_tab (tab, window);
-    }
+    g_object_unref (location);
 }
 
 static GtkFileChooserConfirmation
@@ -663,16 +622,20 @@ confirm_overwrite_callback (GtkFileChooser *dialog,
     return res;
 }
 
+/* Call save_as_tab_finish() in @callback. */
 static void
-save_as_tab (XedTab    *tab,
-             XedWindow *window)
+save_as_tab_async (XedTab              *tab,
+                   XedWindow           *window,
+                   GCancellable        *cancellable,
+                   GAsyncReadyCallback  callback,
+                   gpointer             user_data)
 {
+    GTask *task;
     GtkWidget *save_dialog;
     GtkWindowGroup *wg;
     XedDocument *doc;
     GtkSourceFile *file;
     GFile *location;
-    gboolean uri_set = FALSE;
     const GtkSourceEncoding *encoding;
     GtkSourceNewlineType newline_type;
 
@@ -681,6 +644,9 @@ save_as_tab (XedTab    *tab,
 
     xed_debug (DEBUG_COMMANDS);
 
+    task = g_task_new (tab, cancellable, callback, user_data);
+    g_task_set_task_data (task, g_object_ref (window), g_object_unref);
+
     save_dialog = xed_file_chooser_dialog_new (_("Save As\342\200\246"),
                                                GTK_WINDOW (window),
                                                GTK_FILE_CHOOSER_ACTION_SAVE,
@@ -706,11 +672,11 @@ save_as_tab (XedTab    *tab,
 
     if (location != NULL)
     {
-        uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
+        gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
     }
 
 
-    if (!uri_set)
+    else
     {
         GFile *default_path;
         gchar *docname;
@@ -734,7 +700,7 @@ save_as_tab (XedTab    *tab,
         g_free (docname);
     }
 
-    /* Set suggested encoding */
+    /* Set suggested encoding and newline type */
     encoding = gtk_source_file_get_encoding (file);
 
     if (encoding == NULL)
@@ -748,39 +714,94 @@ save_as_tab (XedTab    *tab,
 
     xed_file_chooser_dialog_set_newline_type (XED_FILE_CHOOSER_DIALOG (save_dialog), newline_type);
 
-    g_object_set_data (G_OBJECT (save_dialog), XED_TAB_TO_SAVE_AS, tab);
-
-    g_signal_connect (save_dialog, "response", G_CALLBACK (save_dialog_response_cb), window);
+    g_signal_connect (save_dialog, "response", G_CALLBACK (save_dialog_response_cb), task);
 
     gtk_widget_show (save_dialog);
 }
 
+static gboolean
+save_as_tab_finish (XedTab       *tab,
+                    GAsyncResult *result)
+{
+   g_return_val_if_fail (g_task_is_valid (result, tab), FALSE);
+
+   return g_task_propagate_boolean (G_TASK (result), NULL);
+}
+
 static void
-save_tab (XedTab    *tab,
-          XedWindow *window)
+save_as_tab_ready_cb (XedTab       *tab,
+                      GAsyncResult *result,
+                      GTask        *task)
 {
-    XedDocument *doc;
+    gboolean success = save_as_tab_finish (tab, result);
+
+    g_task_return_boolean (task, success);
+    g_object_unref (task);
+}
+
+static void
+tab_save_ready_cb (XedTab       *tab,
+                   GAsyncResult *result,
+                   GTask        *task)
+{
+    gboolean success = _xed_tab_save_finish (tab, result);
+
+    g_task_return_boolean (task, success);
+    g_object_unref (task);
+}
+
+/**
+ * xed_commands_save_document_async:
+ * @document: the #XedDocument to save.
+ * @window: a #XedWindow.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the operation
+ *   is finished.
+ * @user_data: (closure): the data to pass to the @callback function.
+ *
+ * Asynchronously save the @document. @document must belong to @window. The
+ * source object of the async task is @document (which will be the first
+ * parameter of the #GAsyncReadyCallback).
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * xed_commands_save_document_finish() to get the result of the operation.
+ */
+void
+xed_commands_save_document_async (XedDocument         *document,
+                                  XedWindow           *window,
+                                  GCancellable        *cancellable,
+                                  GAsyncReadyCallback  callback,
+                                  gpointer             user_data)
+{
+    GTask *task;
+    XedTab *tab;
     gchar *uri_for_display;
 
     xed_debug (DEBUG_COMMANDS);
 
-    g_return_if_fail (XED_IS_TAB (tab));
+    g_return_if_fail (XED_IS_DOCUMENT (document));
     g_return_if_fail (XED_IS_WINDOW (window));
+    g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
 
-    doc = xed_tab_get_document (tab);
-    g_return_if_fail (XED_IS_DOCUMENT (doc));
+    task = g_task_new (document, cancellable, callback, user_data);
+
+    tab = xed_tab_get_from_document (document);
 
-    if (xed_document_is_untitled (doc) ||
-        xed_document_get_readonly (doc))
+    if (xed_document_is_untitled (document) ||
+        xed_document_get_readonly (document))
     {
         xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
 
-        save_as_tab (tab, window);
+        save_as_tab_async (tab,
+                           window,
+                           cancellable,
+                           (GAsyncReadyCallback) save_as_tab_ready_cb,
+                           task);
 
         return;
     }
 
-    uri_for_display = xed_document_get_uri_for_display (doc);
+    uri_for_display = xed_document_get_uri_for_display (document);
     xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
                                  window->priv->generic_message_cid,
                                  _("Saving file '%s'\342\200\246"),
@@ -789,9 +810,53 @@ save_tab (XedTab    *tab,
     g_free (uri_for_display);
 
     _xed_tab_save_async (tab,
-                         NULL,
-                         (GAsyncReadyCallback) save_finish_cb,
-                         NULL);
+                         cancellable,
+                         (GAsyncReadyCallback) tab_save_ready_cb,
+                         task);
+}
+
+/**
+ * xed_commands_save_document_finish:
+ * @document: a #XedDocument.
+ * @result: a #GAsyncResult.
+ *
+ * Finishes an asynchronous document saving operation started with
+ * xed_commands_save_document_async().
+ *
+ * Note that there is no error parameter because the errors are already handled
+ * by xed.
+ *
+ * Returns: %TRUE if the document has been correctly saved, %FALSE otherwise.
+ */
+gboolean
+xed_commands_save_document_finish (XedDocument  *document,
+                                   GAsyncResult *result)
+{
+    g_return_val_if_fail (g_task_is_valid (result, document), FALSE);
+
+    return g_task_propagate_boolean (G_TASK (result), NULL);
+}
+
+static void
+save_tab_ready_cb (XedDocument  *doc,
+                   GAsyncResult *result,
+                   gpointer      user_data)
+{
+    xed_commands_save_document_finish (doc, result);
+}
+
+/* Save tab asynchronously, but without results. */
+static void
+save_tab (XedTab    *tab,
+          XedWindow *window)
+{
+    XedDocument *doc = xed_tab_get_document (tab);
+
+    xed_commands_save_document_async (doc,
+                                      window,
+                                      NULL,
+                                      (GAsyncReadyCallback) save_tab_ready_cb,
+                                      NULL);
 }
 
 void
@@ -803,12 +868,18 @@ _xed_cmd_file_save (GtkAction *action,
     xed_debug (DEBUG_COMMANDS);
 
     tab = xed_window_get_active_tab (window);
-    if (tab == NULL)
+    if (tab != NULL)
     {
-        return;
+        save_tab (tab, window);
     }
+}
 
-    save_tab (tab, window);
+static void
+_xed_cmd_file_save_as_cb (XedTab     *tab,
+                          GAsyncResult *result,
+                          gpointer      user_data)
+{
+    save_as_tab_finish (tab, result);
 }
 
 void
@@ -820,12 +891,149 @@ _xed_cmd_file_save_as (GtkAction *action,
     xed_debug (DEBUG_COMMANDS);
 
     tab = xed_window_get_active_tab (window);
-    if (tab == NULL)
+    if (tab != NULL)
+    {
+        save_as_tab_async (tab,
+                           window,
+                           NULL,
+                           (GAsyncReadyCallback) _xed_cmd_file_save_as_cb,
+                           NULL);
+    }
+}
+
+static void
+quit_if_needed (XedWindow *window)
+{
+    gboolean is_quitting;
+    gboolean is_quitting_all;
+
+    is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING));
+
+    is_quitting_all = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING_ALL));
+
+    if (is_quitting)
+    {
+       gtk_widget_destroy (GTK_WIDGET (window));
+    }
+
+    if (is_quitting_all)
+    {
+        GtkApplication *app;
+
+        app = GTK_APPLICATION (g_application_get_default ());
+
+        if (gtk_application_get_windows (app) == NULL)
+        {
+            g_application_quit (G_APPLICATION (app));
+        }
+    }
+}
+
+static gboolean
+really_close_tab (XedTab *tab)
+{
+    GtkWidget *toplevel;
+    XedWindow *window;
+
+    xed_debug (DEBUG_COMMANDS);
+
+    g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, FALSE);
+
+    toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
+    g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE);
+
+    window = XED_WINDOW (toplevel);
+
+    xed_window_close_tab (window, tab);
+
+    if (xed_window_get_active_tab (window) == NULL)
+    {
+        quit_if_needed (window);
+    }
+
+    return FALSE;
+}
+
+static void
+close_tab (XedTab *tab)
+{
+    XedDocument *doc;
+
+    doc = xed_tab_get_document (tab);
+    g_return_if_fail (doc != NULL);
+
+    /* If the user has modified again the document, do not close the tab. */
+    if (_xed_document_needs_saving (doc))
     {
         return;
     }
 
-    save_as_tab (tab, window);
+    /* Close the document only if it has been succesfully saved.
+     * Tab state is set to CLOSING (it is a state without exiting
+     * transitions) and the tab is closed in an idle handler.
+     */
+    _xed_tab_mark_for_closing (tab);
+
+    g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+                     (GSourceFunc) really_close_tab,
+                     tab,
+                     NULL);
+}
+
+typedef struct _SaveAsData SaveAsData;
+
+struct _SaveAsData
+{
+    /* Reffed */
+    XedWindow *window;
+
+    /* List of reffed GeditTab's */
+    GSList *tabs_to_save_as;
+
+    guint close_tabs : 1;
+};
+
+static void save_as_documents_list (SaveAsData *data);
+
+static void
+save_as_documents_list_cb (XedTab       *tab,
+                           GAsyncResult *result,
+                           SaveAsData   *data)
+{
+    gboolean saved = save_as_tab_finish (tab, result);
+
+    if (saved && data->close_tabs)
+    {
+        close_tab (tab);
+    }
+
+    g_return_if_fail (tab == XED_TAB (data->tabs_to_save_as->data));
+    g_object_unref (data->tabs_to_save_as->data);
+    data->tabs_to_save_as = g_slist_delete_link (data->tabs_to_save_as, data->tabs_to_save_as);
+
+    if (data->tabs_to_save_as != NULL)
+    {
+        save_as_documents_list (data);
+    }
+    else
+    {
+       g_object_unref (data->window);
+       g_slice_free (SaveAsData, data);
+    }
+}
+
+static void
+save_as_documents_list (SaveAsData *data)
+{
+    XedTab *next_tab = XED_TAB (data->tabs_to_save_as->data);
+
+    xed_window_set_active_tab (data->window, next_tab);
+
+    save_as_tab_async (next_tab,
+                       data->window,
+                       NULL,
+                       (GAsyncReadyCallback) save_as_documents_list_cb,
+                       data);
 }
 
 /*
@@ -835,8 +1043,8 @@ static void
 save_documents_list (XedWindow *window,
                      GList     *docs)
 {
+    SaveAsData *data = NULL;
     GList *l;
-    GSList *tabs_to_save_as = NULL;
 
     xed_debug (DEBUG_COMMANDS);
 
@@ -868,9 +1076,17 @@ save_documents_list (XedWindow *window,
             if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
             {
                 if (_xed_document_needs_saving (doc))
+                {
+                    if (data == NULL)
                     {
-                        tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t);
+                        data = g_slice_new (SaveAsData);
+                        data->window = g_object_ref (window);
+                        data->tabs_to_save_as = NULL;
+                        data->close_tabs = FALSE;
                     }
+
+                    data->tabs_to_save_as = g_slist_prepend (data->tabs_to_save_as, g_object_ref (t));
+                }
             }
             else
             {
@@ -913,23 +1129,21 @@ save_documents_list (XedWindow *window,
         l = g_list_next (l);
     }
 
-    if (tabs_to_save_as != NULL)
+    if (data != NULL)
     {
-        XedTab *tab;
-
-        tabs_to_save_as = g_slist_reverse (tabs_to_save_as );
-
-        g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL);
-
-        g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
-
-        tab = XED_TAB (tabs_to_save_as->data);
-
-        xed_window_set_active_tab (window, tab);
-        save_as_tab (tab, window);
+        data->tabs_to_save_as = g_slist_reverse (data->tabs_to_save_as);
+        save_as_documents_list (data);
     }
 }
 
+/**
+ * xed_commands_save_all_documents:
+ * @window: a #XedWindow.
+ *
+ * Asynchronously save all documents belonging to @window. The result of the
+ * operation is not available, so it's difficult to know whether all the
+ * documents are correctly saved.
+ */
 void
 xed_commands_save_all_documents (XedWindow *window)
 {
@@ -953,6 +1167,14 @@ _xed_cmd_file_save_all (GtkAction *action,
     xed_commands_save_all_documents (window);
 }
 
+/**
+ * xed_commands_save_document:
+ * @window: a #XedWindow.
+ * @document: the #XedDocument to save.
+ *
+ * Asynchronously save @document. @document must belong to @window. If you need
+ * the result of the operation, use xed_commands_save_document_async().
+ */
 void
 xed_commands_save_document (XedWindow   *window,
                             XedDocument *document)
@@ -1161,39 +1383,6 @@ _xed_cmd_file_revert (GtkAction   *action,
     gtk_widget_show (dialog);
 }
 
-/* Close tab */
-static gboolean
-really_close_tab (XedTab *tab)
-{
-    GtkWidget *toplevel;
-    XedWindow *window;
-
-    xed_debug (DEBUG_COMMANDS);
-
-    g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, FALSE);
-
-    toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
-    g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE);
-
-    window = XED_WINDOW (toplevel);
-
-    xed_window_close_tab (window, tab);
-
-    if (xed_window_get_active_tab (window) == NULL)
-    {
-        gboolean is_quitting;
-
-        is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING));
-
-        if (is_quitting)
-        {
-            gtk_widget_destroy (GTK_WIDGET (window));
-        }
-    }
-
-    return FALSE;
-}
-
 static void
 tab_state_changed_while_saving (XedTab     *tab,
                                 GParamSpec *pspec,
@@ -1209,26 +1398,9 @@ tab_state_changed_while_saving (XedTab     *tab,
        finished */
     if (ts == XED_TAB_STATE_NORMAL)
     {
-        XedDocument *doc;
-
         g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (tab_state_changed_while_saving), window);
 
-        doc = xed_tab_get_document (tab);
-        g_return_if_fail (doc != NULL);
-
-        /* If the saving operation failed or was interrupted, then the
-           document is still "modified" -> do not close the tab */
-        if (_xed_document_needs_saving (doc))
-        {
-            return;
-        }
-
-        /* Close the document only if it has been succesfully saved.
-           Tab state is set to CLOSING (it is a state without exiting
-           transitions) and the tab is closed in a idle handler */
-        _xed_tab_mark_for_closing (tab);
-
-        g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc)really_close_tab, tab, NULL);
+        close_tab (tab);
     }
 }
 
@@ -1244,21 +1416,6 @@ save_and_close (XedTab    *tab,
     save_tab (tab, window);
 }
 
-static void
-save_as_and_close (XedTab    *tab,
-                   XedWindow *window)
-{
-    xed_debug (DEBUG_COMMANDS);
-
-    g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL);
-
-    /* Trace tab state changes */
-    g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
-
-    xed_window_set_active_tab (window, tab);
-    save_as_tab (tab, window);
-}
-
 static void
 save_and_close_all_documents (const GList *docs,
                               XedWindow   *window)
@@ -1266,9 +1423,9 @@ save_and_close_all_documents (const GList *docs,
     GList  *tabs;
     GList  *l;
     GSList *sl;
-    GSList *tabs_to_save_as;
-    GSList *tabs_to_save_and_close;
-    GList  *tabs_to_close;
+    SaveAsData *data = NULL;
+    GSList *tabs_to_save_and_close = NULL;
+    GList  *tabs_to_close = NULL;
 
     xed_debug (DEBUG_COMMANDS);
 
@@ -1276,19 +1433,13 @@ save_and_close_all_documents (const GList *docs,
 
     tabs = gtk_container_get_children (GTK_CONTAINER (_xed_window_get_notebook (window)));
 
-    tabs_to_save_as = NULL;
-    tabs_to_save_and_close = NULL;
-    tabs_to_close = NULL;
-
     l = tabs;
     while (l != NULL)
     {
-        XedTab *t;
+        XedTab *t = XED_TAB (l->data);;
         XedTabState state;
         XedDocument *doc;
 
-        t = XED_TAB (l->data);
-
         state = xed_tab_get_state (t);
         doc = xed_tab_get_document (t);
 
@@ -1337,9 +1488,15 @@ save_and_close_all_documents (const GList *docs,
                    user is running xed - Paolo (Dec. 8, 2005) */
                 if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
                 {
-                    g_object_set_data (G_OBJECT (t), XED_IS_CLOSING_TAB, GBOOLEAN_TO_POINTER (TRUE));
+                    if (data == NULL)
+                    {
+                        data = g_slice_new (SaveAsData);
+                        data->window = g_object_ref (window);
+                        data->tabs_to_save_as = NULL;
+                        data->close_tabs = TRUE;
+                    }
 
-                    tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t);
+                    data->tabs_to_save_as = g_slist_prepend (data->tabs_to_save_as, g_object_ref (t));
                 }
                 else
                 {
@@ -1371,20 +1528,11 @@ save_and_close_all_documents (const GList *docs,
     }
     g_slist_free (tabs_to_save_and_close);
 
-    /* Save As and close all the files in tabs_to_save_as  */
-    if (tabs_to_save_as != NULL)
+    /* Save As and close all the files in data->tabs_to_save_as. */
+    if (data != NULL)
     {
-        XedTab *tab;
-
-        tabs_to_save_as = g_slist_reverse (tabs_to_save_as );
-
-        g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL);
-
-        g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
-
-        tab = XED_TAB (tabs_to_save_as->data);
-
-        save_as_and_close (tab, window);
+        data->tabs_to_save_as = g_slist_reverse (data->tabs_to_save_as);
+        save_as_documents_list (data);
     }
 }
 
diff --git a/xed/xed-commands.h b/xed/xed-commands.h
index 1ff5ae9..679bc1e 100644
--- a/xed/xed-commands.h
+++ b/xed/xed-commands.h
@@ -12,6 +12,8 @@ void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSo
 /* Ignore non-existing URIs */
 GSList *xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
 void xed_commands_save_document (XedWindow *window, XedDocument *document);
+void xed_commands_save_document_async (XedDocument *document, XedWindow *window, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean xed_commands_save_document_finish (XedDocument *document, GAsyncResult *result);
 void xed_commands_save_all_documents (XedWindow *window);
 
 /*
diff --git a/xed/xed-document-private.h b/xed/xed-document-private.h
new file mode 100644
index 0000000..9693eb9
--- /dev/null
+++ b/xed/xed-document-private.h
@@ -0,0 +1,21 @@
+#ifndef __XED_DOCUMENT_PRIVATE_H__
+#define __XED_DOCUMENT_PRIVATE_H__
+
+#include "xed-document.h"
+
+G_BEGIN_DECLS
+
+glong        _xed_document_get_seconds_since_last_save_or_load  (XedDocument       *doc);
+
+gboolean     _xed_document_needs_saving                         (XedDocument       *doc);
+
+gboolean     _xed_document_get_empty_search                     (XedDocument       *doc);
+
+void         _xed_document_set_create                           (XedDocument       *doc,
+                                                                 gboolean           create);
+
+gboolean     _xed_document_get_create                           (XedDocument       *doc);
+
+G_END_DECLS
+
+#endif /* __XED_DOCUMENT_PRIVATE_H__ */
diff --git a/xed/xed-document.c b/xed/xed-document.c
index 44f27f3..470e831 100644
--- a/xed/xed-document.c
+++ b/xed/xed-document.c
@@ -41,26 +41,20 @@
 #include <gtk/gtk.h>
 
 #include "xed-document.h"
+#include "xed-document-private.h"
 #include "xed-settings.h"
 #include "xed-debug.h"
 #include "xed-utils.h"
-#include "xed-marshal.h"
-#include "xed-enum-types.h"
-
-#ifndef ENABLE_GVFS_METADATA
 #include "xed-metadata-manager.h"
-#else
+
 #define METADATA_QUERY "metadata::*"
-#endif
 
 #define NO_LANGUAGE_NAME "_NORMAL_"
 
-#define XED_DOCUMENT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), XED_TYPE_DOCUMENT, XedDocumentPrivate))
-
 static void xed_document_loaded_real (XedDocument  *doc);
 static void xed_document_saved_real (XedDocument  *doc);
 
-struct _XedDocumentPrivate
+typedef struct
 {
     GtkSourceFile *file;
 
@@ -73,24 +67,22 @@ struct _XedDocumentPrivate
 
     gchar *content_type;
 
-    GTimeVal mtime;
     GTimeVal time_of_last_save_or_load;
 
     GtkSourceSearchContext *search_context;
 
-    guint readonly : 1;
-    guint externally_modified : 1;
-    guint deleted : 1;
+    guint user_action;
+
     guint last_save_was_manually : 1;
     guint language_set_by_user : 1;
     guint stop_cursor_moved_emission : 1;
-    guint mtime_set : 1;
+    guint use_gvfs_metadata : 1;
 
     /* Create file if location points to a non existing file (for example
      * when opened from the command line).
      */
     guint create : 1;
-};
+} XedDocumentPrivate;
 
 enum
 {
@@ -98,9 +90,13 @@ enum
     PROP_SHORTNAME,
     PROP_CONTENT_TYPE,
     PROP_MIME_TYPE,
-    PROP_READ_ONLY
+    PROP_READ_ONLY,
+    PROP_USE_GVFS_METADATA,
+    LAST_PROP
 };
 
+static GParamSpec *properties[LAST_PROP];
+
 enum
 {
     CURSOR_MOVED,
@@ -111,11 +107,11 @@ enum
     LAST_SIGNAL
 };
 
-static guint document_signals[LAST_SIGNAL] = { 0 };
+static guint document_signals[LAST_SIGNAL];
 
 static GHashTable *allocated_untitled_numbers = NULL;
 
-G_DEFINE_TYPE(XedDocument, xed_document, GTK_SOURCE_TYPE_BUFFER)
+G_DEFINE_TYPE_WITH_PRIVATE (XedDocument, xed_document, GTK_SOURCE_TYPE_BUFFER)
 
 static gint
 get_untitled_number (void)
@@ -161,11 +157,13 @@ get_language_string (XedDocument *doc)
 static void
 save_metadata (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     const gchar *language = NULL;
     GtkTextIter iter;
     gchar *position;
 
-    if (doc->priv->language_set_by_user)
+    priv = xed_document_get_instance_private (doc);
+    if (priv->language_set_by_user)
     {
         language = get_language_string (doc);
     }
@@ -196,24 +194,26 @@ save_metadata (XedDocument *doc)
 static void
 xed_document_dispose (GObject *object)
 {
-    XedDocument *doc = XED_DOCUMENT (object);
+    XedDocumentPrivate *priv;
 
     xed_debug (DEBUG_DOCUMENT);
 
+    priv = xed_document_get_instance_private (XED_DOCUMENT (object));
+
     /* Metadata must be saved here and not in finalize because the language
     * is gone by the time finalize runs.
     */
-    if (doc->priv->file != NULL)
+    if (priv->file != NULL)
     {
-        save_metadata (doc);
+        save_metadata (XED_DOCUMENT (object));
 
-        g_object_unref (doc->priv->file);
-        doc->priv->file = NULL;
+        g_object_unref (priv->file);
+        priv->file = NULL;
     }
 
-    g_clear_object (&doc->priv->editor_settings);
-    g_clear_object (&doc->priv->metadata_info);
-    g_clear_object (&doc->priv->search_context);
+    g_clear_object (&priv->editor_settings);
+    g_clear_object (&priv->metadata_info);
+    g_clear_object (&priv->search_context);
 
     G_OBJECT_CLASS (xed_document_parent_class)->dispose (object);
 }
@@ -221,17 +221,19 @@ xed_document_dispose (GObject *object)
 static void
 xed_document_finalize (GObject *object)
 {
-    XedDocument *doc = XED_DOCUMENT (object);
+    XedDocumentPrivate *priv;
 
     xed_debug (DEBUG_DOCUMENT);
 
-    if (doc->priv->untitled_number > 0)
+    priv = xed_document_get_instance_private (XED_DOCUMENT (object));
+
+    if (priv->untitled_number > 0)
     {
-        release_untitled_number (doc->priv->untitled_number);
+        release_untitled_number (priv->untitled_number);
     }
 
-    g_free (doc->priv->content_type);
-    g_free (doc->priv->short_name);
+    g_free (priv->content_type);
+    g_free (priv->short_name);
 
     G_OBJECT_CLASS (xed_document_parent_class)->finalize (object);
 }
@@ -243,6 +245,9 @@ xed_document_get_property (GObject    *object,
                            GParamSpec *pspec)
 {
     XedDocument *doc = XED_DOCUMENT (object);
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
 
     switch (prop_id)
     {
@@ -256,7 +261,10 @@ xed_document_get_property (GObject    *object,
             g_value_take_string (value, xed_document_get_mime_type (doc));
             break;
         case PROP_READ_ONLY:
-            g_value_set_boolean (value, doc->priv->readonly);
+            g_value_set_boolean (value, gtk_source_file_is_readonly (priv->file));
+            break;
+        case PROP_USE_GVFS_METADATA:
+            g_value_set_boolean (value, priv->use_gvfs_metadata);
             break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -271,6 +279,9 @@ xed_document_set_property (GObject      *object,
                            GParamSpec   *pspec)
 {
     XedDocument *doc = XED_DOCUMENT (object);
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
 
     switch (prop_id)
     {
@@ -280,16 +291,53 @@ xed_document_set_property (GObject      *object,
         case PROP_CONTENT_TYPE:
             xed_document_set_content_type (doc, g_value_get_string (value));
             break;
+        case PROP_USE_GVFS_METADATA:
+            priv->use_gvfs_metadata = g_value_get_boolean (value);
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
     }
 }
 
+static void
+xed_document_begin_user_action (GtkTextBuffer *buffer)
+{
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (XED_DOCUMENT (buffer));
+
+    ++priv->user_action;
+
+    if (GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->begin_user_action != NULL)
+    {
+        GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->begin_user_action (buffer);
+    }
+}
+
+static void
+xed_document_end_user_action (GtkTextBuffer *buffer)
+{
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (XED_DOCUMENT (buffer));
+
+    --priv->user_action;
+
+    if (GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->end_user_action != NULL)
+    {
+        GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->end_user_action (buffer);
+    }
+}
+
 static void
 emit_cursor_moved (XedDocument *doc)
 {
-    if (!doc->priv->stop_cursor_moved_emission)
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
+
+    if (!priv->stop_cursor_moved_emission)
     {
         g_signal_emit (doc, document_signals[CURSOR_MOVED], 0);
     }
@@ -301,13 +349,16 @@ xed_document_mark_set (GtkTextBuffer     *buffer,
                        GtkTextMark       *mark)
 {
     XedDocument *doc = XED_DOCUMENT (buffer);
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
 
     if (GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set != NULL)
     {
         GTK_TEXT_BUFFER_CLASS (xed_document_parent_class)->mark_set (buffer, iter, mark);
     }
 
-    if (mark == gtk_text_buffer_get_insert (buffer))
+    if (mark == gtk_text_buffer_get_insert (buffer) && (priv->user_action == 0))
     {
         emit_cursor_moved (doc);
     }
@@ -325,8 +376,11 @@ static void
 xed_document_constructed (GObject *object)
 {
     XedDocument *doc = XED_DOCUMENT (object);
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
 
-    g_settings_bind (doc->priv->editor_settings,
+    g_settings_bind (priv->editor_settings,
                      XED_SETTINGS_ENSURE_TRAILING_NEWLINE,
                      doc,
                      "implicit-trailing-newline",
@@ -347,43 +401,77 @@ xed_document_class_init (XedDocumentClass *klass)
     object_class->set_property = xed_document_set_property;
     object_class->constructed = xed_document_constructed;
 
+    buf_class->begin_user_action = xed_document_begin_user_action;
+    buf_class->end_user_action = xed_document_end_user_action;
     buf_class->mark_set = xed_document_mark_set;
     buf_class->changed = xed_document_changed;
 
     klass->loaded = xed_document_loaded_real;
     klass->saved = xed_document_saved_real;
 
-    g_object_class_install_property (object_class, PROP_SHORTNAME,
-                                     g_param_spec_string ("shortname",
-                                                          "Short Name",
-                                                          "The document's short name",
-                                                          NULL,
-                                                          G_PARAM_READWRITE |
-                                                          G_PARAM_STATIC_STRINGS));
-
-    g_object_class_install_property (object_class, PROP_CONTENT_TYPE,
-                                     g_param_spec_string ("content-type",
-                                                          "Content Type",
-                                                          "The document's Content Type",
-                                                          NULL,
-                                                          G_PARAM_READWRITE |
-                                                          G_PARAM_STATIC_STRINGS));
-
-    g_object_class_install_property (object_class, PROP_MIME_TYPE,
-                                     g_param_spec_string ("mime-type",
-                                                          "MIME Type",
-                                                          "The document's MIME Type",
-                                                          "text/plain",
-                                                          G_PARAM_READABLE |
-                                                          G_PARAM_STATIC_STRINGS));
-
-    g_object_class_install_property (object_class, PROP_READ_ONLY,
-                                     g_param_spec_boolean ("read-only",
-                                                           "Read Only",
-                                                           "Whether the document is read only or not",
-                                                           FALSE,
-                                                           G_PARAM_READABLE |
-                                                           G_PARAM_STATIC_STRINGS));
+    /**
+     * XedDocument:shortname:
+     *
+     * The documents short name.
+     */
+    properties[PROP_SHORTNAME] =
+        g_param_spec_string ("shortname",
+                             "Short Name",
+                             "The documents short name",
+                             NULL,
+                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * XedDocument:content-type:
+     *
+     * The documents content type.
+     */
+    properties[PROP_CONTENT_TYPE] =
+        g_param_spec_string ("content-type",
+                             "Content Type",
+                             "The documents content type",
+                             NULL,
+                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * XedDocument:mime-type:
+     *
+     * The documents MIME type.
+     */
+    properties[PROP_MIME_TYPE] =
+        g_param_spec_string ("mime-type",
+                             "MIME Type",
+                             "The documents MIME type",
+                             "text/plain",
+                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+    properties[PROP_READ_ONLY] =
+        g_param_spec_boolean ("read-only",
+                              "Read Only",
+                              "Whether the document is read-only or not",
+                              FALSE,
+                              G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * XedDocument:use-gvfs-metadata:
+     *
+     * Whether to use GVFS metadata. If %FALSE, use the xed metadata
+     * manager that stores the metadata in an XML file in the user cache
+     * directory.
+     *
+     * <warning>
+     * The property is used internally by xed. It must not be used in a
+     * xed plugin. The property can be modified or removed at any time.
+     * </warning>
+     */
+    properties[PROP_USE_GVFS_METADATA] =
+        g_param_spec_boolean ("use-gvfs-metadata",
+                              "Use GVFS metadata",
+                              "",
+                              TRUE,
+                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+    g_object_class_install_properties (object_class, LAST_PROP, properties);
 
     /* This signal is used to update the cursor position is the statusbar,
      * it's emitted either when the insert mark is moved explicitely or
@@ -396,8 +484,7 @@ xed_document_class_init (XedDocumentClass *klass)
                       G_OBJECT_CLASS_TYPE (object_class),
                       G_SIGNAL_RUN_LAST,
                       G_STRUCT_OFFSET (XedDocumentClass, cursor_moved),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID,
+                      NULL, NULL, NULL,
                       G_TYPE_NONE,
                       0);
 
@@ -424,7 +511,7 @@ xed_document_class_init (XedDocumentClass *klass)
     document_signals[LOADED] =
         g_signal_new ("loaded",
                       G_OBJECT_CLASS_TYPE (object_class),
-                      G_SIGNAL_RUN_LAST,
+                      G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET (XedDocumentClass, loaded),
                       NULL, NULL, NULL,
                       G_TYPE_NONE, 0);
@@ -452,12 +539,10 @@ xed_document_class_init (XedDocumentClass *klass)
     document_signals[SAVED] =
         g_signal_new ("saved",
                       G_OBJECT_CLASS_TYPE (object_class),
-                      G_SIGNAL_RUN_LAST,
+                      G_SIGNAL_RUN_FIRST,
                       G_STRUCT_OFFSET (XedDocumentClass, saved),
                       NULL, NULL, NULL,
                       G_TYPE_NONE, 0);
-
-    g_type_class_add_private (object_class, sizeof (XedDocumentPrivate));
 }
 
 static void
@@ -465,10 +550,13 @@ set_language (XedDocument       *doc,
               GtkSourceLanguage *lang,
               gboolean           set_by_user)
 {
+    XedDocumentPrivate *priv;
     GtkSourceLanguage *old_lang;
 
     xed_debug (DEBUG_DOCUMENT);
 
+    priv = xed_document_get_instance_private (doc);
+
     old_lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc));
 
     if (old_lang == lang)
@@ -478,19 +566,6 @@ set_language (XedDocument       *doc,
 
     gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (doc), lang);
 
-    if (lang != NULL)
-    {
-        gboolean syntax_hl;
-
-        syntax_hl = g_settings_get_boolean (doc->priv->editor_settings,
-                                            XED_SETTINGS_SYNTAX_HIGHLIGHTING);
-        gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), syntax_hl);
-    }
-    else
-    {
-        gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), FALSE);
-    }
-
     if (set_by_user)
     {
         const gchar *language = get_language_string (doc);
@@ -498,18 +573,21 @@ set_language (XedDocument       *doc,
         xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE, language, NULL);
     }
 
-    doc->priv->language_set_by_user = set_by_user;
+    priv->language_set_by_user = set_by_user;
 }
 
 static void
 save_encoding_metadata (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     const GtkSourceEncoding *encoding;
     const gchar *charset;
 
     xed_debug (DEBUG_DOCUMENT);
 
-    encoding = gtk_source_file_get_encoding (doc->priv->file);
+    priv = xed_document_get_instance_private (doc);
+
+    encoding = gtk_source_file_get_encoding (priv->file);
 
     if (encoding == NULL)
     {
@@ -551,10 +629,13 @@ get_default_style_scheme (GSettings *editor_settings)
 static GtkSourceLanguage *
 guess_language (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     gchar *data;
     GtkSourceLanguageManager *manager = gtk_source_language_manager_get_default ();
     GtkSourceLanguage *language = NULL;
 
+    priv = xed_document_get_instance_private (doc);
+
     data = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_LANGUAGE);
 
     if (data != NULL)
@@ -573,19 +654,19 @@ guess_language (XedDocument *doc)
         GFile *location;
         gchar *basename = NULL;
 
-        location = gtk_source_file_get_location (doc->priv->file);
+        location = gtk_source_file_get_location (priv->file);
         xed_debug_message (DEBUG_DOCUMENT, "Sniffing Language");
 
         if (location != NULL)
         {
             basename = g_file_get_basename (location);
         }
-        else if (doc->priv->short_name != NULL)
+        else if (priv->short_name != NULL)
         {
-            basename = g_strdup (doc->priv->short_name);
+            basename = g_strdup (priv->short_name);
         }
 
-        language = gtk_source_language_manager_guess_language (manager, basename, doc->priv->content_type);
+        language = gtk_source_language_manager_guess_language (manager, basename, priv->content_type);
 
         g_free (basename);
     }
@@ -598,7 +679,11 @@ on_content_type_changed (XedDocument *doc,
                          GParamSpec  *pspec,
                          gpointer     useless)
 {
-    if (!doc->priv->language_set_by_user)
+    XedDocumentPrivate *priv;
+
+    priv = xed_document_get_instance_private (doc);
+
+    if (!priv->language_set_by_user)
     {
         GtkSourceLanguage *language = guess_language (doc);
 
@@ -620,61 +705,74 @@ on_location_changed (GtkSourceFile *file,
                      GParamSpec    *pspec,
                      XedDocument   *doc)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
     xed_debug (DEBUG_DOCUMENT);
 
+    priv = xed_document_get_instance_private (doc);
+
     location = gtk_source_file_get_location (file);
 
-    if (location != NULL && doc->priv->untitled_number > 0)
+    if (location != NULL && priv->untitled_number > 0)
     {
-        release_untitled_number (doc->priv->untitled_number);
-        doc->priv->untitled_number = 0;
+        release_untitled_number (priv->untitled_number);
+        priv->untitled_number = 0;
     }
 
-    if (doc->priv->short_name == NULL)
+    if (priv->short_name == NULL)
     {
-        g_object_notify (G_OBJECT (doc), "shortname");
+        g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_SHORTNAME]);
     }
 
-#ifdef ENABLE_GVFS_METADATA
-
-    /* load metadata for this location: we load sync since metadata is
-    * always local so it should be fast and we need the information
-    * right after the location was set.
-    */
-    if (location != NULL)
+    /* Load metadata for this location: we load sync since metadata is
+     * always local so it should be fast and we need the information
+     * right after the location was set.
+     */
+    if (priv->use_gvfs_metadata && location != NULL)
     {
         GError *error = NULL;
 
-        if (doc->priv->metadata_info != NULL)
+        if (priv->metadata_info != NULL)
         {
-            g_object_unref (doc->priv->metadata_info);
+            g_object_unref (priv->metadata_info);
         }
 
-        doc->priv->metadata_info = g_file_query_info (location,
-                                                      METADATA_QUERY,
-                                                      G_FILE_QUERY_INFO_NONE,
-                                                      NULL,
-                                                      &error);
+        priv->metadata_info = g_file_query_info (location,
+                                                 METADATA_QUERY,
+                                                 G_FILE_QUERY_INFO_NONE,
+                                                 NULL,
+                                                 &error);
 
         if (error != NULL)
         {
-            /* TODO document why the warning is not displayed in
-             * certain cases.
+            /* Do not complain about metadata if we are opening a
+             * non existing file.
              */
-            if (error->domain != G_FILE_ERROR ||
-                (error->code != G_FILE_ERROR_ISDIR &&
-                 error->code != G_FILE_ERROR_NOTDIR &&
-                 error->code != G_FILE_ERROR_NOENT))
+            if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) &&
+                !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) &&
+                !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
+                !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
              {
                  g_warning ("%s", error->message);
              }
 
             g_error_free (error);
         }
+
+        if (priv->metadata_info == NULL)
+        {
+            priv->metadata_info = g_file_info_new ();
+        }
     }
-#endif
+}
+
+static void
+on_readonly_changed (GtkSourceFile *file,
+                     GParamSpec    *pspec,
+                     XedDocument   *doc)
+{
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_READ_ONLY]);
 }
 
 static void
@@ -685,40 +783,43 @@ xed_document_init (XedDocument *doc)
 
     xed_debug (DEBUG_DOCUMENT);
 
-    doc->priv = XED_DOCUMENT_GET_PRIVATE (doc);
-    priv = doc->priv;
+    priv = xed_document_get_instance_private (doc);
 
     priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor");
-
     priv->untitled_number = get_untitled_number ();
-
     priv->content_type = get_default_content_type ();
-
-    priv->readonly = FALSE;
-
     priv->stop_cursor_moved_emission = FALSE;
-
     priv->last_save_was_manually = TRUE;
     priv->language_set_by_user = FALSE;
 
-    g_get_current_time (&doc->priv->time_of_last_save_or_load);
+    g_get_current_time (&priv->time_of_last_save_or_load);
 
     priv->file = gtk_source_file_new ();
+    priv->metadata_info = g_file_info_new ();
 
     g_signal_connect_object (priv->file, "notify::location",
                              G_CALLBACK (on_location_changed), doc, 0);
 
+    g_signal_connect_object (priv->file, "notify::read-only",
+                             G_CALLBACK (on_readonly_changed), doc, 0);
+
+    g_settings_bind (priv->editor_settings,
+                     XED_SETTINGS_SYNTAX_HIGHLIGHTING,
+                     doc,
+                     "highlight-syntax",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
+
     g_settings_bind (priv->editor_settings,
                      XED_SETTINGS_MAX_UNDO_ACTIONS,
                      doc,
                      "max-undo-levels",
-                     G_SETTINGS_BIND_GET);
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
 
     g_settings_bind (priv->editor_settings,
                      XED_SETTINGS_BRACKET_MATCHING,
                      doc,
                      "highlight-matching-brackets",
-                     G_SETTINGS_BIND_GET);
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
 
     style_scheme = get_default_style_scheme (priv->editor_settings);
     if (style_scheme != NULL)
@@ -732,34 +833,46 @@ xed_document_init (XedDocument *doc)
 XedDocument *
 xed_document_new (void)
 {
-    return g_object_new (XED_TYPE_DOCUMENT, NULL);
+    gboolean use_gvfs_metadata;
+
+#ifdef ENABLE_GVFS_METADATA
+    use_gvfs_metadata = TRUE;
+#else
+    use_gvfs_metadata = FALSE;
+#endif
+
+    return g_object_new (XED_TYPE_DOCUMENT,
+                         "use-gvfs-metadata", use_gvfs_metadata,
+                         NULL);
 }
 
 static void
 set_content_type_no_guess (XedDocument *doc,
                            const gchar *content_type)
 {
+    XedDocumentPrivate *priv;
     xed_debug (DEBUG_DOCUMENT);
 
-    if (doc->priv->content_type != NULL &&
-        content_type != NULL &&
-        g_str_equal (doc->priv->content_type, content_type))
+    priv = xed_document_get_instance_private (doc);
+
+    if (priv->content_type != NULL && content_type != NULL &&
+        g_str_equal (priv->content_type, content_type))
     {
         return;
     }
 
-    g_free (doc->priv->content_type);
+    g_free (priv->content_type);
 
     if (content_type == NULL || g_content_type_is_unknown (content_type))
     {
-        doc->priv->content_type = get_default_content_type ();
+        priv->content_type = get_default_content_type ();
     }
     else
     {
-        doc->priv->content_type = g_strdup (content_type);
+        priv->content_type = g_strdup (content_type);
     }
 
-    g_object_notify (G_OBJECT (doc), "content-type");
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_CONTENT_TYPE]);
 }
 
 /**
@@ -771,17 +884,21 @@ void
 xed_document_set_content_type (XedDocument *doc,
                                const gchar *content_type)
 {
+    XedDocumentPrivate *priv;
+
     g_return_if_fail (XED_IS_DOCUMENT (doc));
 
     xed_debug (DEBUG_DOCUMENT);
 
+    priv = xed_document_get_instance_private (doc);
+
     if (content_type == NULL)
     {
         GFile *location;
         gchar *guessed_type = NULL;
 
         /* If content type is null, we guess from the filename */
-        location = gtk_source_file_get_location (doc->priv->file);
+        location = gtk_source_file_get_location (priv->file);
         if (location != NULL)
         {
             gchar *basename;
@@ -810,11 +927,14 @@ xed_document_set_content_type (XedDocument *doc,
 GFile *
 xed_document_get_location (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
+    priv = xed_document_get_instance_private (doc);
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    location = gtk_source_file_get_location (priv->file);
 
     return location != NULL ? g_object_ref (location) : NULL;
 }
@@ -823,10 +943,12 @@ void
 xed_document_set_location (XedDocument *doc,
                            GFile       *location)
 {
+    XedDocumentPrivate *priv;
+
     g_return_if_fail (XED_IS_DOCUMENT (doc));
     g_return_if_fail (G_IS_FILE (location));
 
-    gtk_source_file_set_location (doc->priv->file, location);
+    gtk_source_file_set_location (priv->file, location);
     xed_document_set_content_type (doc, NULL);
 }
 
@@ -839,15 +961,18 @@ xed_document_set_location (XedDocument *doc,
 gchar *
 xed_document_get_uri_for_display (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup (""));
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    priv = xed_document_get_instance_private (doc);
+
+    location = gtk_source_file_get_location (priv->file);
 
     if (location == NULL)
     {
-        return g_strdup_printf (_("Unsaved Document %d"), doc->priv->untitled_number);
+        return g_strdup_printf (_("Unsaved Document %d"), priv->untitled_number);
     }
     else
     {
@@ -864,19 +989,22 @@ xed_document_get_uri_for_display (XedDocument *doc)
 gchar *
 xed_document_get_short_name_for_display (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup (""));
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    priv = xed_document_get_instance_private (doc);
+
+    location = gtk_source_file_get_location (priv->file);
 
-    if (doc->priv->short_name != NULL)
+    if (priv->short_name != NULL)
     {
-        return g_strdup (doc->priv->short_name);
+        return g_strdup (priv->short_name);
     }
     else if (location == NULL)
     {
-        return g_strdup_printf (_("Unsaved Document %d"), doc->priv->untitled_number);
+        return g_strdup_printf (_("Unsaved Document %d"), priv->untitled_number);
     }
     else
     {
@@ -893,20 +1021,28 @@ void
 xed_document_set_short_name_for_display (XedDocument *doc,
                                          const gchar *short_name)
 {
+    XedDocumentPrivate *priv;
+
     g_return_if_fail (XED_IS_DOCUMENT (doc));
 
-    g_free (doc->priv->short_name);
-    doc->priv->short_name = g_strdup (short_name);
+    priv = xed_document_get_instance_private (doc);
+
+    g_free (priv->short_name);
+    priv->short_name = g_strdup (short_name);
 
-    g_object_notify (G_OBJECT (doc), "shortname");
+    g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_SHORTNAME]);
 }
 
 gchar *
 xed_document_get_content_type (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
 
-    return g_strdup (doc->priv->content_type);
+    priv = xed_document_get_instance_private (doc);
+
+    return g_strdup (priv->content_type);
 }
 
 /**
@@ -918,40 +1054,31 @@ xed_document_get_content_type (XedDocument *doc)
 gchar *
 xed_document_get_mime_type (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), g_strdup ("text/plain"));
 
-    if (doc->priv->content_type != NULL &&
-        !g_content_type_is_unknown (doc->priv->content_type))
+    priv = xed_document_get_instance_private (doc);
+
+    if (priv->content_type != NULL &&
+        !g_content_type_is_unknown (priv->content_type))
     {
-        return g_content_type_get_mime_type (doc->priv->content_type);
+        return g_content_type_get_mime_type (priv->content_type);
     }
 
     return g_strdup ("text/plain");
 }
 
-static void
-set_readonly (XedDocument *doc,
-              gboolean     readonly)
-{
-    xed_debug (DEBUG_DOCUMENT);
-
-    g_return_if_fail (XED_IS_DOCUMENT (doc));
-
-    readonly = readonly != FALSE;
-
-    if (doc->priv->readonly != readonly)
-    {
-        doc->priv->readonly = readonly;
-        g_object_notify (G_OBJECT (doc), "read-only");
-    }
-}
-
 gboolean
 xed_document_get_readonly (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE);
 
-    return doc->priv->readonly;
+    priv = xed_document_get_instance_private (doc);
+
+    return gtk_source_file_is_readonly (priv->file);
 }
 
 static void
@@ -978,33 +1105,17 @@ loaded_query_info_cb (GFile        *location,
         error = NULL;
     }
 
-    if (info != NULL)
+    if (info != NULL && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
     {
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
-        {
-            const gchar *content_type;
+        const gchar *content_type;
 
-            content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-            xed_document_set_content_type (doc, content_type);
-        }
-
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
-        {
-            gboolean read_only;
-
-            read_only = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
-            set_readonly (doc, read_only);
-        }
-
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
-        {
-            g_file_info_get_modification_time (info, &doc->priv->mtime);
-            doc->priv->mtime_set = TRUE;
-        }
+        content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
 
-        g_object_unref (info);
+        xed_document_set_content_type (doc, content_type);
     }
 
+    g_clear_object (&info);
+
     /* Async operation finished. */
     g_object_unref (doc);
 }
@@ -1012,9 +1123,12 @@ loaded_query_info_cb (GFile        *location,
 static void
 xed_document_loaded_real (XedDocument *doc)
 {
-   GFile *location;
+    XedDocumentPrivate *priv;
+    GFile *location;
+
+    priv = xed_document_get_instance_private (doc);
 
-    if (!doc->priv->language_set_by_user)
+    if (!priv->language_set_by_user)
     {
         GtkSourceLanguage *language = guess_language (doc);
 
@@ -1024,17 +1138,11 @@ xed_document_loaded_real (XedDocument *doc)
         set_language (doc, language, FALSE);
     }
 
-    doc->priv->mtime_set = FALSE;
-    doc->priv->externally_modified = FALSE;
-    doc->priv->deleted = FALSE;
-
-    g_get_current_time (&doc->priv->time_of_last_save_or_load);
-
-    set_readonly (doc, FALSE);
+    g_get_current_time (&priv->time_of_last_save_or_load);
 
     xed_document_set_content_type (doc, NULL);
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    location = gtk_source_file_get_location (priv->file);
 
     if (location != NULL)
     {
@@ -1043,8 +1151,7 @@ xed_document_loaded_real (XedDocument *doc)
 
         g_file_query_info_async (location,
                                  G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
-                                 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ","
-                                 G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                                 G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
                                  G_FILE_QUERY_INFO_NONE,
                                  G_PRIORITY_DEFAULT,
                                  NULL,
@@ -1058,10 +1165,13 @@ saved_query_info_cb (GFile        *location,
                      GAsyncResult *result,
                      XedDocument  *doc)
 {
+    XedDocumentPrivate *priv;
     GFileInfo *info;
     const gchar *content_type = NULL;
     GError *error = NULL;
 
+    priv = xed_document_get_instance_private (doc);
+
     info = g_file_query_info_finish (location, result, &error);
 
     if (error != NULL)
@@ -1071,20 +1181,9 @@ saved_query_info_cb (GFile        *location,
         error = NULL;
     }
 
-    doc->priv->mtime_set = FALSE;
-
-    if (info != NULL)
+    if (info != NULL && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
     {
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
-        {
-            content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-        }
-
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
-        {
-            g_file_info_get_modification_time (info, &doc->priv->mtime);
-            doc->priv->mtime_set = TRUE;
-        }
+        content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
     }
 
     xed_document_set_content_type (doc, content_type);
@@ -1094,15 +1193,9 @@ saved_query_info_cb (GFile        *location,
         g_object_unref (info);
     }
 
-    g_get_current_time (&doc->priv->time_of_last_save_or_load);
-
-    doc->priv->externally_modified = FALSE;
-    doc->priv->deleted = FALSE;
-    doc->priv->create = FALSE;
+    g_get_current_time (&priv->time_of_last_save_or_load);
 
-    set_readonly (doc, FALSE);
-
-    gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), FALSE);
+    priv->create = FALSE;
 
     save_encoding_metadata (doc);
 
@@ -1113,14 +1206,18 @@ saved_query_info_cb (GFile        *location,
 static void
 xed_document_saved_real (XedDocument  *doc)
 {
-    GFile *location = gtk_source_file_get_location (doc->priv->file);
+    XedDocumentPrivate *priv;
+    GFile *location;
+
+    priv = xed_document_get_instance_private (doc);
+
+    location = gtk_source_file_get_location (priv->file);
 
     /* Keep the doc alive during the async operation. */
     g_object_ref (doc);
 
     g_file_query_info_async (location,
-                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
-                             G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                              G_FILE_QUERY_INFO_NONE,
                              G_PRIORITY_DEFAULT,
                              NULL,
@@ -1131,11 +1228,14 @@ xed_document_saved_real (XedDocument  *doc)
 gboolean
 xed_document_is_untouched (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
+    priv = xed_document_get_instance_private (doc);
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE);
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    location = gtk_source_file_get_location (priv->file);
 
     return location == NULL && !gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
 }
@@ -1143,107 +1243,37 @@ xed_document_is_untouched (XedDocument *doc)
 gboolean
 xed_document_is_untitled (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), TRUE);
 
-    return gtk_source_file_get_location (doc->priv->file) == NULL;
+    priv = xed_document_get_instance_private (doc);
+
+    return gtk_source_file_get_location (priv->file) == NULL;
 }
 
 gboolean
 xed_document_is_local (XedDocument *doc)
 {
-    GFile *location;
-
-    g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
-
-    location = gtk_source_file_get_location (doc->priv->file);
-
-    if (location == NULL)
-    {
-        return FALSE;
-    }
-
-    return g_file_has_uri_scheme (location, "file");
-}
-
-static void
-check_file_on_disk (XedDocument *doc)
-{
-    GFile *location;
-    GFileInfo *info;
-
-    location = gtk_source_file_get_location (doc->priv->file);
-
-    if (location == NULL)
-    {
-        return;
-    }
-
-    info = g_file_query_info (location,
-                              G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
-                              G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
-                              G_FILE_QUERY_INFO_NONE,
-                              NULL, NULL);
-
-    if (info != NULL)
-    {
-        /* While at it also check if permissions changed */
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
-        {
-            gboolean read_only;
-
-            read_only = !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
-
-            set_readonly (doc, read_only);
-        }
-
-        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) && doc->priv->mtime_set)
-        {
-            GTimeVal timeval;
-
-            g_file_info_get_modification_time (info, &timeval);
-
-            /* Note that mtime can even go backwards if the
-             * user is copying over a file with an old mtime
-             */
-            if (timeval.tv_sec != doc->priv->mtime.tv_sec ||
-                timeval.tv_usec != doc->priv->mtime.tv_usec)
-            {
-                doc->priv->externally_modified = TRUE;
-            }
-        }
-
-        g_object_unref (info);
-    }
-    else
-    {
-        doc->priv->deleted = TRUE;
-    }
-}
+    XedDocumentPrivate *priv;
 
-gboolean
-_xed_document_check_externally_modified (XedDocument *doc)
-{
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
 
-    if (!doc->priv->externally_modified)
-    {
-        check_file_on_disk (doc);
-    }
+    priv = xed_document_get_instance_private (doc);
 
-    return doc->priv->externally_modified;
+    return gtk_source_file_is_local (priv->file);
 }
 
 gboolean
 xed_document_get_deleted (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
 
-    if (!doc->priv->deleted)
-    {
-        check_file_on_disk (doc);
-    }
+    priv = xed_document_get_instance_private (doc);
 
-    return doc->priv->deleted;
+    return gtk_source_file_is_deleted (priv->file);
 }
 
 /*
@@ -1252,29 +1282,27 @@ xed_document_get_deleted (XedDocument *doc)
 gboolean
 _xed_document_needs_saving (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+    gboolean externally_modified = FALSE;
+    gboolean deleted = FALSE;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
 
+    priv = xed_document_get_instance_private (doc);
+
     if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
     {
         return TRUE;
     }
 
-    if (doc->priv->externally_modified || doc->priv->deleted)
+    if (gtk_source_file_is_local (priv->file))
     {
-        return TRUE;
+        gtk_source_file_check_file_on_disk (priv->file);
+        externally_modified = gtk_source_file_is_externally_modified (priv->file);
+        deleted = gtk_source_file_is_deleted (priv->file);
     }
 
-    if (xed_document_is_local (doc))
-    {
-        check_file_on_disk (doc);
-
-        if (doc->priv->externally_modified || doc->priv->deleted)
-        {
-        return TRUE;
-        }
-    }
-
-    return FALSE;
+    return (externally_modified || deleted) && !priv->create;
 }
 
 /*
@@ -1285,8 +1313,6 @@ gboolean
 xed_document_goto_line (XedDocument *doc,
                         gint         line)
 {
-    gboolean ret = TRUE;
-    guint line_count;
     GtkTextIter iter;
 
     xed_debug (DEBUG_DOCUMENT);
@@ -1294,21 +1320,11 @@ xed_document_goto_line (XedDocument *doc,
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
     g_return_val_if_fail (line >= -1, FALSE);
 
-    line_count = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc));
-
-    if (line >= line_count)
-    {
-        ret = FALSE;
-        gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter);
-    }
-    else
-    {
-        gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), &iter, line);
-    }
+    gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), &iter, line);
 
     gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
 
-    return ret;
+    return gtk_text_iter_get_line (&iter) == line;
 }
 
 gboolean
@@ -1316,29 +1332,17 @@ xed_document_goto_line_offset (XedDocument *doc,
                                gint         line,
                                gint         line_offset)
 {
-    gboolean ret = TRUE;
-    guint offset_count;
     GtkTextIter iter;
 
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
     g_return_val_if_fail (line >= -1, FALSE);
     g_return_val_if_fail (line_offset >= -1, FALSE);
 
-    gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc), &iter, line);
-
-    offset_count = gtk_text_iter_get_chars_in_line (&iter);
-    if (line_offset > offset_count)
-    {
-        ret = FALSE;
-    }
-    else
-    {
-        gtk_text_iter_set_line_offset (&iter, line_offset);
-    }
+    gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (doc), &iter, line, line_offset);
 
     gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
 
-    return ret;
+    return (gtk_text_iter_get_line (&iter) == line && gtk_text_iter_get_line_offset (&iter) == line_offset);
 }
 
 /**
@@ -1372,44 +1376,54 @@ xed_document_get_language (XedDocument *doc)
 const GtkSourceEncoding *
 xed_document_get_encoding (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
 
-    return gtk_source_file_get_encoding (doc->priv->file);
+    xed_document_get_instance_private (doc);
+
+    return gtk_source_file_get_encoding (priv->file);
 }
 
 glong
 _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
     GTimeVal current_time;
 
     xed_debug (DEBUG_DOCUMENT);
 
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), -1);
 
+    priv = xed_document_get_instance_private (doc);
+
     g_get_current_time (&current_time);
 
-    return (current_time.tv_sec - doc->priv->time_of_last_save_or_load.tv_sec);
+    return (current_time.tv_sec - priv->time_of_last_save_or_load.tv_sec);
 }
 
 GtkSourceNewlineType
 xed_document_get_newline_type (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), 0);
 
-    return gtk_source_file_get_newline_type (doc->priv->file);
+    priv = xed_document_get_instance_private (doc);
+
+    return gtk_source_file_get_newline_type (priv->file);
 }
 
-#ifndef ENABLE_GVFS_METADATA
-gchar *
-xed_document_get_metadata (XedDocument *doc,
-                           const gchar *key)
+static gchar *
+get_metadata_from_metadata_manager (XedDocument *doc,
+                                    const gchar *key)
 {
+    XedDocumentPrivate *priv;
     GFile *location;
 
-    g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
-    g_return_val_if_fail (key != NULL, NULL);
+    priv = xed_document_get_instance_private (doc);
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    location = gtk_source_file_get_location (priv->file);
 
     if (location != NULL)
     {
@@ -1419,41 +1433,42 @@ xed_document_get_metadata (XedDocument *doc,
     return NULL;
 }
 
-void
-xed_document_set_metadata (XedDocument *doc,
-                           const gchar *first_key,
-                           ...)
+static gchar *
+get_metadata_from_gvfs (XedDocument *doc,
+                        const gchar *key)
 {
-    GFile *location;
-    const gchar *key;
-    const gchar *value;
-    va_list var_args;
-
-    g_return_if_fail (XED_IS_DOCUMENT (doc));
-    g_return_if_fail (first_key != NULL);
+    XedDocumentPrivate *priv;
 
-    location = gtk_source_file_get_location (doc->priv->file);
+    priv = xed_document_get_instance_private (doc);
 
-    if (location == NULL)
+    if (priv->metadata_info != NULL &&
+        g_file_info_has_attribute (priv->metadata_info, key) &&
+        g_file_info_get_attribute_type (priv->metadata_info, key) == G_FILE_ATTRIBUTE_TYPE_STRING)
     {
-        /* Can't set metadata for untitled documents */
-        return;
+        return g_strdup (g_file_info_get_attribute_string (priv->metadata_info, key));
     }
 
-    va_start (var_args, first_key);
+    return NULL;
+}
 
-    for (key = first_key; key; key = va_arg (var_args, const gchar *))
-    {
-        value = va_arg (var_args, const gchar *);
+static void
+set_gvfs_metadata (GFileInfo   *info,
+                   const gchar *key,
+                   const gchar *value)
+{
+    g_return_if_fail (G_IS_FILE_INFO (info));
 
-        xed_metadata_manager_set (location, key, value);
+    if (value != NULL)
+    {
+        g_file_info_set_attribute_string (info, key, value);
+    }
+    else
+    {
+        /* Unset the key */
+        g_file_info_set_attribute (info, key, G_FILE_ATTRIBUTE_TYPE_INVALID, NULL);
     }
-
-    va_end (var_args);
 }
 
-#else
-
 /**
  * xed_document_get_metadata:
  * @doc: a #XedDocument
@@ -1467,15 +1482,19 @@ gchar *
 xed_document_get_metadata (XedDocument *doc,
                            const gchar *key)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
     g_return_val_if_fail (key != NULL, NULL);
 
-    if (doc->priv->metadata_info && g_file_info_has_attribute (doc->priv->metadata_info, key))
+    priv = xed_document_get_instance_private (doc);
+
+    if (priv->use_gvfs_metadata)
     {
-        return g_strdup (g_file_info_get_attribute_string (doc->priv->metadata_info, key));
+        return get_metadata_from_gvfs (doc, key);
     }
 
-    return NULL;
+    return get_metadata_from_metadata_manager (doc, key);
 }
 
 static void
@@ -1507,44 +1526,57 @@ xed_document_set_metadata (XedDocument *doc,
                            const gchar   *first_key,
                            ...)
 {
+    XedDocumentPrivate *priv;
+    GFile *location;
     const gchar *key;
-    const gchar *value;
     va_list var_args;
-    GFileInfo *info;
-    GFile *location;
+    GFileInfo *info = NULL;
 
     g_return_if_fail (XED_IS_DOCUMENT (doc));
     g_return_if_fail (first_key != NULL);
 
-    info = g_file_info_new ();
+    priv = xed_document_get_instance_private (doc);
+
+    location = gtk_source_file_get_location (priv->file);
+
+    /* With the metadata manager, can't set metadata for untitled documents.
+     * With GVFS metadata, if the location is NULL the metadata is stored in
+     * priv->metadata_info, so that it can be saved later if the document is
+     * saved.
+     */
+
+    if (!priv->use_gvfs_metadata && location == NULL)
+    {
+        return;
+    }
+
+    if (priv->use_gvfs_metadata)
+    {
+        info = g_file_info_new ();
+    }
 
     va_start (var_args, first_key);
 
     for (key = first_key; key; key = va_arg (var_args, const gchar *))
     {
-        value = va_arg (var_args, const gchar *);
+        const gchar *value = va_arg (var_args, const gchar *);
 
-        if (value != NULL)
+        if (priv->use_gvfs_metadata)
         {
-            g_file_info_set_attribute_string (info, key, value);
+            /* Collect the metadata into @info. */
+            set_gvfs_metadata (info, key, value);
+            set_gvfs_metadata (priv->metadata_info, key, value);
         }
         else
         {
             /* Unset the key */
-            g_file_info_remove_attribute (info, key);
+            xed_metadata_manager_set (location, key, value);
         }
     }
 
     va_end (var_args);
 
-    if (doc->priv->metadata_info != NULL)
-    {
-        g_file_info_copy_into (info, doc->priv->metadata_info);
-    }
-
-    location = gtk_source_file_get_location (doc->priv->file);
-
-    if (location != NULL)
+    if (priv->use_gvfs_metadata && location != NULL)
     {
         g_file_set_attributes_async (location,
                                      info,
@@ -1555,9 +1587,8 @@ xed_document_set_metadata (XedDocument *doc,
                                      NULL);
     }
 
-    g_object_unref (info);
+    g_clear_object (&info);
 }
-#endif
 
 /**
  * xed_document_set_search_context:
@@ -1570,19 +1601,23 @@ void
 xed_document_set_search_context (XedDocument            *doc,
                                  GtkSourceSearchContext *search_context)
 {
-   g_return_if_fail (XED_IS_DOCUMENT (doc));
+    XedDocumentPrivate *priv;
 
-   g_clear_object (&doc->priv->search_context);
-   doc->priv->search_context = search_context;
+    g_return_if_fail (XED_IS_DOCUMENT (doc));
+
+    priv = xed_document_get_instance_private (doc);
 
-   if (search_context != NULL)
-   {
-        gboolean highlight = g_settings_get_boolean (doc->priv->editor_settings, XED_SETTINGS_SEARCH_HIGHLIGHTING);
+    g_clear_object (&priv->search_context);
+    priv->search_context = search_context;
+
+    if (search_context != NULL)
+    {
+        gboolean highlight = g_settings_get_boolean (priv->editor_settings, XED_SETTINGS_SEARCH_HIGHLIGHTING);
 
         gtk_source_search_context_set_highlight (search_context, highlight);
 
         g_object_ref (search_context);
-   }
+    }
 }
 
 /**
@@ -1595,9 +1630,13 @@ xed_document_set_search_context (XedDocument            *doc,
 GtkSourceSearchContext *
 xed_document_get_search_context (XedDocument *doc)
 {
+    XedDocumentPrivate *priv;
+
     g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
 
-    return doc->priv->search_context;
+    priv = xed_document_get_instance_private (doc);
+
+    return priv->search_context;
 }
 
 /**
@@ -1618,24 +1657,36 @@ xed_document_get_search_context (XedDocument *doc)
 GtkSourceFile *
 xed_document_get_file (XedDocument *doc)
 {
-   g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
+    XedDocumentPrivate *priv;
+
+    g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL);
 
-   return doc->priv->file;
+    priv = xed_document_get_instance_private (doc);
+
+    return priv->file;
 }
 
 void
 _xed_document_set_create (XedDocument *doc,
                           gboolean     create)
 {
+    XedDocumentPrivate *priv;
+
     g_return_if_fail (XED_IS_DOCUMENT (doc));
 
-    doc->priv->create = create != FALSE;
+    priv = xed_document_get_instance_private (doc);
+
+    priv->create = create != FALSE;
 }
 
 gboolean
 _xed_document_get_create (XedDocument *doc)
 {
-   g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
+    XedDocumentPrivate *priv;
+
+    g_return_val_if_fail (XED_IS_DOCUMENT (doc), FALSE);
+
+    priv = xed_document_get_instance_private (doc);
 
-   return doc->priv->create;
+    return priv->create;
 }
diff --git a/xed/xed-document.h b/xed/xed-document.h
index f8bb270..a1fbf6d 100644
--- a/xed/xed-document.h
+++ b/xed/xed-document.h
@@ -37,29 +37,14 @@
 
 G_BEGIN_DECLS
 
-#define XED_TYPE_DOCUMENT              (xed_document_get_type())
-#define XED_DOCUMENT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT, XedDocument))
-#define XED_DOCUMENT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT, XedDocumentClass))
-#define XED_IS_DOCUMENT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT))
-#define XED_IS_DOCUMENT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT))
-#define XED_DOCUMENT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT, XedDocumentClass))
+#define XED_TYPE_DOCUMENT (xed_document_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (XedDocument, xed_document, XED, DOCUMENT, GtkSourceBuffer)
 
 #define XED_METADATA_ATTRIBUTE_POSITION "metadata::xed-position"
 #define XED_METADATA_ATTRIBUTE_ENCODING "metadata::xed-encoding"
 #define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language"
 
-typedef struct _XedDocument        XedDocument;
-typedef struct _XedDocumentPrivate XedDocumentPrivate;
-typedef struct _XedDocumentClass   XedDocumentClass;
-
-struct _XedDocument
-{
-    GtkSourceBuffer buffer;
-
-    /*< private > */
-    XedDocumentPrivate *priv;
-};
-
 struct _XedDocumentClass
 {
     GtkSourceBufferClass parent_class;
@@ -77,8 +62,6 @@ struct _XedDocumentClass
     void (* saved)          (XedDocument *document);
 };
 
-GType xed_document_get_type (void) G_GNUC_CONST;
-
 XedDocument *xed_document_new (void);
 
 GtkSourceFile *xed_document_get_file (XedDocument *doc);
@@ -138,24 +121,6 @@ void xed_document_set_search_context (XedDocument            *doc,
 
 GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
 
-/* Non exported functions */
-
-glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc);
-
-void _xed_document_apply_error_style (XedDocument *doc,
-                                      GtkTextIter *start,
-                                      GtkTextIter *end);
-
-/* Note: this is a sync stat: use only on local files */
-gboolean _xed_document_check_externally_modified (XedDocument *doc);
-
-gboolean _xed_document_needs_saving (XedDocument *doc);
-
-void _xed_document_set_create (XedDocument *doc,
-                               gboolean     create);
-
-gboolean _xed_document_get_create (XedDocument *doc);
-
 G_END_DECLS
 
 #endif /* __XED_DOCUMENT_H__ */
diff --git a/xed/xed-metadata-manager.c b/xed/xed-metadata-manager.c
index 01d491e..d92ff87 100644
--- a/xed/xed-metadata-manager.c
+++ b/xed/xed-metadata-manager.c
@@ -21,23 +21,15 @@
  * Boston, MA 02110-1301, USA.
  */
 
-/*
- * Modified by the xed Team, 2003-2007. See the AUTHORS file for a
- * list of people on the xed Team.
- * See the ChangeLog files for a list of changes.
- */
-
-#include <time.h>
-#include <stdlib.h>
 #include <libxml/xmlreader.h>
 #include "xed-metadata-manager.h"
 #include "xed-debug.h"
 
 /*
-#define XED_METADATA_VERBOSE_DEBUG	1
+#define XED_METADATA_VERBOSE_DEBUG  1
 */
 
-#define MAX_ITEMS	50
+#define MAX_ITEMS   50
 
 typedef struct _XedMetadataManager XedMetadataManager;
 
@@ -45,21 +37,21 @@ typedef struct _Item Item;
 
 struct _Item
 {
-	time_t	 	 atime; /* time of last access */
+    gint64       atime; /* time of last access in seconds since January 1, 1970 UTC */
 
-	GHashTable	*values;
+    GHashTable  *values;
 };
 
 struct _XedMetadataManager
 {
-	gboolean	 values_loaded; /* It is true if the file
-					   has been read */
+    gboolean     values_loaded; /* It is true if the file
+                       has been read */
 
-	guint 		 timeout_id;
+    guint        timeout_id;
 
-	GHashTable	*items;
+    GHashTable  *items;
 
-	gchar *metadata_filename;
+    gchar *metadata_filename;
 };
 
 static gboolean xed_metadata_manager_save (gpointer data);
@@ -70,34 +62,34 @@ static XedMetadataManager *xed_metadata_manager = NULL;
 static void
 item_free (gpointer data)
 {
-	Item *item;
+    Item *item;
 
-	g_return_if_fail (data != NULL);
+    g_return_if_fail (data != NULL);
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 #endif
 
-	item = (Item *)data;
+    item = (Item *)data;
 
-	if (item->values != NULL)
-		g_hash_table_destroy (item->values);
+    if (item->values != NULL)
+        g_hash_table_destroy (item->values);
 
-	g_free (item);
+    g_free (item);
 }
 
 static void
 xed_metadata_manager_arm_timeout (void)
 {
-	if (xed_metadata_manager->timeout_id == 0)
-	{
-		xed_metadata_manager->timeout_id =
-			g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
-						    2,
-						    (GSourceFunc)xed_metadata_manager_save,
-						    NULL,
-						    NULL);
-	}
+    if (xed_metadata_manager->timeout_id == 0)
+    {
+        xed_metadata_manager->timeout_id =
+            g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
+                            2,
+                            (GSourceFunc)xed_metadata_manager_save,
+                            NULL,
+                            NULL);
+    }
 }
 
 /**
@@ -110,22 +102,22 @@ xed_metadata_manager_arm_timeout (void)
 void
 xed_metadata_manager_init (const gchar *metadata_filename)
 {
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 
-	if (xed_metadata_manager != NULL)
-		return;
+    if (xed_metadata_manager != NULL)
+        return;
 
-	xed_metadata_manager = g_new0 (XedMetadataManager, 1);
+    xed_metadata_manager = g_new0 (XedMetadataManager, 1);
 
-	xed_metadata_manager->values_loaded = FALSE;
+    xed_metadata_manager->values_loaded = FALSE;
 
-	xed_metadata_manager->items =
-		g_hash_table_new_full (g_str_hash,
-				       g_str_equal,
-				       g_free,
-				       item_free);
+    xed_metadata_manager->items =
+        g_hash_table_new_full (g_str_hash,
+                       g_str_equal,
+                       g_free,
+                       item_free);
 
-	xed_metadata_manager->metadata_filename = g_strdup (metadata_filename);
+    xed_metadata_manager->metadata_filename = g_strdup (metadata_filename);
 
     return;
 }
@@ -139,154 +131,159 @@ xed_metadata_manager_init (const gchar *metadata_filename)
 void
 xed_metadata_manager_shutdown (void)
 {
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 
-	if (xed_metadata_manager == NULL)
-		return;
+    if (xed_metadata_manager == NULL)
+        return;
 
-	if (xed_metadata_manager->timeout_id)
-	{
-		g_source_remove (xed_metadata_manager->timeout_id);
-		xed_metadata_manager->timeout_id = 0;
-		xed_metadata_manager_save (NULL);
-	}
+    if (xed_metadata_manager->timeout_id)
+    {
+        g_source_remove (xed_metadata_manager->timeout_id);
+        xed_metadata_manager->timeout_id = 0;
+        xed_metadata_manager_save (NULL);
+    }
 
-	if (xed_metadata_manager->items != NULL)
-		g_hash_table_destroy (xed_metadata_manager->items);
+    if (xed_metadata_manager->items != NULL)
+        g_hash_table_destroy (xed_metadata_manager->items);
 
-    g_free (gedit_metadata_manager->metadata_filename);
-	g_free (xed_metadata_manager);
-	xed_metadata_manager = NULL;
+    g_free (xed_metadata_manager->metadata_filename);
+    g_free (xed_metadata_manager);
+    xed_metadata_manager = NULL;
 }
 
 static void
 parseItem (xmlDocPtr doc, xmlNodePtr cur)
 {
-	Item *item;
+    Item *item;
 
-	xmlChar *uri;
-	xmlChar *atime;
+    xmlChar *uri;
+    xmlChar *atime;
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 #endif
 
-	if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
-			return;
+    if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
+            return;
 
-	uri = xmlGetProp (cur, (const xmlChar *)"uri");
-	if (uri == NULL)
-		return;
+    uri = xmlGetProp (cur, (const xmlChar *)"uri");
+    if (uri == NULL)
+        return;
 
-	atime = xmlGetProp (cur, (const xmlChar *)"atime");
-	if (atime == NULL)
-	{
-		xmlFree (uri);
-		return;
-	}
+    atime = xmlGetProp (cur, (const xmlChar *)"atime");
+    if (atime == NULL)
+    {
+        xmlFree (uri);
+        return;
+    }
 
-	item = g_new0 (Item, 1);
+    item = g_new0 (Item, 1);
 
-	item->atime = g_ascii_strtoull ((char *)atime, NULL, 0);
+    item->atime = g_ascii_strtoll ((char *)atime, NULL, 0);
 
-	item->values = g_hash_table_new_full (g_str_hash,
-					      g_str_equal,
-					      g_free,
-					      g_free);
+    item->values = g_hash_table_new_full (g_str_hash,
+                          g_str_equal,
+                          g_free,
+                          g_free);
 
-	cur = cur->xmlChildrenNode;
+    cur = cur->xmlChildrenNode;
 
-	while (cur != NULL)
-	{
-		if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
-		{
-			xmlChar *key;
-			xmlChar *value;
+    while (cur != NULL)
+    {
+        if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
+        {
+            xmlChar *key;
+            xmlChar *value;
 
-			key = xmlGetProp (cur, (const xmlChar *)"key");
-			value = xmlGetProp (cur, (const xmlChar *)"value");
+            key = xmlGetProp (cur, (const xmlChar *)"key");
+            value = xmlGetProp (cur, (const xmlChar *)"value");
 
-			if ((key != NULL) && (value != NULL))
-				g_hash_table_insert (item->values,
-						     g_strdup ((gchar *)key),
-						     g_strdup ((gchar *)value));
+            if ((key != NULL) && (value != NULL))
+                g_hash_table_insert (item->values,
+                             g_strdup ((gchar *)key),
+                             g_strdup ((gchar *)value));
 
-			if (key != NULL)
-				xmlFree (key);
-			if (value != NULL)
-				xmlFree (value);
-		}
+            if (key != NULL)
+                xmlFree (key);
+            if (value != NULL)
+                xmlFree (value);
+        }
 
-		cur = cur->next;
-	}
+        cur = cur->next;
+    }
 
-	g_hash_table_insert (xed_metadata_manager->items,
-			     g_strdup ((gchar *)uri),
-			     item);
+    g_hash_table_insert (xed_metadata_manager->items,
+                 g_strdup ((gchar *)uri),
+                 item);
 
-	xmlFree (uri);
-	xmlFree (atime);
+    xmlFree (uri);
+    xmlFree (atime);
 }
 
 static gboolean
 load_values (void)
 {
-	xmlDocPtr doc;
-	xmlNodePtr cur;
+    xmlDocPtr doc;
+    xmlNodePtr cur;
 
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 
-	g_return_val_if_fail (xed_metadata_manager != NULL, FALSE);
-	g_return_val_if_fail (xed_metadata_manager->values_loaded == FALSE, FALSE);
+    g_return_val_if_fail (xed_metadata_manager != NULL, FALSE);
+    g_return_val_if_fail (xed_metadata_manager->values_loaded == FALSE, FALSE);
 
-	xed_metadata_manager->values_loaded = TRUE;
+    xed_metadata_manager->values_loaded = TRUE;
 
-	xmlKeepBlanksDefault (0);
+    xmlKeepBlanksDefault (0);
 
-	/* FIXME: file locking - Paolo */
-	if ((xed_metadata_manager->metadata_filename == NULL) ||
-        (!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS)))
-	{
-		return FALSE;
-	}
+    /* FIXME: file locking - Paolo */
+    if (xed_metadata_manager->metadata_filename == NULL)
+    {
+        return FALSE;
+    }
 
-	doc = xmlParseFile (xed_metadata_manager->metadata_filename);
+    /* TODO: avoid races */
+    if (!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS))
+    {
+        return TRUE;
+    }
 
-	if (doc == NULL)
-	{
-		return FALSE;
-	}
+    doc = xmlParseFile (xed_metadata_manager->metadata_filename);
 
-	cur = xmlDocGetRootElement (doc);
-	if (cur == NULL)
-	{
-		g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename));
-		xmlFreeDoc (doc);
+    if (doc == NULL)
+    {
+        return FALSE;
+    }
 
-		return FALSE;
-	}
+    cur = xmlDocGetRootElement (doc);
+    if (cur == NULL)
+    {
+        g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename));
+        xmlFreeDoc (doc);
 
-	if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
-	{
-		g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename));
-		xmlFreeDoc (doc);
+        return TRUE;
+    }
 
-		return FALSE;
-	}
+    if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
+    {
+        g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename));
+        xmlFreeDoc (doc);
 
-	cur = xmlDocGetRootElement (doc);
-	cur = cur->xmlChildrenNode;
+        return FALSE;
+    }
 
-	while (cur != NULL)
-	{
-		parseItem (doc, cur);
+    cur = xmlDocGetRootElement (doc);
+    cur = cur->xmlChildrenNode;
 
-		cur = cur->next;
-	}
+    while (cur != NULL)
+    {
+        parseItem (doc, cur);
 
-	xmlFreeDoc (doc);
+        cur = cur->next;
+    }
 
-	return TRUE;
+    xmlFreeDoc (doc);
+
+    return TRUE;
 }
 
 /**
@@ -298,48 +295,51 @@ load_values (void)
  */
 gchar *
 xed_metadata_manager_get (GFile *location,
-			    const gchar *key)
+                const gchar *key)
 {
-	Item *item;
-	gchar *value;
-	gchar *uri;
+    Item *item;
+    gchar *value;
+    gchar *uri;
 
-	g_return_val_if_fail (G_IS_FILE (location), NULL);
-	g_return_val_if_fail (key != NULL, NULL);
+    g_return_val_if_fail (G_IS_FILE (location), NULL);
+    g_return_val_if_fail (key != NULL, NULL);
 
-	uri = g_file_get_uri (location);
+    uri = g_file_get_uri (location);
 
-	xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
+    xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
 
-	if (!xed_metadata_manager->values_loaded)
-	{
-		gboolean res;
+    if (!xed_metadata_manager->values_loaded)
+    {
+        gboolean res;
 
-		res = load_values ();
+        res = load_values ();
 
-		if (!res)
-			return NULL;
-	}
+        if (!res)
+        {
+            g_free (uri);
+            return NULL;
+        }
+    }
 
-	item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
-					    uri);
+    item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
+                        uri);
 
-	g_free (uri);
+    g_free (uri);
 
-	if (item == NULL)
-		return NULL;
+    if (item == NULL)
+        return NULL;
 
-	item->atime = time (NULL);
+    item->atime = g_get_real_time () / 1000;
 
-	if (item->values == NULL)
-		return NULL;
+    if (item->values == NULL)
+        return NULL;
 
-	value = g_hash_table_lookup (item->values, key);
+    value = g_hash_table_lookup (item->values, key);
 
-	if (value == NULL)
-		return NULL;
-	else
-		return g_strdup (value);
+    if (value == NULL)
+        return NULL;
+    else
+        return g_strdup (value);
 }
 
 /**
@@ -352,219 +352,221 @@ xed_metadata_manager_get (GFile *location,
  */
 void
 xed_metadata_manager_set (GFile *location,
-			    const gchar *key,
-			    const gchar *value)
+                const gchar *key,
+                const gchar *value)
 {
-	Item *item;
-	gchar *uri;
+    Item *item;
+    gchar *uri;
 
-	g_return_if_fail (G_IS_FILE (location));
-	g_return_if_fail (key != NULL);
+    g_return_if_fail (G_IS_FILE (location));
+    g_return_if_fail (key != NULL);
 
-	uri = g_file_get_uri (location);
+    uri = g_file_get_uri (location);
 
-	xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
+    xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
 
-	if (!xed_metadata_manager->values_loaded)
-	{
-		gboolean res;
+    if (!xed_metadata_manager->values_loaded)
+    {
+        gboolean ok;
 
-		res = load_values ();
+        ok = load_values ();
 
-		if (!res)
-			return;
-	}
+        if (!ok)
+        {
+            g_free (uri);
+            return;
+        }
+    }
 
-	item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
-					    uri);
+    item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
+                        uri);
 
-	if (item == NULL)
-	{
-		item = g_new0 (Item, 1);
+    if (item == NULL)
+    {
+        item = g_new0 (Item, 1);
 
-		g_hash_table_insert (xed_metadata_manager->items,
-				     g_strdup (uri),
-				     item);
-	}
+        g_hash_table_insert (xed_metadata_manager->items,
+                     g_strdup (uri),
+                     item);
+    }
 
-	if (item->values == NULL)
-		 item->values = g_hash_table_new_full (g_str_hash,
-				 		       g_str_equal,
-						       g_free,
-						       g_free);
-	if (value != NULL)
-		g_hash_table_insert (item->values,
-				     g_strdup (key),
-				     g_strdup (value));
-	else
-		g_hash_table_remove (item->values,
-				     key);
+    if (item->values == NULL)
+         item->values = g_hash_table_new_full (g_str_hash,
+                               g_str_equal,
+                               g_free,
+                               g_free);
+    if (value != NULL)
+        g_hash_table_insert (item->values,
+                     g_strdup (key),
+                     g_strdup (value));
+    else
+        g_hash_table_remove (item->values,
+                     key);
 
-	item->atime = time (NULL);
+    item->atime = g_get_real_time () / 1000;
 
-	g_free (uri);
+    g_free (uri);
 
-	xed_metadata_manager_arm_timeout ();
+    xed_metadata_manager_arm_timeout ();
 }
 
 static void
 save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
 {
-	xmlNodePtr xml_node;
+    xmlNodePtr xml_node;
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 #endif
 
-	g_return_if_fail (key != NULL);
+    g_return_if_fail (key != NULL);
 
-	if (value == NULL)
-		return;
+    if (value == NULL)
+        return;
 
-	xml_node = xmlNewChild (parent,
-				NULL,
-				(const xmlChar *)"entry",
-				NULL);
+    xml_node = xmlNewChild (parent,
+                NULL,
+                (const xmlChar *)"entry",
+                NULL);
 
-	xmlSetProp (xml_node,
-		    (const xmlChar *)"key",
-		    (const xmlChar *)key);
-	xmlSetProp (xml_node,
-		    (const xmlChar *)"value",
-		    (const xmlChar *)value);
+    xmlSetProp (xml_node,
+            (const xmlChar *)"key",
+            (const xmlChar *)key);
+    xmlSetProp (xml_node,
+            (const xmlChar *)"value",
+            (const xmlChar *)value);
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
+    xed_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
 #endif
 }
 
 static void
 save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
 {
-	xmlNodePtr xml_node;
-	const Item *item = (const Item *)data;
-	gchar *atime;
+    xmlNodePtr xml_node;
+    const Item *item = (const Item *)data;
+    gchar *atime;
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 #endif
 
-	g_return_if_fail (key != NULL);
+    g_return_if_fail (key != NULL);
 
-	if (item == NULL)
-		return;
+    if (item == NULL)
+        return;
 
-	xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
+    xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
 
-	xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
+    xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug_message (DEBUG_METADATA, "uri: %s", key);
+    xed_debug_message (DEBUG_METADATA, "uri: %s", key);
 #endif
 
-	atime = g_strdup_printf ("%ld", item->atime);
-	xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
+    atime = g_strdup_printf ("%" G_GINT64_FORMAT, item->atime);
+    xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
 
 #ifdef XED_METADATA_VERBOSE_DEBUG
-	xed_debug_message (DEBUG_METADATA, "atime: %s", atime);
+    xed_debug_message (DEBUG_METADATA, "atime: %s", atime);
 #endif
 
-	g_free (atime);
+    g_free (atime);
 
-    	g_hash_table_foreach (item->values,
-			      (GHFunc)save_values,
-			      xml_node);
+        g_hash_table_foreach (item->values,
+                  (GHFunc)save_values,
+                  xml_node);
 }
 
 static void
 get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove)
 {
-	const Item *item = (const Item *)value;
-
-	if (*key_to_remove == NULL)
-	{
-		*key_to_remove = key;
-	}
-	else
-	{
-		const Item *item_to_remove =
-			g_hash_table_lookup (xed_metadata_manager->items,
-					     *key_to_remove);
-
-		g_return_if_fail (item_to_remove != NULL);
-
-		if (item->atime < item_to_remove->atime)
-		{
-			*key_to_remove = key;
-		}
-	}
+    const Item *item = (const Item *)value;
+
+    if (*key_to_remove == NULL)
+    {
+        *key_to_remove = key;
+    }
+    else
+    {
+        const Item *item_to_remove =
+            g_hash_table_lookup (xed_metadata_manager->items,
+                         *key_to_remove);
+
+        g_return_if_fail (item_to_remove != NULL);
+
+        if (item->atime < item_to_remove->atime)
+        {
+            *key_to_remove = key;
+        }
+    }
 }
 
 static void
 resize_items (void)
 {
-	while (g_hash_table_size (xed_metadata_manager->items) > MAX_ITEMS)
-	{
-		gpointer key_to_remove = NULL;
+    while (g_hash_table_size (xed_metadata_manager->items) > MAX_ITEMS)
+    {
+        gpointer key_to_remove = NULL;
 
-		g_hash_table_foreach (xed_metadata_manager->items,
-				      (GHFunc)get_oldest,
-				      &key_to_remove);
+        g_hash_table_foreach (xed_metadata_manager->items,
+                      (GHFunc)get_oldest,
+                      &key_to_remove);
 
-		g_return_if_fail (key_to_remove != NULL);
+        g_return_if_fail (key_to_remove != NULL);
 
-		g_hash_table_remove (xed_metadata_manager->items,
-				     key_to_remove);
-	}
+        g_hash_table_remove (xed_metadata_manager->items,
+                     key_to_remove);
+    }
 }
 
 static gboolean
 xed_metadata_manager_save (gpointer data)
 {
-	xmlDocPtr  doc;
-	xmlNodePtr root;
+    xmlDocPtr  doc;
+    xmlNodePtr root;
 
-	xed_debug (DEBUG_METADATA);
+    xed_debug (DEBUG_METADATA);
 
-	xed_metadata_manager->timeout_id = 0;
+    xed_metadata_manager->timeout_id = 0;
 
-	resize_items ();
+    resize_items ();
 
-	xmlIndentTreeOutput = TRUE;
+    xmlIndentTreeOutput = TRUE;
 
-	doc = xmlNewDoc ((const xmlChar *)"1.0");
-	if (doc == NULL)
-		return TRUE;
+    doc = xmlNewDoc ((const xmlChar *)"1.0");
+    if (doc == NULL)
+        return TRUE;
 
-	/* Create metadata root */
-	root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
-	xmlDocSetRootElement (doc, root);
+    /* Create metadata root */
+    root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
+    xmlDocSetRootElement (doc, root);
 
-    	g_hash_table_foreach (xed_metadata_manager->items,
-			      (GHFunc)save_item,
-			      root);
+        g_hash_table_foreach (xed_metadata_manager->items,
+                  (GHFunc)save_item,
+                  root);
 
-	/* FIXME: lock file - Paolo */
-	if (xed_metadata_manager->metadata_filename != NULL)
-	{
-		gchar *cache_dir;
-		int res;
+    /* FIXME: lock file - Paolo */
+    if (xed_metadata_manager->metadata_filename != NULL)
+    {
+        gchar *cache_dir;
+        int res;
 
-		/* make sure the cache dir exists */
-		cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename);
-		res = g_mkdir_with_parents (cache_dir, 0755);
-		if (res != -1)
-		{
-			xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
-		}
+        /* make sure the cache dir exists */
+        cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename);
+        res = g_mkdir_with_parents (cache_dir, 0755);
+        if (res != -1)
+        {
+            xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
+        }
 
-		g_free (cache_dir);
-	}
+        g_free (cache_dir);
+    }
 
-	xmlFreeDoc (doc);
+    xmlFreeDoc (doc);
 
-	xed_debug_message (DEBUG_METADATA, "DONE");
+    xed_debug_message (DEBUG_METADATA, "DONE");
 
-	return FALSE;
+    return FALSE;
 }
-
diff --git a/xed/xed-metadata-manager.h b/xed/xed-metadata-manager.h
index dd682f7..c794a2a 100644
--- a/xed/xed-metadata-manager.h
+++ b/xed/xed-metadata-manager.h
@@ -30,7 +30,7 @@
 #ifndef __XED_METADATA_MANAGER_H__
 #define __XED_METADATA_MANAGER_H__
 
-#include <glib.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
diff --git a/xed/xed-tab.c b/xed/xed-tab.c
index 5c89645..7dc4986 100644
--- a/xed/xed-tab.c
+++ b/xed/xed-tab.c
@@ -43,6 +43,8 @@
 #include "xed-print-preview.h"
 #include "xed-progress-info-bar.h"
 #include "xed-debug.h"
+#include "xed-document.h"
+#include "xed-document-private.h"
 #include "xed-enum-types.h"
 #include "xed-settings.h"
 #include "xed-view-frame.h"
@@ -1112,39 +1114,39 @@ view_focused_in (GtkWidget     *widget,
                  XedTab        *tab)
 {
     XedDocument *doc;
+    GtkSourceFile *file;
 
     g_return_val_if_fail (XED_IS_TAB (tab), FALSE);
 
     /* we try to detect file changes only in the normal state */
     if (tab->priv->state != XED_TAB_STATE_NORMAL)
     {
-        return FALSE;
+        return GDK_EVENT_PROPAGATE;
     }
 
     /* we already asked, don't bug the user again */
     if (!tab->priv->ask_if_externally_modified)
     {
-        return FALSE;
+        return GDK_EVENT_PROPAGATE;
     }
 
     doc = xed_tab_get_document (tab);
+    file = xed_document_get_file (doc);
 
     /* If file was never saved or is remote we do not check */
-    if (!xed_document_is_local (doc))
+    if (gtk_source_file_is_local (file))
     {
-        return FALSE;
-    }
+        gtk_source_file_check_file_on_disk (file);
 
-    if (_xed_document_check_externally_modified (doc))
-    {
-        xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
-
-        display_externally_modified_notification (tab);
+        if (gtk_source_file_is_externally_modified (file))
+        {
+            xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
 
-        return FALSE;
+            display_externally_modified_notification (tab);
+        }
     }
 
-    return FALSE;
+    return GDK_EVENT_PROPAGATE;
 }
 
 static void
diff --git a/xed/xed-window.c b/xed/xed-window.c
index 9d8e369..7227c1a 100644
--- a/xed/xed-window.c
+++ b/xed/xed-window.c
@@ -20,6 +20,8 @@
 #include "xed-utils.h"
 #include "xed-commands.h"
 #include "xed-debug.h"
+#include "xed-document.h"
+#include "xed-document-private.h"
 #include "xed-panel.h"
 #include "xed-documents-panel.h"
 #include "xed-plugins-engine.h"

From e7a6ea452e7df8e832d0e320676b465f0d84c30a Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 00:25:34 -0800
Subject: [PATCH 02/14] preferences-dialog: Complete revamp

Use the new XApps preferences window as the base for a total redesign of the
new dialog. While at it port to GtkSourceStyleSchemeChooserWidget.
---
 configure.ac                               |    1 +
 debian/control                             |    3 +-
 xed/resources/ui/xed-preferences-dialog.ui | 1579 ++++++++++++----------------
 xed/xed-preferences-dialog.c               | 1018 +++++++-----------
 xed/xed-preferences-dialog.h               |   59 +-
 5 files changed, 1071 insertions(+), 1589 deletions(-)

diff --git a/configure.ac b/configure.ac
index 90d461b..aaf0017 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,6 +153,7 @@ PKG_CHECK_MODULES(XED, [
 	gtksourceview-3.0 >= 3.19.0
 	libpeas-1.0 >= 1.12.0
 	libpeas-gtk-1.0 >= 1.12.0
+    xapp
 ])
 
 PKG_CHECK_MODULES(X11, [x11])
diff --git a/debian/control b/debian/control
index b7544aa..493e733 100644
--- a/debian/control
+++ b/debian/control
@@ -14,6 +14,7 @@ Build-Depends: autotools-dev,
                libgtk-3-dev,
                libgtksourceview-3.0-dev,
                libpeas-dev,
+               libxapp-dev,
                libsm-dev,
                libx11-dev,
                libxml2-dev,
@@ -145,4 +146,4 @@ Description: Text editor (documentation files)
  includes support for spell checking, comparing files, viewing CVS
  ChangeLogs, and adjusting indentation levels.
  .
- This package contains the documentation files.
\ No newline at end of file
+ This package contains the documentation files.
diff --git a/xed/resources/ui/xed-preferences-dialog.ui b/xed/resources/ui/xed-preferences-dialog.ui
index 5975d36..00bf20d 100755
--- a/xed/resources/ui/xed-preferences-dialog.ui
+++ b/xed/resources/ui/xed-preferences-dialog.ui
@@ -1,566 +1,375 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Generated with glade 3.18.3 -->
 <interface>
-  <requires lib="gtk+" version="3.0"/>
+  <requires lib="gtk+" version="3.12"/>
+  <requires lib="gtksourceview" version="3.0"/>
   <object class="GtkAdjustment" id="adjustment1">
-    <property name="lower">1</property>
-    <property name="upper">160</property>
-    <property name="value">80</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="adjustment2">
     <property name="lower">1</property>
     <property name="upper">24</property>
-    <property name="value">8</property>
+    <property name="value">4</property>
     <property name="step_increment">1</property>
     <property name="page_increment">4</property>
   </object>
-  <object class="GtkAdjustment" id="adjustment3">
+  <object class="GtkAdjustment" id="adjustment2">
     <property name="lower">1</property>
-    <property name="upper">100</property>
-    <property name="value">8</property>
+    <property name="upper">160</property>
+    <property name="value">120</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkImage" id="install_scheme_image">
-    <property name="can_focus">False</property>
-    <property name="stock">gtk-add</property>
-  </object>
-  <object class="GtkDialog" id="preferences_dialog">
+  <object class="GtkBox" id="editor_page">
+    <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="title" translatable="yes">Preferences</property>
-    <property name="resizable">False</property>
-    <property name="destroy_with_parent">True</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkBox" id="dialog-vbox">
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolledwindow1">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox" id="dialog-action_area">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="helpbutton1">
-                <property name="label">gtk-help</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>
-            <child>
-              <object class="GtkButton" id="closebutton1">
-                <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">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
+        <property name="can_focus">True</property>
+        <property name="hscrollbar_policy">never</property>
         <child>
-          <object class="GtkNotebook" id="notebook">
+          <object class="GtkViewport" id="viewport1">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="border_width">6</property>
+            <property name="can_focus">False</property>
             <child>
-              <object class="GtkVBox" id="vbox228">
+              <object class="GtkBox" id="box">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="border_width">12</property>
-                <property name="spacing">18</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkVBox" id="vbox226">
+                  <object class="GtkLabel" id="label7">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label848">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Text Wrapping</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
+                    <property name="label" translatable="yes">Font</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box12">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkHBox" id="hbox142">
+                      <object class="GtkBox" id="box13">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label849">
+                          <object class="GtkLabel" id="fixed_width_font_label">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Use the system fixed width font (%s)</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="wrap_mode_frame">
+                          <object class="GtkSwitch" id="fixed_width_font_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="wrap_text_checkbutton">
-                                <property name="label" translatable="yes">Enable text _wrapping</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="xalign">0.5</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="GtkCheckButton" id="split_checkbutton">
-                                <property name="label" translatable="yes">Do not _split words over two lines</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="xalign">0.5</property>
-                                <property name="draw_indicator">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRevealer" id="font_button_revealer">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="transition_duration">175</property>
+                        <property name="reveal_child">True</property>
+                        <child>
+                          <object class="GtkFontButton" id="font_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="margin_top">6</property>
+                            <property name="font">Sans 12</property>
+                            <property name="preview_text"/>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
                         <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
+                    <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">0</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox217">
+                  <object class="GtkLabel" id="label8">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label854">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Line Numbers</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
+                    <property name="label" translatable="yes">Display</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkHBox" id="hbox137">
+                      <object class="GtkBox" id="box18">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label843">
+                          <object class="GtkLabel" id="label9">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Display line numbers</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox222">
+                          <object class="GtkSwitch" id="display_line_numbers_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="display_line_numbers_checkbutton">
-                                <property name="label" translatable="yes">_Display line numbers</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="xalign">0.5</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>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox244">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label876">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Current Line</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHBox" id="hbox161">
+                      <object class="GtkBox" id="box8">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_top">6</property>
                         <child>
-                          <object class="GtkLabel" id="label877">
+                          <object class="GtkLabel" id="label6">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Display overview map</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox245">
+                          <object class="GtkSwitch" id="minimap_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="highlight_current_line_checkbutton">
-                                <property name="label" translatable="yes">Highlight current _line</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="xalign">0.5</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>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
+                        <property name="expand">False</property>
                         <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox230">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label855">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Right Margin</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
                     <child>
-                      <object class="GtkHBox" id="hbox145">
+                      <object class="GtkBox" id="box10">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_top">6</property>
                         <child>
-                          <object class="GtkLabel" id="label856">
+                          <object class="GtkLabel" id="label2">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Display right margin</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox231">
+                          <object class="GtkSwitch" id="display_right_margin_switch">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRevealer" id="right_margin_revealer">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="transition_duration">175</property>
+                        <child>
+                          <object class="GtkBox" id="box11">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
+                            <property name="margin_top">6</property>
                             <child>
-                              <object class="GtkCheckButton" id="right_margin_checkbutton">
-                                <property name="label" translatable="yes">Display right _margin</property>
+                              <object class="GtkLabel" id="label10">
                                 <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="xalign">0.5</property>
-                                <property name="draw_indicator">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Right margin at column</property>
+                                <property name="xalign">0</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
-                                <property name="fill">False</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="right_margin_position_hbox">
+                              <object class="GtkSpinButton" id="right_margin_spin">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkLabel" id="label857">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">_Right margin at column:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">right_margin_position_spinbutton</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinButton" id="right_margin_position_spinbutton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment1</property>
-                                    <property name="climb_rate">1</property>
-                                    <property name="snap_to_ticks">True</property>
-                                    <property name="numeric">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
+                                <property name="can_focus">True</property>
+                                <property name="text" translatable="yes">4</property>
+                                <property name="adjustment">adjustment2</property>
+                                <property name="value">4</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
-                                <property name="fill">False</property>
+                                <property name="fill">True</property>
+                                <property name="pack_type">end</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
+                        <property name="expand">False</property>
                         <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">False</property>
+                    <property name="fill">True</property>
                     <property name="position">3</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox249">
+                  <object class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Highlighting</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box7">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkLabel" id="label881">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Bracket Matching</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox163">
+                      <object class="GtkBox" id="box4">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label882">
+                          <object class="GtkLabel" id="label11">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Highlight the current line</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox250">
+                          <object class="GtkSwitch" id="highlight_current_line_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="bracket_matching_checkbutton">
-                                <property name="label" translatable="yes">Highlight matching _bracket</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="xalign">0.5</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>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox" id="box3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label3">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Overview Map</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
                       <packing>
                         <property name="expand">False</property>
                         <property name="fill">True</property>
@@ -568,14 +377,34 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="mini_map_checkbutton">
-                        <property name="label" translatable="yes">Display overview map</property>
+                      <object class="GtkBox" id="box5">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="margin_left">12</property>
-                        <property name="xalign">0</property>
-                        <property name="draw_indicator">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkLabel" id="label1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Highlight matching brackets</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSwitch" id="highlight_matching_bracket_switch">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -585,341 +414,253 @@
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
+                    <property name="expand">False</property>
                     <property name="fill">True</property>
                     <property name="position">5</property>
                   </packing>
                 </child>
-              </object>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label853">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">View</property>
-              </object>
-              <packing>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkVBox" id="vbox224">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="border_width">12</property>
-                <property name="spacing">18</property>
                 <child>
-                  <object class="GtkVBox" id="vbox225">
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Indentation</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box6">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkLabel" id="label846">
+                      <object class="GtkBox" id="box1">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Tab Stops</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
+                        <child>
+                          <object class="GtkLabel" id="label5">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Tab width</property>
+                            <property name="xalign">0</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSpinButton" id="tab_width_spin">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="adjustment">adjustment1</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHBox" id="hbox141">
+                      <object class="GtkBox" id="box2">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label847">
+                          <object class="GtkLabel" id="label15">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Use spaces instead of tabs</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox205">
+                          <object class="GtkSwitch" id="use_spaces_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkHBox" id="tabs_width_hbox">
-                                <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkLabel" id="label98">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">_Tab width:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="justify">center</property>
-                                    <property name="mnemonic_widget">tabs_width_spinbutton</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinButton" id="tabs_width_spinbutton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment2</property>
-                                    <property name="climb_rate">1</property>
-                                    <property name="numeric">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="expand">True</property>
-                                <property name="fill">True</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="insert_spaces_checkbutton">
-                                <property name="label" translatable="yes">Insert _spaces instead of tabs</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="xalign">0.5</property>
-                                <property name="draw_indicator">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">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>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox227">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label851">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Automatic Indentation</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
                     <child>
-                      <object class="GtkHBox" id="hbox143">
+                      <object class="GtkBox" id="box9">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label852">
+                          <object class="GtkLabel" id="label16">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Automatic indentation</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkCheckButton" id="auto_indent_checkbutton">
-                            <property name="label" translatable="yes">_Enable automatic indentation</property>
+                          <object class="GtkSwitch" id="automatic_indentation_switch">
                             <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="xalign">0.5</property>
-                            <property name="draw_indicator">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
+                    <property name="fill">True</property>
+                    <property name="position">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Word wrap</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">8</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox232">
+                  <object class="GtkBox" id="box14">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkLabel" id="label859">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">File Saving</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox147">
+                      <object class="GtkBox" id="box15">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label860">
+                          <object class="GtkLabel" id="word_wrap_label">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Word wrap</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox187">
+                          <object class="GtkSwitch" id="word_wrap_switch">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRevealer" id="split_words_revealer">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="transition_duration">175</property>
+                        <property name="reveal_child">True</property>
+                        <child>
+                          <object class="GtkBox" id="box16">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
                             <child>
-                              <object class="GtkCheckButton" id="backup_copy_checkbutton">
-                                <property name="label" translatable="yes">Create a _backup copy of files before saving</property>
+                              <object class="GtkLabel" id="split_words_label">
                                 <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="xalign">0.5</property>
-                                <property name="draw_indicator">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Split words over two lines</property>
+                                <property name="xalign">0</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
-                                <property name="fill">False</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="autosave_hbox">
+                              <object class="GtkSwitch" id="split_words_switch">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkCheckButton" id="auto_save_checkbutton">
-                                    <property name="label" translatable="yes">_Autosave files every</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="xalign">0.5</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="GtkSpinButton" id="auto_save_spinbutton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">adjustment3</property>
-                                    <property name="climb_rate">1</property>
-                                    <property name="numeric">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="label97">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">_minutes</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="justify">center</property>
-                                    <property name="mnemonic_widget">auto_save_spinbutton</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
+                                <property name="can_focus">True</property>
                               </object>
                               <packing>
-                                <property name="expand">True</property>
+                                <property name="expand">False</property>
                                 <property name="fill">True</property>
+                                <property name="pack_type">end</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
+                        <property name="expand">False</property>
                         <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
@@ -927,418 +668,484 @@
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
+                    <property name="fill">True</property>
+                    <property name="position">9</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="box1">
+                  <object class="GtkLabel" id="label13">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">6</property>
+                    <property name="label" translatable="yes">Tab scrolling</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">10</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box17">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
                     <child>
-                      <object class="GtkLabel" id="label1">
+                      <object class="GtkLabel" id="tab_scrolling_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Tab Scrolling</property>
+                        <property name="label" translatable="yes">Allow mouse wheel scrolling to change tabs</property>
                         <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkBox" id="box2">
+                      <object class="GtkSwitch" id="tab_scrolling_switch">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <child>
-                          <object class="GtkLabel" id="label2">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkCheckButton" id="tab_scrolling_checkbutton">
-                            <property name="label" translatable="yes">Allow mouse wheel scrolling to change tabs</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="xalign">0</property>
-                            <property name="draw_indicator">True</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="can_focus">True</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
+                        <property name="pack_type">end</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
+                    <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">3</property>
+                    <property name="position">11</property>
                   </packing>
                 </child>
               </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label829">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Editor</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
-              </packing>
             </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkAdjustment" id="adjustment3">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkBox" id="save_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolledwindow2">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hscrollbar_policy">never</property>
+        <child>
+          <object class="GtkViewport" id="viewport2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <child>
-              <object class="GtkVBox" id="vbox202">
+              <object class="GtkBox" id="box19">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="border_width">12</property>
-                <property name="spacing">18</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="label14">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">File saving</property>
+                    <property name="xalign">0</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.1000000000000001"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
                 <child>
-                  <object class="GtkVBox" id="vbox185">
+                  <object class="GtkBox" id="box20">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="margin_left">32</property>
+                    <property name="margin_right">32</property>
+                    <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkLabel" id="label819">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Font</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox116">
+                      <object class="GtkBox" id="box21">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label800">
+                          <object class="GtkLabel" id="label17">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Create a backup copy of files before saving</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox183">
+                          <object class="GtkSwitch" id="backup_copy_switch">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <object class="GtkCheckButton" id="default_font_checkbutton">
-                                <property name="label">_Use the system fixed width font (%s)</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="xalign">0.5</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="GtkHBox" id="font_hbox">
-                                <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">12</property>
-                                <child>
-                                  <object class="GtkLabel" id="font_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">Editor _font: </property>
-                                    <property name="use_underline">True</property>
-                                    <property name="justify">center</property>
-                                    <property name="mnemonic_widget">font_button</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkFontButton" id="font_button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="font">Sans 12</property>
-                                    <property name="title" translatable="yes">Pick the editor font</property>
-                                    <property name="use_font">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">True</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
+                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                       </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox14">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label798">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Color Scheme</property>
-                        <property name="xalign">0</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkCheckButton" id="prefer_dark_theme_checkbutton">
-                        <property name="label" translatable="yes">Use dark theme variant (if available)</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="margin_left">12</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">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="hbox115">
+                      <object class="GtkBox" id="box22">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkLabel" id="label797">
+                          <object class="GtkLabel" id="label18">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">    </property>
+                            <property name="label" translatable="yes">Autosave files</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
-                            <property name="fill">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkVBox" id="vbox1">
+                          <object class="GtkSwitch" id="auto_save_switch">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRevealer" id="auto_save_revealer">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="transition_duration">175</property>
+                        <property name="reveal_child">True</property>
+                        <child>
+                          <object class="GtkBox" id="box23">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="spacing">6</property>
                             <child>
-                              <object class="GtkScrolledWindow" id="scrolledwindow2">
+                              <object class="GtkLabel" id="label19">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="shadow_type">etched-in</property>
-                                <child>
-                                  <object class="GtkTreeView" id="schemes_treeview">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="headers_visible">False</property>
-                                    <property name="rules_hint">True</property>
-                                    <child internal-child="selection">
-                                      <object class="GtkTreeSelection" id="treeview-selection1"/>
-                                    </child>
-                                  </object>
-                                </child>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Minutes between saving</property>
+                                <property name="xalign">0</property>
                               </object>
                               <packing>
-                                <property name="expand">True</property>
+                                <property name="expand">False</property>
                                 <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHButtonBox" id="hbuttonbox1">
+                              <object class="GtkSpinButton" id="auto_save_spin">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">6</property>
-                                <property name="layout_style">end</property>
-                                <child>
-                                  <object class="GtkButton" id="install_scheme_button">
-                                    <property name="label" translatable="yes">_Add...</property>
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="image">install_scheme_image</property>
-                                    <property name="use_underline">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="uninstall_scheme_button">
-                                    <property name="label">gtk-remove</property>
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">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">1</property>
-                                  </packing>
-                                </child>
+                                <property name="can_focus">True</property>
+                                <property name="adjustment">adjustment3</property>
+                                <property name="climb_rate">1</property>
+                                <property name="numeric">True</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
                                 <property name="fill">True</property>
+                                <property name="pack_type">end</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
+                        <property name="expand">False</property>
                         <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
+                    <property name="expand">False</property>
                     <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkBox" id="plugins_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkBox" id="plugin_manager_place_holder">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkBox" id="theme_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkBox" id="box24">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="label21">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Dark theme</property>
+            <property name="xalign">0</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+              <attribute name="scale" value="1.1000000000000001"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box25">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">32</property>
+            <property name="margin_right">32</property>
+            <child>
+              <object class="GtkLabel" id="label20">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Use dark theme variant (if available)</property>
+                <property name="xalign">0</property>
               </object>
               <packing>
-                <property name="position">2</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label830">
+            <child>
+              <object class="GtkSwitch" id="prefer_dark_theme_switch">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Font &amp; Colors</property>
+                <property name="can_focus">True</property>
               </object>
               <packing>
-                <property name="position">2</property>
-                <property name="tab_fill">False</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
               </packing>
             </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label22">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Style scheme</property>
+            <property name="xalign">0</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+              <attribute name="scale" value="1.1000000000000001"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box26">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">32</property>
+            <property name="margin_right">32</property>
+            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkVBox" id="plugin_manager_place_holder">
+              <object class="GtkScrolledWindow" id="scrolledwindow4">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="border_width">12</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
                 <child>
-                  <placeholder/>
+                  <object class="GtkViewport" id="viewport4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkSourceStyleSchemeChooserWidget" id="schemes_list">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                      </object>
+                    </child>
+                  </object>
                 </child>
               </object>
               <packing>
-                <property name="position">3</property>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label868">
+            <child>
+              <object class="GtkBox" id="box27">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Plugins</property>
+                <child>
+                  <object class="GtkBox" id="box28">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="border_width">6</property>
+                    <child>
+                      <object class="GtkButton" id="install_scheme_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="tooltip_text" translatable="yes">Install scheme</property>
+                        <child>
+                          <object class="GtkImage" id="image1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">list-add-symbolic</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="uninstall_scheme_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="tooltip_text" translatable="yes">Remove scheme</property>
+                        <child>
+                          <object class="GtkImage" id="image2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">list-remove-symbolic</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</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>
+                <style>
+                  <class name="inline-toolbar"/>
+                </style>
               </object>
               <packing>
-                <property name="position">3</property>
-                <property name="tab_fill">False</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
+            <property name="expand">True</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
     </child>
-    <action-widgets>
-      <action-widget response="-11">helpbutton1</action-widget>
-      <action-widget response="-7">closebutton1</action-widget>
-    </action-widgets>
   </object>
 </interface>
diff --git a/xed/xed-preferences-dialog.c b/xed/xed-preferences-dialog.c
index 2e3ad43..32faf6f 100755
--- a/xed/xed-preferences-dialog.c
+++ b/xed/xed-preferences-dialog.c
@@ -62,95 +62,86 @@
 
 static GtkWidget *preferences_dialog = NULL;
 
-enum
-{
-    ID_COLUMN = 0,
-    NAME_COLUMN,
-    DESC_COLUMN,
-    NUM_COLUMNS
-};
-
+#define XED_TYPE_PREFERENCES_DIALOG (xed_preferences_dialog_get_type ())
 
-#define XED_PREFERENCES_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
-                                                   XED_TYPE_PREFERENCES_DIALOG, \
-                                                   XedPreferencesDialogPrivate))
+G_DECLARE_FINAL_TYPE (XedPreferencesDialog, xed_preferences_dialog, XED, PREFERENCES_DIALOG, XAppPreferencesWindow)
 
-struct _XedPreferencesDialogPrivate
+struct _XedPreferencesDialog
 {
-    GSettings *editor;
-    GSettings *ui;
+    XAppPreferencesWindow parent_instance;
 
-    GtkWidget   *notebook;
+    GSettings *editor_settings;
+    GSettings *ui_settings;
 
-    /* Font */
-    GtkWidget *default_font_checkbutton;
-    GtkWidget *font_button;
-    GtkWidget *font_hbox;
+    /* Main pages */
+    GtkWidget *editor_page;
+    GtkWidget *save_page;
+    GtkWidget *theme_page;
+    GtkWidget *plugins_page;
 
-    /* Style Scheme */
-    GtkWidget *prefer_dark_theme_checkbutton;
-    GtkListStore *schemes_treeview_model;
-    GtkWidget *schemes_treeview;
-    GtkWidget *install_scheme_button;
-    GtkWidget *uninstall_scheme_button;
-
-    GtkWidget *install_scheme_file_schooser;
-
-    /* Tabs */
-    GtkWidget *tabs_width_spinbutton;
-    GtkWidget *insert_spaces_checkbutton;
-    GtkWidget *tabs_width_hbox;
+    /* File Saving */
+    GtkWidget *backup_copy_switch;
+    GtkWidget *auto_save_switch;
+    GtkWidget *auto_save_spin;
+    GtkWidget *auto_save_revealer;
 
-    /* Auto indentation */
-    GtkWidget *auto_indent_checkbutton;
+    /* Font */
+    GtkWidget *fixed_width_font_label;
+    GtkWidget *fixed_width_font_switch;
+    GtkWidget *font_button_revealer;
+    GtkWidget *font_button;
 
-    /* Text Wrapping */
-    GtkWidget *wrap_text_checkbutton;
-    GtkWidget *split_checkbutton;
+    /* Display */
+    GtkWidget *display_line_numbers_switch;
 
-    /* File Saving */
-    GtkWidget *backup_copy_checkbutton;
-    GtkWidget *auto_save_checkbutton;
-    GtkWidget *auto_save_spinbutton;
-    GtkWidget *autosave_hbox;
+    /* Minimap */
+    GtkWidget *minimap_switch;
 
-    /* Line numbers */
-    GtkWidget *display_line_numbers_checkbutton;
+    /* Right margin */
+    GtkWidget *display_right_margin_switch;
+    GtkWidget *right_margin_spin;
+    GtkWidget *right_margin_revealer;
 
     /* Highlight current line */
-    GtkWidget *highlight_current_line_checkbutton;
+    GtkWidget *highlight_current_line_switch;
 
     /* Highlight matching bracket */
-    GtkWidget *bracket_matching_checkbutton;
+    GtkWidget *highlight_matching_bracket_switch;
 
-    /* Minimap */
-    GtkWidget *mini_map_checkbutton;
+    /* Tabs */
+    GtkWidget *tab_width_spin;
+    GtkWidget *use_spaces_switch;
+    GtkWidget *automatic_indentation_switch;
 
-    /* Right margin */
-    GtkWidget *right_margin_checkbutton;
-    GtkWidget *right_margin_position_spinbutton;
-    GtkWidget *right_margin_position_hbox;
+    /* Word wrap */
+    GtkWidget *word_wrap_switch;
+    GtkWidget *split_words_revealer;
+    GtkWidget *split_words_switch;
 
     /* Tab scrolling */
-    GtkWidget *tab_scrolling_checkbutton;
+    GtkWidget *tab_scrolling_switch;
 
-    /* Plugins manager */
-    GtkWidget *plugin_manager_place_holder;
+    /* Style scheme */
+    GtkWidget *prefer_dark_theme_switch;
+    GtkWidget *schemes_list;
+    GtkWidget *install_scheme_button;
+    GtkWidget *uninstall_scheme_button;
+    GtkWidget *install_scheme_file_schooser;
 
-    /* Style Scheme editor dialog */
-    GtkWidget *style_scheme_dialog;
+    /* Plugins manager */
+     GtkWidget *plugin_manager_place_holder;
 };
 
 
-G_DEFINE_TYPE(XedPreferencesDialog, xed_preferences_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE(XedPreferencesDialog, xed_preferences_dialog, XAPP_TYPE_PREFERENCES_WINDOW)
 
 static void
 xed_preferences_dialog_dispose (GObject *object)
 {
     XedPreferencesDialog *dlg = XED_PREFERENCES_DIALOG (object);
 
-    g_clear_object (&dlg->priv->editor);
-    g_clear_object (&dlg->priv->ui);
+    g_clear_object (&dlg->editor_settings);
+    g_clear_object (&dlg->ui_settings);
 
     G_OBJECT_CLASS (xed_preferences_dialog_parent_class)->dispose (object);
 }
@@ -159,427 +150,329 @@ static void
 xed_preferences_dialog_class_init (XedPreferencesDialogClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
     object_class->dispose = xed_preferences_dialog_dispose;
 
-    g_type_class_add_private (object_class, sizeof (XedPreferencesDialogPrivate));
-}
-
-static void
-dialog_response_handler (GtkDialog *dlg,
-                         gint       res_id)
-{
-    xed_debug (DEBUG_PREFS);
-
-    switch (res_id)
-    {
-        case GTK_RESPONSE_HELP:
-            xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-prefs");
-            g_signal_stop_emission_by_name (dlg, "response");
-            break;
-        default:
-            gtk_widget_destroy (GTK_WIDGET (dlg));
-    }
+    gtk_widget_class_set_template_from_resource (widget_class, "/org/x/editor/ui/xed-preferences-dialog.ui");
+
+    /* Pages */
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, editor_page);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, save_page);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, theme_page);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, plugins_page);
+
+    /* Editor Page widgets */
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, fixed_width_font_label);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, fixed_width_font_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, font_button_revealer);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, font_button);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, display_line_numbers_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, minimap_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, display_right_margin_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, right_margin_spin);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, right_margin_revealer);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, highlight_current_line_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, highlight_matching_bracket_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, tab_width_spin);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, use_spaces_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, automatic_indentation_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, word_wrap_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, split_words_revealer);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, split_words_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, tab_scrolling_switch);
+
+    /* Save page widgets */
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, backup_copy_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, auto_save_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, auto_save_spin);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, auto_save_revealer);
+
+    /* Theme page widgets */
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, prefer_dark_theme_switch);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, schemes_list);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, install_scheme_button);
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, uninstall_scheme_button);
+
+    /* Plugin page widgets */
+    gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, plugin_manager_place_holder);
 }
 
 static void
-on_auto_save_changed (GSettings            *settings,
-                      const gchar          *key,
-                      XedPreferencesDialog *dlg)
+close_button_clicked (GtkButton *button,
+                      gpointer   data)
 {
-    gboolean value;
+    XedPreferencesDialog *dlg = XED_PREFERENCES_DIALOG (data);
 
     xed_debug (DEBUG_PREFS);
 
-    value = g_settings_get_boolean (settings, key);
-
-    gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, value);
+    gtk_widget_destroy (GTK_WIDGET (dlg));
 }
 
 static void
-setup_editor_page (XedPreferencesDialog *dlg)
+help_button_clicked (GtkButton *button,
+                     gpointer   data)
 {
-    gboolean auto_save;
+    XedPreferencesDialog *dlg = XED_PREFERENCES_DIALOG (data);
 
     xed_debug (DEBUG_PREFS);
 
-    /* Get values */
-    auto_save = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_AUTO_SAVE);
-
-    /* Set widget sensitivity */
-    gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, auto_save);
-
-    /* Connect signal */
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_TABS_SIZE,
-                     dlg->priv->tabs_width_spinbutton,
-                     "value",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_INSERT_SPACES,
-                     dlg->priv->insert_spaces_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_AUTO_INDENT,
-                     dlg->priv->auto_indent_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_CREATE_BACKUP_COPY,
-                     dlg->priv->backup_copy_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_BRACKET_MATCHING,
-                     dlg->priv->bracket_matching_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_AUTO_SAVE_INTERVAL,
-                     dlg->priv->auto_save_spinbutton,
-                     "value",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_signal_connect (dlg->priv->editor, "changed::auto_save",
-                      G_CALLBACK (on_auto_save_changed), dlg);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_AUTO_SAVE,
-                     dlg->priv->auto_save_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->ui,
-                     XED_SETTINGS_ENABLE_TAB_SCROLLING,
-                     dlg->priv->tab_scrolling_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+    xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-prefs");
 }
 
-static gboolean split_button_state = TRUE;
-
 static void
-wrap_mode_checkbutton_toggled (GtkToggleButton      *button,
-                               XedPreferencesDialog *dlg)
+word_wrap_switch_toggled (GObject    *toggle_switch,
+                          GParamSpec *pspec,
+                          gpointer    data)
 {
+    XedPreferencesDialog *dlg = XED_PREFERENCES_DIALOG (data);
     GtkWrapMode mode;
 
-    if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton)))
+    if (!gtk_switch_get_active (GTK_SWITCH (dlg->word_wrap_switch)))
     {
         mode = GTK_WRAP_NONE;
 
-        gtk_widget_set_sensitive (dlg->priv->split_checkbutton, FALSE);
-        gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
+        gtk_revealer_set_reveal_child (GTK_REVEALER (dlg->split_words_revealer), FALSE);
     }
     else
     {
-        gtk_widget_set_sensitive (dlg->priv->split_checkbutton, TRUE);
-        gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE);
-
+        gtk_revealer_set_reveal_child (GTK_REVEALER (dlg->split_words_revealer), TRUE);
 
-        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton)))
+        if (gtk_switch_get_active (GTK_SWITCH (dlg->split_words_switch)))
         {
-            split_button_state = TRUE;
-            mode = GTK_WRAP_WORD;
+            mode = GTK_WRAP_CHAR;
         }
         else
         {
-            split_button_state = FALSE;
-            mode = GTK_WRAP_CHAR;
+            mode = GTK_WRAP_WORD;
         }
     }
 
-    g_settings_set_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE, mode);
-}
-
-static void
-right_margin_checkbutton_toggled (GtkToggleButton      *button,
-                                  XedPreferencesDialog *dlg)
-{
-    gboolean active;
-
-    g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton));
-
-    active = gtk_toggle_button_get_active (button);
-
-    g_settings_set_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN, active);
-
-    gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, active);
+    g_settings_set_enum (dlg->editor_settings, XED_SETTINGS_WRAP_MODE, mode);
 }
 
 static void
-setup_view_page (XedPreferencesDialog *dlg)
+setup_editor_page (XedPreferencesDialog *dlg)
 {
+    XedSettings *settings;
+    gchar *system_font = NULL;
+    gchar *label_text;
     GtkWrapMode wrap_mode;
-    gboolean display_right_margin;
 
     xed_debug (DEBUG_PREFS);
 
-    /* Get values */
-    display_right_margin = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_DISPLAY_RIGHT_MARGIN);
+    /* Fonts */
+    settings = _xed_app_get_settings (XED_APP (g_application_get_default ()));
+    system_font = xed_settings_get_system_font (settings);
 
-    /* Set initial state */
-    wrap_mode = g_settings_get_enum (dlg->priv->editor, XED_SETTINGS_WRAP_MODE);
+    label_text = g_strdup_printf(_("Use the system fixed width font (%s)"), system_font);
+    gtk_label_set_text (GTK_LABEL (dlg->fixed_width_font_label), label_text);
+    g_free (system_font);
+    g_free (label_text);
 
-    switch (wrap_mode)
-    {
-        case GTK_WRAP_WORD:
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE);
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
-            break;
-        case GTK_WRAP_CHAR:
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE);
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE);
-            break;
-        default:
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), FALSE);
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), split_button_state);
-            gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_USE_DEFAULT_FONT,
+                     dlg->fixed_width_font_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    }
+    g_object_bind_property (dlg->fixed_width_font_switch,
+                            "active",
+                            dlg->font_button_revealer,
+                            "reveal-child",
+                            G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
 
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton), display_right_margin);
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_EDITOR_FONT,
+                     dlg->font_button,
+                     "font-name",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+
+    /* Display */
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_DISPLAY_RIGHT_MARGIN,
+                     dlg->display_right_margin_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    /* Set widgets sensitivity */
-    gtk_widget_set_sensitive (dlg->priv->split_checkbutton, (wrap_mode != GTK_WRAP_NONE));
-    gtk_widget_set_sensitive (dlg->priv->right_margin_position_hbox, display_right_margin);
+    g_object_bind_property (dlg->display_right_margin_switch,
+                            "active",
+                            dlg->right_margin_revealer,
+                            "reveal-child",
+                            G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT);
 
-    /* Connect signals */
-    g_settings_bind (dlg->priv->editor,
+    g_settings_bind (dlg->editor_settings,
                      XED_SETTINGS_DISPLAY_LINE_NUMBERS,
-                     dlg->priv->display_line_numbers_checkbutton,
+                     dlg->display_line_numbers_switch,
                      "active",
                      G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_HIGHLIGHT_CURRENT_LINE,
-                     dlg->priv->highlight_current_line_checkbutton,
+
+    g_settings_bind (dlg->ui_settings,
+                     XED_SETTINGS_MINIMAP_VISIBLE,
+                     dlg->minimap_switch,
                      "active",
                      G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
+
+    g_settings_bind (dlg->editor_settings,
                      XED_SETTINGS_RIGHT_MARGIN_POSITION,
-                     dlg->priv->right_margin_position_spinbutton,
+                     dlg->right_margin_spin,
                      "value",
                      G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->ui,
-                     XED_SETTINGS_MINIMAP_VISIBLE,
-                     dlg->priv->mini_map_checkbutton,
+
+    /* Highlighting */
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_HIGHLIGHT_CURRENT_LINE,
+                     dlg->highlight_current_line_switch,
                      "active",
                      G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_signal_connect (dlg->priv->wrap_text_checkbutton, "toggled",
-                      G_CALLBACK (wrap_mode_checkbutton_toggled), dlg);
-    g_signal_connect (dlg->priv->split_checkbutton, "toggled",
-                      G_CALLBACK (wrap_mode_checkbutton_toggled), dlg);
-    g_signal_connect (dlg->priv->right_margin_checkbutton, "toggled",
-                      G_CALLBACK (right_margin_checkbutton_toggled), dlg);
-}
-
-static void
-on_use_default_font_changed (GSettings            *settings,
-                             const gchar          *key,
-                             XedPreferencesDialog *dlg)
-{
-    gboolean value;
-
-    xed_debug (DEBUG_PREFS);
-
-    value = g_settings_get_boolean (settings, key);
-    gtk_widget_set_sensitive (dlg->priv->font_hbox, !value);
-}
-
-static void
-setup_font_colors_page_font_section (XedPreferencesDialog *dlg)
-{
-    GObject *settings;
-    gboolean use_default_font;
-    gchar *system_font = NULL;
-    gchar *label;
-
-    xed_debug (DEBUG_PREFS);
-
-    gtk_widget_set_tooltip_text (dlg->priv->font_button,
-                                 _("Click on this button to select the font to be used by the editor"));
-
-    xed_utils_set_atk_relation (dlg->priv->font_button,
-                                dlg->priv->default_font_checkbutton,
-                                ATK_RELATION_CONTROLLED_BY);
-    xed_utils_set_atk_relation (dlg->priv->default_font_checkbutton,
-                                dlg->priv->font_button,
-                                ATK_RELATION_CONTROLLER_FOR);
-
-    /* Get values */
-    settings = _xed_app_get_settings (XED_APP (g_application_get_default ()));
-    system_font = xed_settings_get_system_font (XED_SETTINGS (settings));
-    use_default_font = g_settings_get_boolean (dlg->priv->editor, XED_SETTINGS_USE_DEFAULT_FONT);
 
-    label = g_strdup_printf(_("_Use the system fixed width font (%s)"), system_font);
-    gtk_button_set_label (GTK_BUTTON (dlg->priv->default_font_checkbutton), label);
-    g_free (system_font);
-    g_free (label);
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_BRACKET_MATCHING,
+                     dlg->highlight_matching_bracket_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    /* read current config and setup initial state */
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->default_font_checkbutton), use_default_font);
+    /* Indentation */
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_TABS_SIZE,
+                     dlg->tab_width_spin,
+                     "value",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    /* Connect signals */
-    g_signal_connect (dlg->priv->editor, "changed::use-default-font",
-                      G_CALLBACK (on_use_default_font_changed), dlg);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_USE_DEFAULT_FONT,
-                     dlg->priv->default_font_checkbutton,
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_INSERT_SPACES,
+                     dlg->use_spaces_switch,
                      "active",
                      G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_EDITOR_FONT,
-                     dlg->priv->font_button,
-                     "font-name",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    /* Set initial widget sensitivity */
-    gtk_widget_set_sensitive (dlg->priv->font_hbox, !use_default_font);
-}
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_AUTO_INDENT,
+                     dlg->automatic_indentation_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-static gboolean
-is_xed_user_style_scheme (const gchar *scheme_id)
-{
-    GtkSourceStyleSchemeManager *manager;
-    GtkSourceStyleScheme *scheme;
-    gboolean res = FALSE;
+    /* Word wrap */
+    wrap_mode = g_settings_get_enum (dlg->editor_settings, XED_SETTINGS_WRAP_MODE);
 
-    manager = gtk_source_style_scheme_manager_get_default ();
-    scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_id);
-    if (scheme != NULL)
+    switch (wrap_mode)
     {
-        const gchar *filename;
-
-        filename = gtk_source_style_scheme_get_filename (scheme);
-        if (filename != NULL)
-        {
-           res = g_str_has_prefix (filename, xed_dirs_get_user_styles_dir ());
-        }
+        case GTK_WRAP_WORD:
+            gtk_switch_set_active (GTK_SWITCH (dlg->word_wrap_switch), TRUE);
+            gtk_revealer_set_reveal_child (GTK_REVEALER (dlg->split_words_revealer), TRUE);
+            gtk_switch_set_active (GTK_SWITCH (dlg->split_words_switch), FALSE);
+            break;
+        case GTK_WRAP_CHAR:
+            gtk_switch_set_active (GTK_SWITCH (dlg->word_wrap_switch), TRUE);
+            gtk_revealer_set_reveal_child (GTK_REVEALER (dlg->split_words_revealer), TRUE);
+            gtk_switch_set_active (GTK_SWITCH (dlg->split_words_switch), TRUE);
+            break;
+        default:
+            gtk_switch_set_active (GTK_SWITCH (dlg->word_wrap_switch), FALSE);
+            gtk_revealer_set_reveal_child (GTK_REVEALER (dlg->split_words_revealer), FALSE);
     }
 
-   return res;
-}
-
-static void
-set_buttons_sensisitivity_according_to_scheme (XedPreferencesDialog *dlg,
-                                               const gchar          *scheme_id)
-{
-    gboolean editable;
+    g_signal_connect (dlg->word_wrap_switch, "notify::active",
+                      G_CALLBACK (word_wrap_switch_toggled), dlg);
+    g_signal_connect (dlg->split_words_switch, "notify::active",
+                      G_CALLBACK (word_wrap_switch_toggled), dlg);
 
-    editable = ((scheme_id != NULL) && is_xed_user_style_scheme (scheme_id));
+    /* Tab scrolling */
+    g_settings_bind (dlg->ui_settings,
+                     XED_SETTINGS_ENABLE_TAB_SCROLLING,
+                     dlg->tab_scrolling_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    gtk_widget_set_sensitive (dlg->priv->uninstall_scheme_button, editable);
+    xapp_preferences_window_add_page (XAPP_PREFERENCES_WINDOW (dlg), dlg->editor_page, "editor", _("Editor"));
 }
 
 static void
-style_scheme_changed (GtkWidget            *treeview,
-                      XedPreferencesDialog *dlg)
+setup_save_page (XedPreferencesDialog *dlg)
 {
-    GtkTreePath *path;
-
-    gtk_tree_view_get_cursor (GTK_TREE_VIEW (dlg->priv->schemes_treeview), &path, NULL);
+    xed_debug (DEBUG_PREFS);
 
-    if (path != NULL)
-    {
-        GtkTreeIter iter;
-        gchar *id;
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_CREATE_BACKUP_COPY,
+                     dlg->backup_copy_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-        gtk_tree_model_get_iter (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), &iter, path);
-        gtk_tree_path_free (path);
-        gtk_tree_model_get (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model), &iter, ID_COLUMN, &id, -1);
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_AUTO_SAVE,
+                     dlg->auto_save_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-        g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, id);
+    g_object_bind_property (dlg->auto_save_switch,
+                            "active",
+                            dlg->auto_save_revealer,
+                            "reveal-child",
+                            G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT);
 
-        set_buttons_sensisitivity_according_to_scheme (dlg, id);
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_AUTO_SAVE_INTERVAL,
+                     dlg->auto_save_spin,
+                     "value",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-        g_free (id);
-    }
+    xapp_preferences_window_add_page (XAPP_PREFERENCES_WINDOW (dlg), dlg->save_page, "save", _("Save"));
 }
 
-static const gchar *
-ensure_color_scheme_id (XedPreferencesDialog *dlg,
-                        const gchar          *id)
+static GtkSourceStyleScheme *
+get_default_color_scheme (XedPreferencesDialog *dlg)
 {
     GtkSourceStyleSchemeManager *manager;
     GtkSourceStyleScheme *scheme = NULL;
+    gchar *pref_id;
 
     manager = gtk_source_style_scheme_manager_get_default ();
-    if (id == NULL)
-    {
-        gchar *pref_id;
+    pref_id = g_settings_get_string (dlg->editor_settings, XED_SETTINGS_SCHEME);
+    scheme = gtk_source_style_scheme_manager_get_scheme (manager, pref_id);
 
-        pref_id = g_settings_get_string (dlg->priv->editor, XED_SETTINGS_SCHEME);
-        scheme = gtk_source_style_scheme_manager_get_scheme (manager, pref_id);
-        g_free (pref_id);
-    }
-    else
-    {
-        scheme = gtk_source_style_scheme_manager_get_scheme (manager, id);
-    }
+    g_free (pref_id);
 
     if (scheme == NULL)
     {
-        /* Fall-back to classic style scheme */
+        /* Fallback to classic style scheme */
         scheme = gtk_source_style_scheme_manager_get_scheme (manager, "classic");
     }
 
-    if (scheme == NULL)
-    {
-        /* Cannot determine default style scheme -> broken GtkSourceView installation */
-        return NULL;
-    }
-
-    return  gtk_source_style_scheme_get_id (scheme);
+    return scheme;
 }
 
-static const gchar *
-populate_color_scheme_list (XedPreferencesDialog *dlg,
-                            const gchar          *def_id)
+static void
+set_buttons_sensisitivity_according_to_scheme (XedPreferencesDialog *dlg,
+                                               GtkSourceStyleScheme *scheme)
 {
-    GtkSourceStyleSchemeManager *manager;
-    const gchar * const *ids;
-    gint i;
-
-    gtk_list_store_clear (dlg->priv->schemes_treeview_model);
+    gboolean editable = FALSE;
 
-    def_id = ensure_color_scheme_id (dlg, def_id);
-    if (def_id == NULL)
+    if (scheme != NULL)
     {
-        g_warning ("Cannot build the list of available color schemes.\n"
-                   "Please check your GtkSourceView installation.");
-        return NULL;
-    }
+        const gchar *filename;
 
-    manager = gtk_source_style_scheme_manager_get_default ();
-    ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
-    for (i = 0; ids[i] != NULL; i++)
-    {
-        GtkSourceStyleScheme *scheme;
-        const gchar *name;
-        const gchar *description;
-        GtkTreeIter iter;
-
-        scheme = gtk_source_style_scheme_manager_get_scheme (manager, ids[i]);
-        name = gtk_source_style_scheme_get_name (scheme);
-        description = gtk_source_style_scheme_get_description (scheme);
-
-        gtk_list_store_append (dlg->priv->schemes_treeview_model, &iter);
-        gtk_list_store_set (dlg->priv->schemes_treeview_model,
-                            &iter,
-                            ID_COLUMN, ids[i],
-                            NAME_COLUMN, name,
-                            DESC_COLUMN, description,
-                            -1);
-
-        g_return_val_if_fail (def_id != NULL, NULL);
-        if (strcmp (ids[i], def_id) == 0)
+        filename = gtk_source_style_scheme_get_filename (scheme);
+        if (filename != NULL)
         {
-            GtkTreeSelection *selection;
-
-            selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
-            gtk_tree_selection_select_iter (selection, &iter);
+            editable = g_str_has_prefix (filename, xed_dirs_get_user_styles_dir ());
         }
     }
 
-    return def_id;
+    gtk_widget_set_sensitive (dlg->uninstall_scheme_button, editable);
+}
+
+static void
+style_scheme_changed (GtkSourceStyleSchemeChooser *chooser,
+                      GParamSpec                  *pspec,
+                      XedPreferencesDialog        *dlg)
+{
+    GtkSourceStyleScheme *scheme;
+    const gchar *id;
+
+    scheme = gtk_source_style_scheme_chooser_get_style_scheme (chooser);
+    id = gtk_source_style_scheme_get_id (scheme);
+
+    g_settings_set_string (dlg->editor_settings, XED_SETTINGS_SCHEME, id);
+    set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
 }
 
 /*
@@ -654,6 +547,7 @@ file_copy (const gchar  *name,
 
     if (!g_file_set_contents (dest_name, contents, length, error))
     {
+        g_free (contents);
         return FALSE;
     }
 
@@ -677,7 +571,7 @@ file_copy (const gchar  *name,
  *
  * Return value: the id of the installed scheme, %NULL otherwise.
  */
-static const gchar *
+static GtkSourceStyleScheme *
 install_style_scheme (const gchar *fname)
 {
     GtkSourceStyleSchemeManager *manager;
@@ -686,7 +580,7 @@ install_style_scheme (const gchar *fname)
     const gchar *styles_dir;
     GError *error = NULL;
     gboolean copied = FALSE;
-    const gchar* const *ids;
+    const gchar * const *ids;
 
     g_return_val_if_fail (fname != NULL, NULL);
 
@@ -703,13 +597,16 @@ install_style_scheme (const gchar *fname)
         new_file_name = g_build_filename (styles_dir, basename, NULL);
         g_free (basename);
 
-        /* Copy the style scheme file into GEDIT_STYLES_DIR */
+        /* Copy the style scheme file into XED_STYLES_DIR */
         if (!file_copy (fname, new_file_name, &error))
         {
             g_free (new_file_name);
+            g_free (dirname);
 
             g_message ("Cannot install style scheme:\n%s", error->message);
 
+            g_error_free (error);
+
            return NULL;
         }
 
@@ -742,7 +639,7 @@ install_style_scheme (const gchar *fname)
             /* The style scheme has been correctly installed */
             g_free (new_file_name);
 
-            return gtk_source_style_scheme_get_id (scheme);
+            return scheme;
         }
         ++ids;
     }
@@ -758,59 +655,13 @@ install_style_scheme (const gchar *fname)
     return NULL;
 }
 
-/**
- * uninstall_style_scheme:
- * @manager: a #GtkSourceStyleSchemeManager
- * @id: the id of the style scheme to be uninstalled
- *
- * Uninstall a user scheme.
- *
- * If the call was succesful, it returns %TRUE
- * otherwise %FALSE.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
-static gboolean
-uninstall_style_scheme (const gchar *id)
-{
-    GtkSourceStyleSchemeManager *manager;
-    GtkSourceStyleScheme *scheme;
-    const gchar *filename;
-
-    g_return_val_if_fail (id != NULL, FALSE);
-
-    manager = gtk_source_style_scheme_manager_get_default ();
-
-    scheme = gtk_source_style_scheme_manager_get_scheme (manager, id);
-    if (scheme == NULL)
-    {
-       return FALSE;
-    }
-
-    filename = gtk_source_style_scheme_get_filename (scheme);
-    if (filename == NULL)
-    {
-        return FALSE;
-    }
-
-    if (g_unlink (filename) == -1)
-    {
-        return FALSE;
-    }
-
-    /* Reload the available style schemes */
-    gtk_source_style_scheme_manager_force_rescan (manager);
-
-    return TRUE;
-}
-
 static void
 add_scheme_chooser_response_cb (GtkDialog            *chooser,
                                 gint                  res_id,
                                 XedPreferencesDialog *dlg)
 {
     gchar* filename;
-    const gchar *scheme_id;
+    GtkSourceStyleScheme *scheme;
 
     if (res_id != GTK_RESPONSE_ACCEPT)
     {
@@ -826,20 +677,18 @@ add_scheme_chooser_response_cb (GtkDialog            *chooser,
 
     gtk_widget_hide (GTK_WIDGET (chooser));
 
-    scheme_id = install_style_scheme (filename);
+    scheme = install_style_scheme (filename);
     g_free (filename);
 
-    if (scheme_id == NULL)
+    if (scheme == NULL)
     {
         xed_warning (GTK_WINDOW (dlg), _("The selected color scheme cannot be installed."));
         return;
     }
 
-    g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, scheme_id);
+    g_settings_set_string (dlg->editor_settings, XED_SETTINGS_SCHEME, gtk_source_style_scheme_get_id (scheme));
 
-    scheme_id = populate_color_scheme_list (dlg, scheme_id);
-
-    set_buttons_sensisitivity_according_to_scheme (dlg, scheme_id);
+    set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
 }
 
 static void
@@ -849,10 +698,10 @@ install_scheme_clicked (GtkButton            *button,
     GtkWidget      *chooser;
     GtkFileFilter  *filter;
 
-    if (dlg->priv->install_scheme_file_schooser != NULL)
+    if (dlg->install_scheme_file_schooser != NULL)
     {
-        gtk_window_present (GTK_WINDOW (dlg->priv->install_scheme_file_schooser));
-        gtk_widget_grab_focus (dlg->priv->install_scheme_file_schooser);
+        gtk_window_present (GTK_WINDOW (dlg->install_scheme_file_schooser));
+        gtk_widget_grab_focus (dlg->install_scheme_file_schooser);
         return;
     }
 
@@ -884,191 +733,95 @@ install_scheme_clicked (GtkButton            *button,
     g_signal_connect (chooser, "response",
                       G_CALLBACK (add_scheme_chooser_response_cb), dlg);
 
-    dlg->priv->install_scheme_file_schooser = chooser;
+    dlg->install_scheme_file_schooser = chooser;
 
-    g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer) &dlg->priv->install_scheme_file_schooser);
+    g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer) &dlg->install_scheme_file_schooser);
 
     gtk_widget_show (chooser);
 }
 
-static void
-uninstall_scheme_clicked (GtkButton            *button,
-                          XedPreferencesDialog *dlg)
+/**
+ * uninstall_style_scheme:
+ * @manager: a #GtkSourceStyleSchemeManager
+ * @scheme: a #GtkSourceStyleScheme
+ *
+ * Uninstall a user scheme.
+ *
+ * If the call was succesful, it returns %TRUE
+ * otherwise %FALSE.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
+ */
+static gboolean
+uninstall_style_scheme (GtkSourceStyleScheme *scheme)
 {
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
+    GtkSourceStyleSchemeManager *manager;
+    const gchar *filename;
+
+    g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme), FALSE);
 
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
-    model = GTK_TREE_MODEL (dlg->priv->schemes_treeview_model);
+    manager = gtk_source_style_scheme_manager_get_default ();
 
-    if (gtk_tree_selection_get_selected (selection, &model, &iter))
+    filename = gtk_source_style_scheme_get_filename (scheme);
+    if (filename == NULL)
     {
-        gchar *id;
-        gchar *name;
+        return FALSE;
+    }
 
-        gtk_tree_model_get (model, &iter, ID_COLUMN, &id, NAME_COLUMN, &name, -1);
+    if (g_unlink (filename) == -1)
+    {
+        return FALSE;
+    }
 
-        if (!uninstall_style_scheme (id))
-        {
-            xed_warning (GTK_WINDOW (dlg), _("Could not remove color scheme \"%s\"."), name);
-        }
-        else
-        {
-            const gchar *real_new_id;
-            gchar *new_id = NULL;
-            GtkTreePath *path;
-            GtkTreeIter new_iter;
-            gboolean new_iter_set = FALSE;
-
-            /* If the removed style scheme is the last of the list,
-             * set as new default style scheme the previous one,
-             * otherwise set the next one.
-             * To make this possible, we need to get the id of the
-             * new default style scheme before re-populating the list.
-             * Fall back to "classic" if it is not possible to get
-             * the id
-             */
-            path = gtk_tree_model_get_path (model, &iter);
-
-            /* Try to move to the next path */
-            gtk_tree_path_next (path);
-            if (!gtk_tree_model_get_iter (model, &new_iter, path))
-            {
-                /* It seems the removed style scheme was the
-                 * last of the list. Try to move to the
-                 * previous one */
-                gtk_tree_path_free (path);
-
-                path = gtk_tree_model_get_path (model, &iter);
-
-                gtk_tree_path_prev (path);
-                if (gtk_tree_model_get_iter (model, &new_iter, path))
-                {
-                    new_iter_set = TRUE;
-                }
-            }
-            else
-            {
-                new_iter_set = TRUE;
-            }
-
-            gtk_tree_path_free (path);
-
-            if (new_iter_set)
-            {
-                gtk_tree_model_get (model, &new_iter, ID_COLUMN, &new_id, -1);
-            }
-
-            real_new_id = populate_color_scheme_list (dlg, new_id);
-            g_free (new_id);
-
-            set_buttons_sensisitivity_according_to_scheme (dlg, real_new_id);
-
-            if (real_new_id != NULL)
-            {
-                g_settings_set_string (dlg->priv->editor, XED_SETTINGS_SCHEME, real_new_id);
-            }
-        }
+    /* Reload the available style schemes */
+    gtk_source_style_scheme_manager_force_rescan (manager);
 
-        g_free (id);
-        g_free (name);
-    }
+    return TRUE;
 }
 
 static void
-scheme_description_cell_data_func (GtkTreeViewColumn *column,
-                                   GtkCellRenderer   *renderer,
-                                   GtkTreeModel      *model,
-                                   GtkTreeIter       *iter,
-                                   gpointer           data)
+uninstall_scheme_clicked (GtkButton            *button,
+                          XedPreferencesDialog *dlg)
 {
-    gchar *name;
-    gchar *desc;
-    gchar *text;
+    GtkSourceStyleScheme *scheme;
 
-    gtk_tree_model_get (model, iter, NAME_COLUMN, &name, DESC_COLUMN, &desc, -1);
+    scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
 
-    if (desc != NULL)
-    {
-        text = g_markup_printf_escaped ("<b>%s</b> - %s", name, desc);
-    }
-    else
+    if (!uninstall_style_scheme (scheme))
     {
-        text = g_markup_printf_escaped ("<b>%s</b>", name);
+        xed_warning (GTK_WINDOW (dlg), _("Could not remove color scheme \"%s\"."),
+                     gtk_source_style_scheme_get_name (scheme));
     }
-
-    g_free (name);
-    g_free (desc);
-
-    g_object_set (G_OBJECT (renderer), "markup", text, NULL);
-
-    g_free (text);
 }
 
 static void
-setup_font_colors_page_style_scheme_section (XedPreferencesDialog *dlg)
+setup_theme_page (XedPreferencesDialog *dlg)
 {
-    GtkCellRenderer *renderer;
-    GtkTreeViewColumn *column;
-    GtkTreeSelection *selection;
-    const gchar *def_id;
+    GtkSourceStyleScheme *scheme;
 
     xed_debug (DEBUG_PREFS);
 
-    /* Create GtkListStore for styles & setup treeview. */
-    dlg->priv->schemes_treeview_model = gtk_list_store_new (NUM_COLUMNS,
-                                                            G_TYPE_STRING,
-                                                            G_TYPE_STRING,
-                                                            G_TYPE_STRING,
-                                                            G_TYPE_STRING);
-
-    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dlg->priv->schemes_treeview_model),
-                                          0, GTK_SORT_ASCENDING);
-    gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->schemes_treeview),
-                             GTK_TREE_MODEL (dlg->priv->schemes_treeview_model));
-
-    column = gtk_tree_view_column_new ();
-
-    renderer = gtk_cell_renderer_text_new ();
-    g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-    gtk_tree_view_column_pack_start (column, renderer, TRUE);
-    gtk_tree_view_column_set_cell_data_func (column,
-                                             renderer,
-                                             scheme_description_cell_data_func,
-                                             dlg,
-                                             NULL);
-
-    gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->schemes_treeview), column);
-
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
-    gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+    /* Prefer dark theme */
+    g_settings_bind (dlg->editor_settings,
+                     XED_SETTINGS_PREFER_DARK_THEME,
+                     dlg->prefer_dark_theme_switch,
+                     "active",
+                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
 
-    def_id = populate_color_scheme_list (dlg, NULL);
+    /* Style scheme */
+    scheme = get_default_color_scheme (dlg);
 
-    /* Connect signals */
-    g_signal_connect (dlg->priv->schemes_treeview, "cursor-changed",
+    g_signal_connect (dlg->schemes_list, "notify::style-scheme",
                       G_CALLBACK (style_scheme_changed), dlg);
-    g_signal_connect (dlg->priv->install_scheme_button, "clicked",
+    g_signal_connect (dlg->install_scheme_button, "clicked",
                       G_CALLBACK (install_scheme_clicked), dlg);
-    g_signal_connect (dlg->priv->uninstall_scheme_button, "clicked",
+    g_signal_connect (dlg->uninstall_scheme_button, "clicked",
                       G_CALLBACK (uninstall_scheme_clicked), dlg);
 
-    /* Set initial widget sensitivity */
-    set_buttons_sensisitivity_according_to_scheme (dlg, def_id);
-}
-
-static void
-setup_font_colors_page (XedPreferencesDialog *dlg)
-{
-    setup_font_colors_page_font_section (dlg);
-    setup_font_colors_page_style_scheme_section (dlg);
+    gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list), scheme);
+    set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
 
-    g_settings_bind (dlg->priv->editor,
-                     XED_SETTINGS_PREFER_DARK_THEME,
-                     dlg->priv->prefer_dark_theme_checkbutton,
-                     "active",
-                     G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+    xapp_preferences_window_add_page (XAPP_PREFERENCES_WINDOW (dlg), dlg->theme_page, "theme", _("Theme"));
 }
 
 static void
@@ -1081,87 +834,48 @@ setup_plugins_page (XedPreferencesDialog *dlg)
     page_content = peas_gtk_plugin_manager_new (NULL);
     g_return_if_fail (page_content != NULL);
 
-    gtk_box_pack_start (GTK_BOX (dlg->priv->plugin_manager_place_holder), page_content, TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (dlg->plugin_manager_place_holder), page_content, TRUE, TRUE, 0);
 
     gtk_widget_show_all (page_content);
+
+    xapp_preferences_window_add_page (XAPP_PREFERENCES_WINDOW (dlg), dlg->plugins_page, "plugins", _("Plugins"));
 }
 
 static void
-xed_preferences_dialog_init (XedPreferencesDialog *dlg)
+setup_buttons (XedPreferencesDialog *dlg)
 {
-    GtkBuilder *builder;
-    gchar *root_objects[] = {
-        "notebook",
-        "adjustment1",
-        "adjustment2",
-        "adjustment3",
-        NULL
-    };
+    GtkWidget *button;
 
-    xed_debug (DEBUG_PREFS);
+    button = gtk_button_new_with_label (_("Help"));
+    xapp_preferences_window_add_button (XAPP_PREFERENCES_WINDOW (dlg), button, GTK_PACK_START);
+    g_signal_connect (button, "clicked",
+                      G_CALLBACK (help_button_clicked), dlg);
 
-    dlg->priv = XED_PREFERENCES_DIALOG_GET_PRIVATE (dlg);
-    dlg->priv->editor = g_settings_new ("org.x.editor.preferences.editor");
-    dlg->priv->ui = g_settings_new ("org.x.editor.preferences.ui");
+    button = gtk_button_new_with_label (_("Close"));
+    xapp_preferences_window_add_button (XAPP_PREFERENCES_WINDOW (dlg), button, GTK_PACK_END);
+    g_signal_connect (button, "clicked",
+                      G_CALLBACK (close_button_clicked), dlg);
+}
+
+static void
+xed_preferences_dialog_init (XedPreferencesDialog *dlg)
+{
+    xed_debug (DEBUG_PREFS);
 
-    gtk_dialog_add_buttons (GTK_DIALOG (dlg),
-                            _("Close"), GTK_RESPONSE_CLOSE,
-                            _("Help"), GTK_RESPONSE_HELP,
-                            NULL);
+    dlg->editor_settings = g_settings_new ("org.x.editor.preferences.editor");
+    dlg->ui_settings = g_settings_new ("org.x.editor.preferences.ui");
 
     gtk_window_set_title (GTK_WINDOW (dlg), _("Xed Preferences"));
-    gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
-    gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
-
-    /* HIG defaults */
-    gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
-    gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); /* 2 * 5 + 2 = 12 */
-    gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 5);
-    gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6);
-
-    g_signal_connect (dlg, "response",
-                      G_CALLBACK (dialog_response_handler), NULL);
-
-    builder = gtk_builder_new ();
-    gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-preferences-dialog.ui", root_objects, NULL);
-    dlg->priv->notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook"));
-    g_object_ref (dlg->priv->notebook);
-    dlg->priv->display_line_numbers_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "display_line_numbers_checkbutton"));
-    dlg->priv->highlight_current_line_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "highlight_current_line_checkbutton"));
-    dlg->priv->bracket_matching_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "bracket_matching_checkbutton"));
-    dlg->priv->mini_map_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "mini_map_checkbutton"));
-    dlg->priv->wrap_text_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "wrap_text_checkbutton"));
-    dlg->priv->split_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "split_checkbutton"));
-    dlg->priv->right_margin_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_checkbutton"));
-    dlg->priv->right_margin_position_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_position_spinbutton"));
-    dlg->priv->right_margin_position_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "right_margin_position_hbox"));
-    dlg->priv->tabs_width_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "tabs_width_spinbutton"));
-    dlg->priv->tabs_width_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "tabs_width_hbox"));
-    dlg->priv->insert_spaces_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "insert_spaces_checkbutton"));
-    dlg->priv->auto_indent_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_indent_checkbutton"));
-    dlg->priv->autosave_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "autosave_hbox"));
-    dlg->priv->backup_copy_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "backup_copy_checkbutton"));
-    dlg->priv->auto_save_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_save_checkbutton"));
-    dlg->priv->auto_save_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "auto_save_spinbutton"));
-    dlg->priv->tab_scrolling_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "tab_scrolling_checkbutton"));
-    dlg->priv->default_font_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "default_font_checkbutton"));
-    dlg->priv->font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
-    dlg->priv->font_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "font_hbox"));
-    dlg->priv->prefer_dark_theme_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "prefer_dark_theme_checkbutton"));
-    dlg->priv->schemes_treeview = GTK_WIDGET (gtk_builder_get_object (builder, "schemes_treeview"));
-    dlg->priv->install_scheme_button = GTK_WIDGET (gtk_builder_get_object (builder, "install_scheme_button"));
-    dlg->priv->uninstall_scheme_button = GTK_WIDGET (gtk_builder_get_object (builder, "uninstall_scheme_button"));
-    dlg->priv->plugin_manager_place_holder = GTK_WIDGET (gtk_builder_get_object (builder, "plugin_manager_place_holder"));
-    g_object_unref (builder);
-
-    gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), dlg->priv->notebook, FALSE, FALSE, 0);
-    g_object_unref (dlg->priv->notebook);
-    gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->notebook), 5);
+
+    gtk_widget_init_template (GTK_WIDGET (dlg));
+
+    setup_buttons (dlg);
 
     setup_editor_page (dlg);
-    setup_view_page (dlg);
-    setup_font_colors_page (dlg);
+    setup_save_page (dlg);
+    setup_theme_page (dlg);
     setup_plugins_page (dlg);
+    gtk_widget_show_all (GTK_WIDGET (dlg));
 }
 
 void
diff --git a/xed/xed-preferences-dialog.h b/xed/xed-preferences-dialog.h
index 40cc03e..f7e8685 100755
--- a/xed/xed-preferences-dialog.h
+++ b/xed/xed-preferences-dialog.h
@@ -3,7 +3,7 @@
  * xed-preferences-dialog.c
  * This file is part of xed
  *
- * Copyright (C) 2001-2005 Paolo Maggi 
+ * Copyright (C) 2001-2005 Paolo Maggi
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,14 +17,14 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, 
- * Boston, MA 02110-1301, USA. 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /*
- * Modified by the xed Team, 2003. See the AUTHORS file for a 
- * list of people on the xed Team.  
- * See the ChangeLog files for a list of changes. 
+ * Modified by the xed Team, 2003. See the AUTHORS file for a
+ * list of people on the xed Team.
+ * See the ChangeLog files for a list of changes.
  *
  * $Id$
  */
@@ -32,54 +32,13 @@
 #ifndef __XED_PREFERENCES_DIALOG_H__
 #define __XED_PREFERENCES_DIALOG_H__
 
+#include <libxapp/xapp-preferences-window.h>
+
 #include "xed-window.h"
 
 G_BEGIN_DECLS
 
-/*
- * Type checking and casting macros
- */
-#define XED_TYPE_PREFERENCES_DIALOG              (xed_preferences_dialog_get_type())
-#define XED_PREFERENCES_DIALOG(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PREFERENCES_DIALOG, XedPreferencesDialog))
-#define XED_PREFERENCES_DIALOG_CONST(obj)        (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_PREFERENCES_DIALOG, XedPreferencesDialog const))
-#define XED_PREFERENCES_DIALOG_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_PREFERENCES_DIALOG, XedPreferencesDialogClass))
-#define XED_IS_PREFERENCES_DIALOG(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_PREFERENCES_DIALOG))
-#define XED_IS_PREFERENCES_DIALOG_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_PREFERENCES_DIALOG))
-#define XED_PREFERENCES_DIALOG_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_PREFERENCES_DIALOG, XedPreferencesDialogClass))
-
-
-/* Private structure type */
-typedef struct _XedPreferencesDialogPrivate XedPreferencesDialogPrivate;
-
-/*
- * Main object structure
- */
-typedef struct _XedPreferencesDialog XedPreferencesDialog;
-
-struct _XedPreferencesDialog 
-{
-	GtkDialog dialog;
-	
-	/*< private > */
-	XedPreferencesDialogPrivate *priv;
-};
-
-/*
- * Class definition
- */
-typedef struct _XedPreferencesDialogClass XedPreferencesDialogClass;
-
-struct _XedPreferencesDialogClass 
-{
-	GtkDialogClass parent_class;
-};
-
-/*
- * Public methods
- */
-GType		 xed_preferences_dialog_get_type	(void) G_GNUC_CONST;
-
-void		 xed_show_preferences_dialog		(XedWindow *parent);
+void xed_show_preferences_dialog (XedWindow *parent);
 
 G_END_DECLS
 

From 5ef9b73f1bb5a1f64620d5bed78a6a38bf394714 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 00:46:02 -0800
Subject: [PATCH 03/14] xed-window: Rework the fullscreen toolbar

The animation used for hiding/showing the fullscreen toolbar is totally broken
under HiDPI. Port to GtkRevealer and GtkEventBox to get the proper behaviour.
---
 xed/xed-window-private.h |   6 +-
 xed/xed-window.c         | 206 ++++++++++-------------------------------------
 2 files changed, 44 insertions(+), 168 deletions(-)

diff --git a/xed/xed-window-private.h b/xed/xed-window-private.h
index 2e3b5c1..691779c 100644
--- a/xed/xed-window-private.h
+++ b/xed/xed-window-private.h
@@ -66,9 +66,9 @@ struct _XedWindowPrivate
 
     /* Widgets for fullscreen mode */
     GtkWidget *fullscreen_controls;
-    GtkWidget *fullscreen_controls_container;
-    guint      fullscreen_animation_timeout_id;
-    gboolean   fullscreen_animation_enter;
+    GtkWidget *fullscreen_overlay;
+    GtkWidget *fullscreen_eventbox;
+    GtkWidget *fullscreen_revealer;
 
     /* statusbar and context ids for statusbar messages */
     GtkWidget *statusbar;
diff --git a/xed/xed-window.c b/xed/xed-window.c
index 7227c1a..16fa803 100644
--- a/xed/xed-window.c
+++ b/xed/xed-window.c
@@ -35,8 +35,6 @@
 #define TAB_WIDTH_DATA "XedWindowTabWidthData"
 #define LANGUAGE_DATA  "XedWindowLanguageData"
 
-#define FULLSCREEN_ANIMATION_SPEED 4
-
 #define XED_WINDOW_DEFAULT_WIDTH  650
 #define XED_WINDOW_DEFAULT_HEIGHT 500
 
@@ -207,18 +205,6 @@ xed_window_dispose (GObject *object)
         window->priv->dispose_has_run = TRUE;
     }
 
-    if (window->priv->fullscreen_animation_timeout_id != 0)
-    {
-        g_source_remove (window->priv->fullscreen_animation_timeout_id);
-        window->priv->fullscreen_animation_timeout_id = 0;
-    }
-
-    if (window->priv->fullscreen_controls != NULL)
-    {
-        gtk_widget_destroy (window->priv->fullscreen_controls);
-        window->priv->fullscreen_controls = NULL;
-    }
-
     if (window->priv->recents_handler_id != 0)
     {
         GtkRecentManager *recent_manager;
@@ -2636,143 +2622,22 @@ drop_uris_cb (GtkWidget *widget,
     load_uris_from_drop (window, uri_list);
 }
 
-static void
-fullscreen_controls_show (XedWindow *window)
-{
-    GdkScreen *screen;
-    GdkRectangle fs_rect;
-    gint min_h, nat_h;
-
-    screen = gtk_window_get_screen (GTK_WINDOW (window));
-    gdk_screen_get_monitor_geometry (
-                    screen, gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
-                    &fs_rect);
-
-    gtk_widget_get_preferred_height (window->priv->fullscreen_controls_container, &min_h, &nat_h);
-    gtk_window_resize (GTK_WINDOW (window->priv->fullscreen_controls), fs_rect.width, nat_h);
-    gtk_window_move (GTK_WINDOW (window->priv->fullscreen_controls), fs_rect.x, fs_rect.y - nat_h + 1);
-
-    gtk_widget_show_all (window->priv->fullscreen_controls);
-}
-
-static gboolean
-run_fullscreen_animation (gpointer data)
-{
-    XedWindow *window = XED_WINDOW(data);
-    GdkScreen *screen;
-    GdkRectangle fs_rect;
-    gint x, y;
-
-    screen = gtk_window_get_screen (GTK_WINDOW(window));
-    gdk_screen_get_monitor_geometry (screen,
-                    gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
-                    &fs_rect);
-
-    gtk_window_get_position (GTK_WINDOW(window->priv->fullscreen_controls), &x, &y);
-
-    if (window->priv->fullscreen_animation_enter)
-    {
-        if (y == fs_rect.y)
-        {
-            window->priv->fullscreen_animation_timeout_id = 0;
-            return FALSE;
-        }
-        else
-        {
-            gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), x, y + 1);
-            return TRUE;
-        }
-    }
-    else
-    {
-        gint w, h;
-        gtk_window_get_size (GTK_WINDOW(window->priv->fullscreen_controls), &w, &h);
-        if (y == fs_rect.y - h + 1)
-        {
-            window->priv->fullscreen_animation_timeout_id = 0;
-            return FALSE;
-        }
-        else
-        {
-            gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), x, y - 1);
-            return TRUE;
-        }
-    }
-}
-
-static void
-show_hide_fullscreen_toolbar (XedWindow *window,
-                              gboolean show,
-                              gint height)
-{
-    GtkSettings *settings;
-    gboolean enable_animations;
-
-    settings = gtk_widget_get_settings (GTK_WIDGET(window));
-    g_object_get (G_OBJECT(settings), "gtk-enable-animations", &enable_animations, NULL);
-
-    if (enable_animations)
-    {
-        window->priv->fullscreen_animation_enter = show;
-        if (window->priv->fullscreen_animation_timeout_id == 0)
-        {
-            window->priv->fullscreen_animation_timeout_id = g_timeout_add (FULLSCREEN_ANIMATION_SPEED,
-                                                                    (GSourceFunc) run_fullscreen_animation, window);
-        }
-    }
-    else
-    {
-        GdkRectangle fs_rect;
-        GdkScreen *screen;
-        screen = gtk_window_get_screen (GTK_WINDOW(window));
-        gdk_screen_get_monitor_geometry (screen,
-                    gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET(window))),
-                    &fs_rect);
-
-        if (show)
-        {
-            gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), fs_rect.x, fs_rect.y);
-        }
-        else
-        {
-            gtk_window_move (GTK_WINDOW(window->priv->fullscreen_controls), fs_rect.x, fs_rect.y - height + 1);
-        }
-    }
-
-}
-
 static gboolean
-on_fullscreen_controls_enter_notify_event (GtkWidget *widget,
+on_fullscreen_controls_enter_notify_event (GtkWidget        *widget,
                                            GdkEventCrossing *event,
-                                           XedWindow *window)
+                                           XedWindow        *window)
 {
-    show_hide_fullscreen_toolbar (window, TRUE, 0);
+    gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), TRUE);
+
     return FALSE;
 }
 
 static gboolean
-on_fullscreen_controls_leave_notify_event (GtkWidget *widget,
+on_fullscreen_controls_leave_notify_event (GtkWidget        *widget,
                                            GdkEventCrossing *event,
-                                           XedWindow *window)
+                                           XedWindow        *window)
 {
-    GdkDisplay *display;
-    GdkScreen *screen;
-    gint w, h;
-    gint x, y;
-
-    display = gdk_display_get_default ();
-    screen = gtk_window_get_screen (GTK_WINDOW(window));
-
-    gtk_window_get_size (GTK_WINDOW(window->priv->fullscreen_controls), &w, &h);
-    gdk_display_get_pointer (display, &screen, &x, &y, NULL);
-
-    /* gtk seems to emit leave notify when clicking on tool items,
-     * work around it by checking the coordinates
-     */
-    if (y >= h)
-    {
-        show_hide_fullscreen_toolbar (window, FALSE, h);
-    }
+    gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), FALSE);
 
     return FALSE;
 }
@@ -2783,6 +2648,9 @@ fullscreen_controls_build (XedWindow *window)
     XedWindowPrivate *priv = window->priv;
     GtkAction *action;
     GtkWidget *box;
+    GtkWidget *toolbar;
+    GtkWidget *toolitem;
+    GtkWidget *toolbox;
     GtkWidget *fullscreen_btn;
     GtkWidget *separator;
     GtkWidget *button;
@@ -2792,17 +2660,23 @@ fullscreen_controls_build (XedWindow *window)
         return;
     }
 
-    priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP);
+    priv->fullscreen_controls = gtk_revealer_new ();
+    gtk_widget_set_valign (priv->fullscreen_controls, GTK_ALIGN_START);
+    gtk_container_add (GTK_CONTAINER (priv->fullscreen_eventbox), priv->fullscreen_controls);
 
-    gtk_window_set_transient_for (GTK_WINDOW (priv->fullscreen_controls), GTK_WINDOW (&window->window));
+    toolbar = gtk_toolbar_new ();
+    toolitem = gtk_tool_item_new ();
+    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (toolitem), 0);
 
-    window->priv->fullscreen_controls_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (window->priv->fullscreen_controls_container), 6);
-    gtk_container_add (GTK_CONTAINER (priv->fullscreen_controls), window->priv->fullscreen_controls_container);
+    toolbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "primary-toolbar");
+    gtk_container_add (GTK_CONTAINER (toolitem), toolbox);
+    gtk_container_add (GTK_CONTAINER (priv->fullscreen_controls), toolbar);
 
     box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_widget_set_vexpand (box, FALSE);
-    gtk_box_pack_start (GTK_BOX (window->priv->fullscreen_controls_container), box, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (toolbox), box, FALSE, FALSE, 0);
 
     action = gtk_action_group_get_action (window->priv->always_sensitive_action_group, "FileNew");
     button = create_toolbar_button (action);
@@ -2858,13 +2732,15 @@ fullscreen_controls_build (XedWindow *window)
     fullscreen_btn = create_toolbar_button (action);
     gtk_box_pack_end (GTK_BOX (box), fullscreen_btn, FALSE, FALSE, 0);
 
-    gtk_widget_show_all (window->priv->fullscreen_controls_container);
+    gtk_widget_show_all (toolbox);
+
+    g_signal_connect (priv->fullscreen_eventbox, "enter-notify-event",
+                      G_CALLBACK (on_fullscreen_controls_enter_notify_event), window);
 
-    g_signal_connect(priv->fullscreen_controls, "enter-notify-event",
-                     G_CALLBACK (on_fullscreen_controls_enter_notify_event), window);
+    g_signal_connect (priv->fullscreen_eventbox, "leave-notify-event",
+                      G_CALLBACK (on_fullscreen_controls_leave_notify_event), window);
 
-    g_signal_connect(priv->fullscreen_controls, "leave-notify-event",
-                     G_CALLBACK (on_fullscreen_controls_leave_notify_event), window);
+    gtk_widget_set_size_request (priv->fullscreen_eventbox, -1, 1);
 }
 
 static void
@@ -3531,14 +3407,7 @@ check_window_is_active (XedWindow *window,
 {
     if (window->priv->window_state & GDK_WINDOW_STATE_FULLSCREEN)
     {
-        if (gtk_window_is_active (GTK_WINDOW(window)))
-        {
-            gtk_widget_show (window->priv->fullscreen_controls);
-        }
-        else
-        {
-            gtk_widget_hide (window->priv->fullscreen_controls);
-        }
+        gtk_widget_set_visible (window->priv->fullscreen_eventbox, gtk_window_is_active (GTK_WINDOW (window)));
     }
 }
 
@@ -3606,7 +3475,6 @@ xed_window_init (XedWindow *window)
     window->priv->inhibition_cookie = 0;
     window->priv->dispose_has_run = FALSE;
     window->priv->fullscreen_controls = NULL;
-    window->priv->fullscreen_animation_timeout_id = 0;
     window->priv->editor_settings = g_settings_new ("org.x.editor.preferences.editor");
     window->priv->ui_settings = g_settings_new ("org.x.editor.preferences.ui");
 
@@ -3623,9 +3491,16 @@ xed_window_init (XedWindow *window)
     gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "xed-window");
 
     main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-    gtk_container_add (GTK_CONTAINER (window), main_box);
+    window->priv->fullscreen_overlay = gtk_overlay_new ();
+    gtk_container_add (GTK_CONTAINER (window->priv->fullscreen_overlay), main_box);
+    gtk_container_add (GTK_CONTAINER (window), window->priv->fullscreen_overlay);
+    gtk_widget_show (window->priv->fullscreen_overlay);
     gtk_widget_show (main_box);
 
+    window->priv->fullscreen_eventbox = gtk_event_box_new ();
+    gtk_widget_set_valign (window->priv->fullscreen_eventbox, GTK_ALIGN_START);
+    gtk_overlay_add_overlay (GTK_OVERLAY (window->priv->fullscreen_overlay), window->priv->fullscreen_eventbox);
+
     /* Add menu bar and toolbar bar */
     create_menu_bar_and_toolbar (window, main_box);
 
@@ -4324,7 +4199,8 @@ _xed_window_fullscreen (XedWindow *window)
     gtk_widget_hide (window->priv->statusbar);
 
     fullscreen_controls_build (window);
-    fullscreen_controls_show (window);
+
+    gtk_widget_show_all (window->priv->fullscreen_eventbox);
 }
 
 void
@@ -4361,7 +4237,7 @@ _xed_window_unfullscreen (XedWindow *window)
     }
     g_signal_handlers_unblock_by_func (window->priv->statusbar, statusbar_visibility_changed, window);
 
-    gtk_widget_hide (window->priv->fullscreen_controls);
+    gtk_widget_hide (window->priv->fullscreen_eventbox);
 }
 
 gboolean

From a9070a43c1a32417d28f26505070f7997a968a5f Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 01:03:23 -0800
Subject: [PATCH 04/14] xed-status-combo-box: Remove some deprecated css
 functionality

This stuff is deprecated and just spams warnings so clean it up.
---
 xed/xed-status-combo-box.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/xed/xed-status-combo-box.c b/xed/xed-status-combo-box.c
index 9d45981..ea195cc 100644
--- a/xed/xed-status-combo-box.c
+++ b/xed/xed-status-combo-box.c
@@ -141,18 +141,14 @@ xed_status_combo_box_changed (XedStatusComboBox *combo,
 static void
 xed_status_combo_box_class_init (XedStatusComboBoxClass *klass)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
     static const gchar style[] =
         "* {\n"
-          "-GtkButton-default-border : 0;\n"
-          "-GtkButton-default-outside-border : 0;\n"
-          "-GtkButton-inner-border: 0;\n"
-          "-GtkWidget-focus-line-width : 0;\n"
-          "-GtkWidget-focus-padding : 0;\n"
           "padding: 2px;\n"
         "}";
 
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
     object_class->finalize = xed_status_combo_box_finalize;
     object_class->get_property = xed_status_combo_box_get_property;
     object_class->set_property = xed_status_combo_box_set_property;

From 11d1a3d046d92792034ad460259ae75283e6ade5 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 01:18:56 -0800
Subject: [PATCH 05/14] xed-view-frame: Fix the css for the minimap frame

This makes it work in gtk3.20+
---
 xed/resources/css/xed-style.css | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xed/resources/css/xed-style.css b/xed/resources/css/xed-style.css
index 984ca8a..a910576 100644
--- a/xed/resources/css/xed-style.css
+++ b/xed/resources/css/xed-style.css
@@ -1,7 +1,7 @@
-.xed-map-frame:dir(ltr) {
+.xed-map-frame:dir(ltr) border {
     border-width: 0 0 0 1px;
 }
 
-.xed-map-frame:dir(rtl) {
+.xed-map-frame:dir(rtl) border {
     border-width: 0 1px 0 0;
-}
\ No newline at end of file
+}

From 074894ffb0b881969488cf1d4df3ab079a6b8848 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 01:31:43 -0800
Subject: [PATCH 06/14] xed-notebook: Clean up some gtk3.20+ conditionals

Since we are moving to gtk3.22 we can clean these up.
---
 xed/xed-notebook.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/xed/xed-notebook.c b/xed/xed-notebook.c
index 481afa5..6e13d4b 100644
--- a/xed/xed-notebook.c
+++ b/xed/xed-notebook.c
@@ -714,11 +714,9 @@ xed_notebook_init (XedNotebook *notebook)
     notebook->priv->tab_scrolling_enabled = g_settings_get_boolean (notebook->priv->ui_settings, "enable-tab-scrolling");
 
     gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
-
-#if GTK_CHECK_VERSION (3, 20, 0)
-        gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
-#endif
+    gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+    gtk_container_set_border_width (GTK_CONTAINER (notebook), 0);
 
     g_signal_connect (notebook, "button-press-event",
                       (GCallback)button_press_cb, NULL);

From 5597fe21b3edc173874d9f1eb419c1afda53785c Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 03:22:03 -0800
Subject: [PATCH 07/14] Add a shortcuts window

---
 xed/resources/ui/xed-shortcuts.ui | 330 ++++++++++++++++++++++++++++++++++++++
 xed/resources/ui/xed-ui.xml       |   2 +
 xed/resources/xed.gresource.xml   |   3 +-
 xed/xed-commands-help.c           |  32 +++-
 xed/xed-commands.h                |   1 +
 xed/xed-ui.h                      |   2 +
 6 files changed, 368 insertions(+), 2 deletions(-)
 create mode 100644 xed/resources/ui/xed-shortcuts.ui

diff --git a/xed/resources/ui/xed-shortcuts.ui b/xed/resources/ui/xed-shortcuts.ui
new file mode 100644
index 0000000..bd9b628
--- /dev/null
+++ b/xed/resources/ui/xed-shortcuts.ui
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.17 -->
+  <object class="GtkShortcutsWindow" id="shortcuts-xed">
+    <property name="modal">1</property>
+    <child>
+      <object class="GtkShortcutsSection">
+        <property name="visible">1</property>
+        <property name="section-name">shortcuts</property>
+        <property name="max-height">12</property>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Documents</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;N</property>
+                <property name="title" translatable="yes">Create a new document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;O</property>
+                <property name="title" translatable="yes">Open a document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;S</property>
+                <property name="title" translatable="yes">Save the document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;S</property>
+                <property name="title" translatable="yes">Save the document with a new filename</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;L</property>
+                <property name="title" translatable="yes">Save all the documents</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;W</property>
+                <property name="title" translatable="yes">Close the document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;W</property>
+                <property name="title" translatable="yes">Close all the documents</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;Alt&gt;Page_Down</property>
+                <property name="title" translatable="yes">Switch to the next document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;Alt&gt;Page_Up</property>
+                <property name="title" translatable="yes">Switch to the previous document</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Alt&gt;1...9</property>
+                <property name="title" translatable="yes">Switch to the first - ninth document</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Windows and Panes</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">F9</property>
+                <property name="title" translatable="yes">Show side pane</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;F9</property>
+                <property name="title" translatable="yes">Show bottom pane</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">F11</property>
+                <property name="title" translatable="yes">Fullscreen on / off</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;Q</property>
+                <property name="title" translatable="yes">Quit the application</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Find and Replace</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;F</property>
+                <property name="title" translatable="yes">Find</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;G</property>
+                <property name="title" translatable="yes">Find the next match</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;Shift&gt;G</property>
+                <property name="title" translatable="yes">Find the previous match</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;H</property>
+                <property name="title" translatable="yes">Find and Replace</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;I</property>
+                <property name="title" translatable="yes">Go to line</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Copy and Paste</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;C</property>
+                <property name="title" translatable="yes">Copy selected text to clipboard</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;X</property>
+                <property name="title" translatable="yes">Cut selected text to clipboard</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;V</property>
+                <property name="title" translatable="yes">Paste text from clipboard</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Undo and Redo</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;Z</property>
+                <property name="title" translatable="yes">Undo previous command</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;Y</property>
+                <property name="title" translatable="yes">Redo previous command</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Selection</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;A</property>
+                <property name="title" translatable="yes">Select all text</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Editing</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">Insert</property>
+                <property name="title" translatable="yes">Toggle insert / overwrite</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;D</property>
+                <property name="title" translatable="yes">Delete current line</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;alt&gt;Up</property>
+                <property name="title" translatable="yes">Move current line up</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;alt&gt;Down</property>
+                <property name="title" translatable="yes">Move current line down</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;alt&gt;Left</property>
+                <property name="title" translatable="yes">Move current word left</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;alt&gt;Right</property>
+                <property name="title" translatable="yes">Move current word right</property>
+              </object>
+            </child>
+            <!--
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;U</property>
+                <property name="title" translatable="yes">Convert to uppercase</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;L</property>
+                <property name="title" translatable="yes">Convert to lowercase</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;asciitilde</property>
+                <property name="title" translatable="yes">Invert case</property>
+              </object>
+            </child>
+            -->
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;a</property>
+                <property name="title" translatable="yes">Increment number at cursor</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;x</property>
+                <property name="title" translatable="yes">Decrement number at cursor</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Tools</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;shift&gt;F7</property>
+                <property name="title" translatable="yes">Check spelling</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;P</property>
+                <property name="title" translatable="yes">Print the document</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/xed/resources/ui/xed-ui.xml b/xed/resources/ui/xed-ui.xml
index 10d48bf..91a01ba 100644
--- a/xed/resources/ui/xed-ui.xml
+++ b/xed/resources/ui/xed-ui.xml
@@ -123,6 +123,8 @@
     <menu name="HelpMenu" action="Help">
       <menuitem name="HelpContentsMenu" action="HelpContents"/>
       <menuitem name="HelpAboutMenu" action="HelpAbout"/>
+      <menuitem name="HelpAboutMenu" action="HelpAbout"/>
+      <menuitem name="HelpShortcutsMenu" action="HelpShortcuts"/>
     </menu>
   </menubar>
 
diff --git a/xed/resources/xed.gresource.xml b/xed/resources/xed.gresource.xml
index b02bde6..0a55cb5 100644
--- a/xed/resources/xed.gresource.xml
+++ b/xed/resources/xed.gresource.xml
@@ -6,7 +6,8 @@
     <file preprocess="xml-stripblanks">ui/xed-preferences-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/xed-print-preferences.ui</file>
     <file preprocess="xml-stripblanks">ui/xed-searchbar.ui</file>
+    <file preprocess="xml-stripblanks">ui/xed-shortcuts.ui</file>
     <file preprocess="xml-stripblanks">ui/xed-view-frame.ui</file>
     <file>css/xed-style.css</file>
   </gresource>
-</gresources>
\ No newline at end of file
+</gresources>
diff --git a/xed/xed-commands-help.c b/xed/xed-commands-help.c
index b031339..769ddc2 100644
--- a/xed/xed-commands-help.c
+++ b/xed/xed-commands-help.c
@@ -46,7 +46,7 @@
 void _xed_cmd_help_contents (GtkAction *action,
                              XedWindow *window)
 {
-    xed_debug(DEBUG_COMMANDS);
+    xed_debug (DEBUG_COMMANDS);
 
     xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (window), NULL, NULL);
 }
@@ -67,3 +67,33 @@ void _xed_cmd_help_about (GtkAction *action,
         "website", "http://github.com/linuxmint/xed",
         NULL);
 }
+
+void
+_xed_cmd_help_keyboard_shortcuts (GtkAction *action,
+                                  XedWindow *window)
+{
+    static GtkWidget *shortcuts_window;
+
+    xed_debug (DEBUG_COMMANDS);
+
+    if (shortcuts_window == NULL)
+    {
+        GtkBuilder *builder;
+
+        builder = gtk_builder_new_from_resource ("/org/x/editor/ui/xed-shortcuts.ui");
+        shortcuts_window = GTK_WIDGET (gtk_builder_get_object (builder, "shortcuts-xed"));
+
+        g_signal_connect (shortcuts_window, "destroy",
+                          G_CALLBACK (gtk_widget_destroyed), &shortcuts_window);
+
+        g_object_unref (builder);
+    }
+
+    if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (shortcuts_window)))
+    {
+        gtk_window_set_transient_for (GTK_WINDOW (shortcuts_window), GTK_WINDOW (window));
+    }
+
+    gtk_widget_show_all (shortcuts_window);
+    gtk_window_present (GTK_WINDOW (shortcuts_window));
+}
diff --git a/xed/xed-commands.h b/xed/xed-commands.h
index 679bc1e..005e64a 100644
--- a/xed/xed-commands.h
+++ b/xed/xed-commands.h
@@ -66,6 +66,7 @@ void _xed_cmd_documents_move_to_new_window (GtkAction *action, XedWindow *window
 
 void _xed_cmd_help_contents (GtkAction *action, XedWindow *window);
 void _xed_cmd_help_about (GtkAction *action, XedWindow *window);
+void _xed_cmd_help_keyboard_shortcuts (GtkAction *action, XedWindow *window);
 
 void _xed_cmd_file_close_tab (XedTab *tab, XedWindow *window);
 
diff --git a/xed/xed-ui.h b/xed/xed-ui.h
index 24e97b5..5f32f9f 100644
--- a/xed/xed-ui.h
+++ b/xed/xed-ui.h
@@ -67,6 +67,8 @@ static const GtkActionEntry xed_always_sensitive_menu_entries[] =
 	 N_("Open the xed manual"), G_CALLBACK (_xed_cmd_help_contents) },
 	{ "HelpAbout", "help-about-symbolic", N_("_About"), NULL,
 	 N_("About this application"), G_CALLBACK (_xed_cmd_help_about) },
+    { "HelpShortcuts", NULL, N_("_Keyboard Shortcuts"), NULL,
+     N_("Show the keyboard shortcuts dialog"), G_CALLBACK (_xed_cmd_help_keyboard_shortcuts) },
 
 	/* Fullscreen toolbar */
 	{ "LeaveFullscreen", "view-restore-symbolic", NULL,

From cfe89c32d50fcbd1faad659ba2aefa5801557808 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 12:12:48 -0800
Subject: [PATCH 08/14] xed-view: Add shortcuts for change case

Closes https://github.com/linuxmint/xed/issues/154
---
 xed/resources/ui/xed-shortcuts.ui | 49 +++++++++++++++++++++------------------
 xed/xed-view.c                    | 32 +++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/xed/resources/ui/xed-shortcuts.ui b/xed/resources/ui/xed-shortcuts.ui
index bd9b628..ad6ae4d 100644
--- a/xed/resources/ui/xed-shortcuts.ui
+++ b/xed/resources/ui/xed-shortcuts.ui
@@ -219,6 +219,26 @@
             </child>
           </object>
         </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title" translatable="yes">Tools</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;shift&gt;F7</property>
+                <property name="title" translatable="yes">Check spelling</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;P</property>
+                <property name="title" translatable="yes">Print the document</property>
+              </object>
+            </child>
+          </object>
+        </child>
         <child>
           <object class="GtkShortcutsGroup">
             <property name="visible">1</property>
@@ -265,7 +285,6 @@
                 <property name="title" translatable="yes">Move current word right</property>
               </object>
             </child>
-            <!--
             <child>
               <object class="GtkShortcutsShortcut">
                 <property name="visible">1</property>
@@ -280,6 +299,13 @@
                 <property name="title" translatable="yes">Convert to lowercase</property>
               </object>
             </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;ctrl&gt;T</property>
+                <property name="title" translatable="yes">Convert to title case</property>
+              </object>
+            </child>
             <child>
               <object class="GtkShortcutsShortcut">
                 <property name="visible">1</property>
@@ -287,7 +313,6 @@
                 <property name="title" translatable="yes">Invert case</property>
               </object>
             </child>
-            -->
             <child>
               <object class="GtkShortcutsShortcut">
                 <property name="visible">1</property>
@@ -304,26 +329,6 @@
             </child>
           </object>
         </child>
-        <child>
-          <object class="GtkShortcutsGroup">
-            <property name="visible">1</property>
-            <property name="title" translatable="yes">Tools</property>
-            <child>
-              <object class="GtkShortcutsShortcut">
-                <property name="visible">1</property>
-                <property name="accelerator">&lt;shift&gt;F7</property>
-                <property name="title" translatable="yes">Check spelling</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkShortcutsShortcut">
-                <property name="visible">1</property>
-                <property name="accelerator">&lt;ctrl&gt;P</property>
-                <property name="title" translatable="yes">Print the document</property>
-              </object>
-            </child>
-          </object>
-        </child>
       </object>
     </child>
   </object>
diff --git a/xed/xed-view.c b/xed/xed-view.c
index 0099553..0a60133 100644
--- a/xed/xed-view.c
+++ b/xed/xed-view.c
@@ -607,8 +607,36 @@ xed_view_class_init (XedViewClass *klass)
 
     binding_set = gtk_binding_set_by_class (klass);
 
-    gtk_binding_entry_add_signal (binding_set, GDK_KEY_d, GDK_CONTROL_MASK, "delete_from_cursor", 2, G_TYPE_ENUM,
-                                  GTK_DELETE_PARAGRAPHS, G_TYPE_INT, 1);
+    gtk_binding_entry_add_signal (binding_set,
+                                  GDK_KEY_d,
+                                  GDK_CONTROL_MASK,
+                                  "delete_from_cursor", 2,
+                                  G_TYPE_ENUM, GTK_DELETE_PARAGRAPHS,
+                                  G_TYPE_INT, 1);
+
+    gtk_binding_entry_add_signal (binding_set,
+                                  GDK_KEY_u,
+                                  GDK_CONTROL_MASK,
+                                  "change_case", 1,
+                                  G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_UPPER);
+
+    gtk_binding_entry_add_signal (binding_set,
+                                  GDK_KEY_l,
+                                  GDK_CONTROL_MASK,
+                                  "change_case", 1,
+                                  G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_LOWER);
+
+    gtk_binding_entry_add_signal (binding_set,
+                                  GDK_KEY_asciitilde,
+                                  GDK_CONTROL_MASK,
+                                  "change_case", 1,
+                                  G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_TOGGLE);
+
+    gtk_binding_entry_add_signal (binding_set,
+                                  GDK_KEY_t,
+                                  GDK_CONTROL_MASK,
+                                  "change_case", 1,
+                                  G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_TITLE);
 }
 
 /**

From 1d7694eef7b2d0d8a0e28d160375b7ea54e8d513 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Mon, 4 Dec 2017 22:39:28 -0800
Subject: [PATCH 09/14] debian: Add --enable-silent-rules to debian/rules

---
 debian/rules | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/debian/rules b/debian/rules
index b6118b3..529c008 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,7 +14,7 @@ override_dh_auto_configure:
 	# upstream tarball is without configure. autogen.sh will create it
 	NOCONFIGURE=1 ./autogen.sh
 	dh_auto_configure $(DHFLAGS) -- \
-		--disable-silent-rules \
+		--enable-silent-rules \
 		--libexecdir=/usr/lib/ \
 		--enable-gtk-doc
 

From e0ceb3f0a576c364264e2d3d499754066c26124a Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Tue, 5 Dec 2017 00:10:49 -0800
Subject: [PATCH 10/14] css: Add support for Adwaita

---
 xed/resources/css/xed.adwaita.css | 17 +++++++++++++
 xed/resources/xed.gresource.xml   |  1 +
 xed/xed-app.c                     | 50 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 xed/resources/css/xed.adwaita.css

diff --git a/xed/resources/css/xed.adwaita.css b/xed/resources/css/xed.adwaita.css
new file mode 100644
index 0000000..600a9d2
--- /dev/null
+++ b/xed/resources/css/xed.adwaita.css
@@ -0,0 +1,17 @@
+.xed-window .primary-toolbar {
+    border: 0px solid @borders;
+    border-bottom-width: 1px;
+}
+
+.xed-statusbar {
+    border: 0px solid @borders;
+    border-top-width: 1px;
+}
+
+.xed-searchbar {
+    box-shadow: inset 0 1px @borders;
+}
+
+.xed-statusbar button {
+    padding: 0 4px;
+}
diff --git a/xed/resources/xed.gresource.xml b/xed/resources/xed.gresource.xml
index 0a55cb5..29a9aed 100644
--- a/xed/resources/xed.gresource.xml
+++ b/xed/resources/xed.gresource.xml
@@ -9,5 +9,6 @@
     <file preprocess="xml-stripblanks">ui/xed-shortcuts.ui</file>
     <file preprocess="xml-stripblanks">ui/xed-view-frame.ui</file>
     <file>css/xed-style.css</file>
+    <file>css/xed.adwaita.css</file>
   </gresource>
 </gresources>
diff --git a/xed/xed-app.c b/xed/xed-app.c
index 785e162..ef0f169 100644
--- a/xed/xed-app.c
+++ b/xed/xed-app.c
@@ -223,6 +223,54 @@ set_initial_theme_style (XedApp *app)
     }
 }
 
+static void
+theme_changed (GtkSettings *settings,
+               GParamSpec  *pspec,
+               gpointer     data)
+{
+    static GtkCssProvider *provider;
+    gchar *theme;
+    GdkScreen *screen;
+
+    g_object_get (settings, "gtk-theme-name", &theme, NULL);
+    screen = gdk_screen_get_default ();
+
+    if (g_str_equal (theme, "Adwaita"))
+    {
+        if (provider == NULL)
+        {
+            GFile *file;
+
+            provider = gtk_css_provider_new ();
+            file = g_file_new_for_uri ("resource:///org/x/editor/css/xed.adwaita.css");
+            gtk_css_provider_load_from_file (provider, file, NULL);
+            g_object_unref (file);
+        }
+
+        gtk_style_context_add_provider_for_screen (screen,
+                                                   GTK_STYLE_PROVIDER (provider),
+                                                   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    }
+    else if (provider != NULL)
+    {
+        gtk_style_context_remove_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider));
+        g_clear_object (&provider);
+    }
+
+    g_free (theme);
+}
+
+static void
+setup_theme_extensions (void)
+{
+    GtkSettings *settings;
+
+    settings = gtk_settings_get_default ();
+    g_signal_connect (settings, "notify::gtk-theme-name",
+                      G_CALLBACK (theme_changed), NULL);
+    theme_changed (settings, NULL, NULL);
+}
+
 static void
 xed_app_startup (GApplication *application)
 {
@@ -251,6 +299,8 @@ xed_app_startup (GApplication *application)
     gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), icon_dir);
     g_free (icon_dir);
 
+    setup_theme_extensions ();
+
 #ifndef ENABLE_GVFS_METADATA
     /* Setup metadata-manager */
     cache_dir = xed_dirs_get_user_cache_dir ();

From 20e63815ca9861c4c18976e9e1f50ad527aa69af Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Sat, 9 Dec 2017 01:06:28 -0800
Subject: [PATCH 11/14] xed-searchbar: Fix the size of the searchbar close
 button

The theming for this changed in gtk3.20+. Get it back to the proper size and
theme it in xed-style.css instead of hard coding it.
---
 xed/resources/css/xed-style.css | 6 ++++++
 xed/xed-searchbar.c             | 8 +-------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/xed/resources/css/xed-style.css b/xed/resources/css/xed-style.css
index a910576..1807e87 100644
--- a/xed/resources/css/xed-style.css
+++ b/xed/resources/css/xed-style.css
@@ -5,3 +5,9 @@
 .xed-map-frame:dir(rtl) border {
     border-width: 0 1px 0 0;
 }
+
+.xed-searchbar .close-button {
+    padding: 0;
+    min-height: 0;
+    min-width: 0;
+}
diff --git a/xed/xed-searchbar.c b/xed/xed-searchbar.c
index 94b33c2..9d705a6 100755
--- a/xed/xed-searchbar.c
+++ b/xed/xed-searchbar.c
@@ -659,11 +659,8 @@ xed_searchbar_init (XedSearchbar *searchbar)
 {
     GtkWidget *content;
     GtkSizeGroup *size_group;
-    GtkStyleContext *context;
-    GtkCssProvider *provider;
     GtkBuilder *builder;
     gchar *root_objects[] = { "searchbar_content", NULL };
-    const gchar *data = ".button {padding: 0;}";
 
     searchbar->priv = XED_SEARCHBAR_GET_PRIVATE (searchbar);
 
@@ -709,10 +706,7 @@ xed_searchbar_init (XedSearchbar *searchbar)
     gtk_label_set_mnemonic_widget (GTK_LABEL (searchbar->priv->search_label), searchbar->priv->search_entry);
     gtk_label_set_mnemonic_widget (GTK_LABEL (searchbar->priv->replace_label), searchbar->priv->replace_entry);
 
-    provider = gtk_css_provider_new ();
-    context = gtk_widget_get_style_context (searchbar->priv->close_button);
-    gtk_css_provider_load_from_data (provider, data, -1, NULL);
-    gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    gtk_style_context_add_class (gtk_widget_get_style_context (searchbar->priv->close_button), "close-button");
 
     size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
     gtk_size_group_add_widget (size_group, GTK_WIDGET (searchbar->priv->find_button));

From a213c70a3addcd1693c266a913390a8fa0488afe Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Sun, 10 Dec 2017 15:23:37 -0800
Subject: [PATCH 12/14] xed-spell-checker.c: Clean up the code formatting

---
 plugins/spell/xed-spell-checker.c | 734 ++++++++++++++++++++------------------
 1 file changed, 389 insertions(+), 345 deletions(-)

diff --git a/plugins/spell/xed-spell-checker.c b/plugins/spell/xed-spell-checker.c
index b158bd8..e45e926 100644
--- a/plugins/spell/xed-spell-checker.c
+++ b/plugins/spell/xed-spell-checker.c
@@ -44,27 +44,27 @@
 
 struct _XedSpellChecker
 {
-	GObject parent_instance;
+    GObject parent_instance;
 
-	EnchantDict                     *dict;
-	EnchantBroker                   *broker;
-	const XedSpellCheckerLanguage *active_lang;
+    EnchantDict                     *dict;
+    EnchantBroker                   *broker;
+    const XedSpellCheckerLanguage *active_lang;
 };
 
 /* GObject properties */
 enum {
-	PROP_0 = 0,
-	PROP_LANGUAGE,
-	LAST_PROP
+    PROP_0 = 0,
+    PROP_LANGUAGE,
+    LAST_PROP
 };
 
 /* Signals */
 enum {
-	ADD_WORD_TO_PERSONAL = 0,
-	ADD_WORD_TO_SESSION,
-	SET_LANGUAGE,
-	CLEAR_SESSION,
-	LAST_SIGNAL
+    ADD_WORD_TO_PERSONAL = 0,
+    ADD_WORD_TO_SESSION,
+    SET_LANGUAGE,
+    CLEAR_SESSION,
+    LAST_SIGNAL
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -72,415 +72,453 @@ static guint signals[LAST_SIGNAL] = { 0 };
 G_DEFINE_TYPE(XedSpellChecker, xed_spell_checker, G_TYPE_OBJECT)
 
 static void
-xed_spell_checker_set_property (GObject *object,
-			   guint prop_id,
-			   const GValue *value,
-			   GParamSpec *pspec)
+xed_spell_checker_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
 {
-	/*
-	XedSpellChecker *spell = XED_SPELL_CHECKER (object);
-	*/
-
-	switch (prop_id)
-	{
-		case PROP_LANGUAGE:
-			/* TODO */
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-	}
+    /*
+    XedSpellChecker *spell = XED_SPELL_CHECKER (object);
+    */
+
+    switch (prop_id)
+    {
+        case PROP_LANGUAGE:
+            /* TODO */
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
 }
 
 static void
-xed_spell_checker_get_property (GObject *object,
-			   guint prop_id,
-			   GValue *value,
-			   GParamSpec *pspec)
+xed_spell_checker_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
 {
-	/*
-	XedSpellChecker *spell = XED_SPELL_CHECKER (object);
-	*/
-
-	switch (prop_id)
-	{
-		case PROP_LANGUAGE:
-			/* TODO */
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-	}
+    /*
+    XedSpellChecker *spell = XED_SPELL_CHECKER (object);
+    */
+
+    switch (prop_id)
+    {
+        case PROP_LANGUAGE:
+            /* TODO */
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
 }
 
 static void
 xed_spell_checker_finalize (GObject *object)
 {
-	XedSpellChecker *spell_checker;
+    XedSpellChecker *spell_checker;
 
-	g_return_if_fail (XED_IS_SPELL_CHECKER (object));
+    g_return_if_fail (XED_IS_SPELL_CHECKER (object));
 
-	spell_checker = XED_SPELL_CHECKER (object);
+    spell_checker = XED_SPELL_CHECKER (object);
 
-	if (spell_checker->dict != NULL)
-		enchant_broker_free_dict (spell_checker->broker, spell_checker->dict);
+    if (spell_checker->dict != NULL)
+    {
+        enchant_broker_free_dict (spell_checker->broker, spell_checker->dict);
+    }
 
-	if (spell_checker->broker != NULL)
-		enchant_broker_free (spell_checker->broker);
+    if (spell_checker->broker != NULL)
+    {
+        enchant_broker_free (spell_checker->broker);
+    }
 
-	G_OBJECT_CLASS (xed_spell_checker_parent_class)->finalize (object);
+    G_OBJECT_CLASS (xed_spell_checker_parent_class)->finalize (object);
 }
 
 static void
-xed_spell_checker_class_init (XedSpellCheckerClass * klass)
+xed_spell_checker_class_init (XedSpellCheckerClass *klass)
 {
-	GObjectClass *object_class;
-
-	object_class = G_OBJECT_CLASS (klass);
-
-	object_class->set_property = xed_spell_checker_set_property;
-	object_class->get_property = xed_spell_checker_get_property;
-
-	object_class->finalize = xed_spell_checker_finalize;
-
-	g_object_class_install_property (object_class,
-					 PROP_LANGUAGE,
-					 g_param_spec_pointer ("language",
-						 	      "Language",
-							      "The language used by the spell checker",
-							      G_PARAM_READWRITE));
-
-	signals[ADD_WORD_TO_PERSONAL] =
-	    g_signal_new ("add_word_to_personal",
-			  G_OBJECT_CLASS_TYPE (object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_personal),
-			  NULL, NULL,
-			  xed_marshal_VOID__STRING_INT,
-			  G_TYPE_NONE,
-			  2,
-			  G_TYPE_STRING,
-			  G_TYPE_INT);
-
-	signals[ADD_WORD_TO_SESSION] =
-	    g_signal_new ("add_word_to_session",
-			  G_OBJECT_CLASS_TYPE (object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_session),
-			  NULL, NULL,
-			  xed_marshal_VOID__STRING_INT,
-			  G_TYPE_NONE,
-			  2,
-			  G_TYPE_STRING,
-			  G_TYPE_INT);
-
-	signals[SET_LANGUAGE] =
-	    g_signal_new ("set_language",
-			  G_OBJECT_CLASS_TYPE (object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (XedSpellCheckerClass, set_language),
-			  NULL, NULL,
-			  xed_marshal_VOID__POINTER,
-			  G_TYPE_NONE,
-			  1,
-			  G_TYPE_POINTER);
-
-	signals[CLEAR_SESSION] =
-	    g_signal_new ("clear_session",
-			  G_OBJECT_CLASS_TYPE (object_class),
-			  G_SIGNAL_RUN_LAST,
-			  G_STRUCT_OFFSET (XedSpellCheckerClass, clear_session),
-			  NULL, NULL,
-			  xed_marshal_VOID__VOID,
-			  G_TYPE_NONE,
-			  0);
+    GObjectClass *object_class;
+
+    object_class = G_OBJECT_CLASS (klass);
+
+    object_class->set_property = xed_spell_checker_set_property;
+    object_class->get_property = xed_spell_checker_get_property;
+
+    object_class->finalize = xed_spell_checker_finalize;
+
+    g_object_class_install_property (object_class,
+                                     PROP_LANGUAGE,
+                                     g_param_spec_pointer ("language",
+                                                           "Language",
+                                                           "The language used by the spell checker",
+                                                           G_PARAM_READWRITE));
+
+    signals[ADD_WORD_TO_PERSONAL] =
+        g_signal_new ("add_word_to_personal",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_personal),
+                      NULL, NULL,
+                      xed_marshal_VOID__STRING_INT,
+                      G_TYPE_NONE,
+                      2,
+                      G_TYPE_STRING,
+                      G_TYPE_INT);
+
+    signals[ADD_WORD_TO_SESSION] =
+        g_signal_new ("add_word_to_session",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_session),
+                      NULL, NULL,
+                      xed_marshal_VOID__STRING_INT,
+                      G_TYPE_NONE,
+                      2,
+                      G_TYPE_STRING,
+                      G_TYPE_INT);
+
+    signals[SET_LANGUAGE] =
+        g_signal_new ("set_language",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (XedSpellCheckerClass, set_language),
+                      NULL, NULL,
+                      xed_marshal_VOID__POINTER,
+                      G_TYPE_NONE,
+                      1,
+                      G_TYPE_POINTER);
+
+    signals[CLEAR_SESSION] =
+        g_signal_new ("clear_session",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (XedSpellCheckerClass, clear_session),
+                      NULL, NULL,
+                      xed_marshal_VOID__VOID,
+                      G_TYPE_NONE,
+                      0);
 }
 
 static void
 xed_spell_checker_init (XedSpellChecker *spell_checker)
 {
-	spell_checker->broker = enchant_broker_init ();
-	spell_checker->dict = NULL;
-	spell_checker->active_lang = NULL;
+    spell_checker->broker = enchant_broker_init ();
+    spell_checker->dict = NULL;
+    spell_checker->active_lang = NULL;
 }
 
 XedSpellChecker *
-xed_spell_checker_new	(void)
+xed_spell_checker_new (void)
 {
-	XedSpellChecker *spell;
+    XedSpellChecker *spell;
 
-	spell = XED_SPELL_CHECKER (
-			g_object_new (XED_TYPE_SPELL_CHECKER, NULL));
+    spell = XED_SPELL_CHECKER (g_object_new (XED_TYPE_SPELL_CHECKER, NULL));
 
-	g_return_val_if_fail (spell != NULL, NULL);
+    g_return_val_if_fail (spell != NULL, NULL);
 
-	return spell;
+    return spell;
 }
 
 static gboolean
 lazy_init (XedSpellChecker               *spell,
-	   const XedSpellCheckerLanguage *language)
+           const XedSpellCheckerLanguage *language)
 {
-	if (spell->dict != NULL)
-		return TRUE;
-
-	g_return_val_if_fail (spell->broker != NULL, FALSE);
-
-	spell->active_lang = NULL;
-
-	if (language != NULL)
-	{
-		spell->active_lang = language;
-	}
-	else
-	{
-		/* First try to get a default language */
-		const XedSpellCheckerLanguage *l;
-		gint i = 0;
-		const gchar * const *lang_tags = g_get_language_names ();
-
-		while (lang_tags [i])
-		{
-			l = xed_spell_checker_language_from_key (lang_tags [i]);
-
-			if (l != NULL)
-			{
-				spell->active_lang = l;
-				break;
-			}
-
-			i++;
-		}
-	}
-
-	/* Second try to get a default language */
-	if (spell->active_lang == NULL)
-		spell->active_lang = xed_spell_checker_language_from_key ("en_US");
-
-	/* Last try to get a default language */
-	if (spell->active_lang == NULL)
-	{
-		const GSList *langs;
-		langs = xed_spell_checker_get_available_languages ();
-		if (langs != NULL)
-			spell->active_lang = (const XedSpellCheckerLanguage *)langs->data;
-	}
-
-	if (spell->active_lang != NULL)
-	{
-		const gchar *key;
-
-		key = xed_spell_checker_language_to_key (spell->active_lang);
-
-		spell->dict = enchant_broker_request_dict (spell->broker,
-							   key);
-	}
-
-	if (spell->dict == NULL)
-	{
-		spell->active_lang = NULL;
-
-		if (language != NULL)
-			g_warning ("Spell checker plugin: cannot select a default language.");
-
-		return FALSE;
-	}
-
-	return TRUE;
+    if (spell->dict != NULL)
+    {
+        return TRUE;
+    }
+
+    g_return_val_if_fail (spell->broker != NULL, FALSE);
+
+    spell->active_lang = NULL;
+
+    if (language != NULL)
+    {
+        spell->active_lang = language;
+    }
+    else
+    {
+        /* First try to get a default language */
+        const XedSpellCheckerLanguage *l;
+        gint i = 0;
+        const gchar * const *lang_tags = g_get_language_names ();
+
+        while (lang_tags [i])
+        {
+            l = xed_spell_checker_language_from_key (lang_tags [i]);
+
+            if (l != NULL)
+            {
+                spell->active_lang = l;
+                break;
+            }
+
+            i++;
+        }
+    }
+
+    /* Second try to get a default language */
+    if (spell->active_lang == NULL)
+    {
+        spell->active_lang = xed_spell_checker_language_from_key ("en_US");
+    }
+
+    /* Last try to get a default language */
+    if (spell->active_lang == NULL)
+    {
+        const GSList *langs;
+        langs = xed_spell_checker_get_available_languages ();
+        if (langs != NULL)
+        {
+            spell->active_lang = (const XedSpellCheckerLanguage *)langs->data;
+        }
+    }
+
+    if (spell->active_lang != NULL)
+    {
+        const gchar *key;
+
+        key = xed_spell_checker_language_to_key (spell->active_lang);
+
+        spell->dict = enchant_broker_request_dict (spell->broker, key);
+    }
+
+    if (spell->dict == NULL)
+    {
+        spell->active_lang = NULL;
+
+        if (language != NULL)
+        {
+            g_warning ("Spell checker plugin: cannot select a default language.");
+        }
+
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 gboolean
 xed_spell_checker_set_language (XedSpellChecker               *spell,
-				  const XedSpellCheckerLanguage *language)
+                                const XedSpellCheckerLanguage *language)
 {
-	gboolean ret;
-
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
-
-	if (spell->dict != NULL)
-	{
-		enchant_broker_free_dict (spell->broker, spell->dict);
-		spell->dict = NULL;
-	}
-
-	ret = lazy_init (spell, language);
-
-	if (ret)
-		g_signal_emit (G_OBJECT (spell), signals[SET_LANGUAGE], 0, language);
-	else
-		g_warning ("Spell checker plugin: cannot use language %s.",
-		           xed_spell_checker_language_to_string (language));
-
-	return ret;
+    gboolean ret;
+
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+
+    if (spell->dict != NULL)
+    {
+        enchant_broker_free_dict (spell->broker, spell->dict);
+        spell->dict = NULL;
+    }
+
+    ret = lazy_init (spell, language);
+
+    if (ret)
+    {
+        g_signal_emit (G_OBJECT (spell), signals[SET_LANGUAGE], 0, language);
+    }
+    else
+    {
+        g_warning ("Spell checker plugin: cannot use language %s.", xed_spell_checker_language_to_string (language));
+    }
+    
+    return ret;
 }
 
 const XedSpellCheckerLanguage *
 xed_spell_checker_get_language (XedSpellChecker *spell)
 {
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL);
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL);
 
-	if (!lazy_init (spell, spell->active_lang))
-		return NULL;
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return NULL;
+    }
 
-	return spell->active_lang;
+    return spell->active_lang;
 }
 
 gboolean
 xed_spell_checker_check_word (XedSpellChecker *spell,
-				const gchar       *word,
-				gssize             len)
+                              const gchar     *word,
+                              gssize           len)
 {
-	gint enchant_result;
-	gboolean res = FALSE;
-
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
-	g_return_val_if_fail (word != NULL, FALSE);
-
-	if (!lazy_init (spell, spell->active_lang))
-		return FALSE;
-
-	if (len < 0)
-		len = strlen (word);
-
-	if (strcmp (word, "xed") == 0)
-		return TRUE;
-
-	if (xed_spell_utils_is_digit (word, len))
-		return TRUE;
-
-	g_return_val_if_fail (spell->dict != NULL, FALSE);
-	enchant_result = enchant_dict_check (spell->dict, word, len);
-
-	switch (enchant_result)
-	{
-		case -1:
-			/* error */
-			res = FALSE;
-
-			g_warning ("Spell checker plugin: error checking word '%s' (%s).",
-				   word, enchant_dict_get_error (spell->dict));
-
-			break;
-		case 1:
-			/* it is not in the directory */
-			res = FALSE;
-			break;
-		case 0:
-			/* is is in the directory */
-			res = TRUE;
-			break;
-		default:
-			g_return_val_if_reached (FALSE);
-	}
-
-	return res;
+    gint enchant_result;
+    gboolean res = FALSE;
+
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+    g_return_val_if_fail (word != NULL, FALSE);
+
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return FALSE;
+    }
+
+    if (len < 0)
+    {
+        len = strlen (word);
+    }
+
+    if (strcmp (word, "xed") == 0)
+    {
+        return TRUE;
+    }
+
+    if (xed_spell_utils_is_digit (word, len))
+    {
+        return TRUE;
+    }
+
+    g_return_val_if_fail (spell->dict != NULL, FALSE);
+    enchant_result = enchant_dict_check (spell->dict, word, len);
+
+    switch (enchant_result)
+    {
+        case -1:
+            /* error */
+            res = FALSE;
+
+            g_warning ("Spell checker plugin: error checking word '%s' (%s).",
+                   word, enchant_dict_get_error (spell->dict));
+
+            break;
+        case 1:
+            /* it is not in the directory */
+            res = FALSE;
+            break;
+        case 0:
+            /* is is in the directory */
+            res = TRUE;
+            break;
+        default:
+            g_return_val_if_reached (FALSE);
+    }
+
+    return res;
 }
 
 
 /* return NULL on error or if no suggestions are found */
 GSList *
 xed_spell_checker_get_suggestions (XedSpellChecker *spell,
-				     const gchar       *word,
-				     gssize             len)
+                                   const gchar     *word,
+                                   gssize           len)
 {
-	gchar **suggestions;
-	size_t n_suggestions = 0;
-	GSList *suggestions_list = NULL;
-	gint i;
+    gchar **suggestions;
+    size_t n_suggestions = 0;
+    GSList *suggestions_list = NULL;
+    gint i;
 
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL);
-	g_return_val_if_fail (word != NULL, NULL);
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL);
+    g_return_val_if_fail (word != NULL, NULL);
 
-	if (!lazy_init (spell, spell->active_lang))
-		return NULL;
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return NULL;
+    }
 
-	g_return_val_if_fail (spell->dict != NULL, NULL);
+    g_return_val_if_fail (spell->dict != NULL, NULL);
 
-	if (len < 0)
-		len = strlen (word);
+    if (len < 0)
+    {
+        len = strlen (word);
+    }
 
-	suggestions = enchant_dict_suggest (spell->dict, word, len, &n_suggestions);
+    suggestions = enchant_dict_suggest (spell->dict, word, len, &n_suggestions);
 
-	if (n_suggestions == 0)
-		return NULL;
+    if (n_suggestions == 0)
+    {
+        return NULL;
+    }
 
-	g_return_val_if_fail (suggestions != NULL, NULL);
+    g_return_val_if_fail (suggestions != NULL, NULL);
 
-	for (i = 0; i < (gint)n_suggestions; i++)
-	{
-		suggestions_list = g_slist_prepend (suggestions_list,
-						    suggestions[i]);
-	}
+    for (i = 0; i < (gint)n_suggestions; i++)
+    {
+        suggestions_list = g_slist_prepend (suggestions_list, suggestions[i]);
+    }
 
-	/* The single suggestions will be freed by the caller */
-	g_free (suggestions);
+    /* The single suggestions will be freed by the caller */
+    g_free (suggestions);
 
-	suggestions_list = g_slist_reverse (suggestions_list);
+    suggestions_list = g_slist_reverse (suggestions_list);
 
-	return suggestions_list;
+    return suggestions_list;
 }
 
 gboolean
 xed_spell_checker_add_word_to_personal (XedSpellChecker *spell,
-					  const gchar       *word,
-					  gssize             len)
+                                        const gchar     *word,
+                                        gssize           len)
 {
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
-	g_return_val_if_fail (word != NULL, FALSE);
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+    g_return_val_if_fail (word != NULL, FALSE);
 
-	if (!lazy_init (spell, spell->active_lang))
-		return FALSE;
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return FALSE;
+    }
 
-	g_return_val_if_fail (spell->dict != NULL, FALSE);
+    g_return_val_if_fail (spell->dict != NULL, FALSE);
 
-	if (len < 0)
-		len = strlen (word);
+    if (len < 0)
+    {
+        len = strlen (word);
+    }
 
-	enchant_dict_add_to_pwl (spell->dict, word, len);
+    enchant_dict_add_to_pwl (spell->dict, word, len);
 
-	g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_PERSONAL], 0, word, len);
+    g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_PERSONAL], 0, word, len);
 
-	return TRUE;
+    return TRUE;
 }
 
 gboolean
 xed_spell_checker_add_word_to_session (XedSpellChecker *spell,
-					 const gchar       *word,
-					 gssize             len)
+                                       const gchar     *word,
+                                       gssize           len)
 {
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
-	g_return_val_if_fail (word != NULL, FALSE);
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+    g_return_val_if_fail (word != NULL, FALSE);
 
-	if (!lazy_init (spell, spell->active_lang))
-		return FALSE;
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return FALSE;
+    }
 
-	g_return_val_if_fail (spell->dict != NULL, FALSE);
+    g_return_val_if_fail (spell->dict != NULL, FALSE);
 
-	if (len < 0)
-		len = strlen (word);
+    if (len < 0)
+    {
+        len = strlen (word);
+    }
 
-	enchant_dict_add_to_session (spell->dict, word, len);
+    enchant_dict_add_to_session (spell->dict, word, len);
 
-	g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_SESSION], 0, word, len);
+    g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_SESSION], 0, word, len);
 
-	return TRUE;
+    return TRUE;
 }
 
 gboolean
 xed_spell_checker_clear_session (XedSpellChecker *spell)
 {
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
 
-	/* free and re-request dictionary */
-	if (spell->dict != NULL)
-	{
-		enchant_broker_free_dict (spell->broker, spell->dict);
-		spell->dict = NULL;
-	}
+    /* free and re-request dictionary */
+    if (spell->dict != NULL)
+    {
+        enchant_broker_free_dict (spell->broker, spell->dict);
+        spell->dict = NULL;
+    }
 
-	if (!lazy_init (spell, spell->active_lang))
-		return FALSE;
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return FALSE;
+    }
 
-	g_signal_emit (G_OBJECT (spell), signals[CLEAR_SESSION], 0);
+    g_signal_emit (G_OBJECT (spell), signals[CLEAR_SESSION], 0);
 
-	return TRUE;
+    return TRUE;
 }
 
 /*
@@ -489,32 +527,38 @@ xed_spell_checker_clear_session (XedSpellChecker *spell)
  */
 gboolean
 xed_spell_checker_set_correction (XedSpellChecker *spell,
-				    const gchar       *word,
-				    gssize             w_len,
-				    const gchar       *replacement,
-				    gssize             r_len)
+                                  const gchar     *word,
+                                  gssize           w_len,
+                                  const gchar     *replacement,
+                                  gssize           r_len)
 {
-	g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
-	g_return_val_if_fail (word != NULL, FALSE);
-	g_return_val_if_fail (replacement != NULL, FALSE);
-
-	if (!lazy_init (spell, spell->active_lang))
-		return FALSE;
-
-	g_return_val_if_fail (spell->dict != NULL, FALSE);
-
-	if (w_len < 0)
-		w_len = strlen (word);
-
-	if (r_len < 0)
-		r_len = strlen (replacement);
-
-	enchant_dict_store_replacement (spell->dict,
-					word,
-					w_len,
-					replacement,
-					r_len);
-
-	return TRUE;
+    g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE);
+    g_return_val_if_fail (word != NULL, FALSE);
+    g_return_val_if_fail (replacement != NULL, FALSE);
+
+    if (!lazy_init (spell, spell->active_lang))
+    {
+        return FALSE;
+    }
+
+    g_return_val_if_fail (spell->dict != NULL, FALSE);
+
+    if (w_len < 0)
+    {
+        w_len = strlen (word);
+    }
+
+    if (r_len < 0)
+    {
+        r_len = strlen (replacement);
+    }
+
+    enchant_dict_store_replacement (spell->dict,
+                                    word,
+                                    w_len,
+                                    replacement,
+                                    r_len);
+
+    return TRUE;
 }
 

From 9833abf9b0352ac4347636bafc0693b5d9ee9d1d Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Sun, 10 Dec 2017 15:38:15 -0800
Subject: [PATCH 13/14] spell-plugin: Update for removal of some deprecated
 functionality

enchant_dict_add_to_pwl () was removed from libenchant. Use it's replacement,
enchant_dict_add () instead and bump our required version of libenchant.

Closes https://github.com/linuxmint/xed/issues/198
---
 configure.ac                      | 2 +-
 plugins/spell/xed-spell-checker.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index aaf0017..e282b07 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@ dnl ================================================================
 dnl spell plugins checks: enchant and iso-codes
 dnl ================================================================
 
-ENCHANT_REQUIRED=1.2.0
+ENCHANT_REQUIRED=1.6.0
 ISO_CODES_REQUIRED=0.35
 
 AC_ARG_ENABLE([spell],
diff --git a/plugins/spell/xed-spell-checker.c b/plugins/spell/xed-spell-checker.c
index e45e926..65d55fa 100644
--- a/plugins/spell/xed-spell-checker.c
+++ b/plugins/spell/xed-spell-checker.c
@@ -465,7 +465,7 @@ xed_spell_checker_add_word_to_personal (XedSpellChecker *spell,
         len = strlen (word);
     }
 
-    enchant_dict_add_to_pwl (spell->dict, word, len);
+    enchant_dict_add (spell->dict, word, len);
 
     g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_PERSONAL], 0, word, len);
 

From c77c33773d2ea8848245e99bbb18fb1cf92dcbe3 Mon Sep 17 00:00:00 2001
From: JosephMcc <mccullarjoseph@gmail.com>
Date: Tue, 12 Dec 2017 18:42:51 -0800
Subject: [PATCH 14/14] xed-notebook: Allow changing tabs with mouse
 back/forward buttons

While at it, fix the direction for switching tabs when scrolling with the
mouse wheel.

Closes https://github.com/linuxmint/xed/issues/115
---
 xed/xed-notebook.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/xed/xed-notebook.c b/xed/xed-notebook.c
index 6e13d4b..8dceee0 100644
--- a/xed/xed-notebook.c
+++ b/xed/xed-notebook.c
@@ -543,6 +543,8 @@ button_release_cb (XedNotebook    *notebook,
                    GdkEventButton *event,
                    gpointer        data)
 {
+    gboolean ret_val = FALSE;
+
     if (notebook->priv->drag_in_progress)
     {
         gint cur_page_num;
@@ -566,11 +568,23 @@ button_release_cb (XedNotebook    *notebook,
         }
         gtk_grab_remove (GTK_WIDGET (notebook));
     }
+    else if ((event->type == GDK_BUTTON_RELEASE) && (event->button == 8))
+    {
+        gtk_notebook_prev_page (GTK_NOTEBOOK (notebook));
+
+        ret_val = TRUE;
+    }
+    else if ((event->type == GDK_BUTTON_RELEASE) && (event->button == 9))
+    {
+        gtk_notebook_next_page (GTK_NOTEBOOK (notebook));
+
+        ret_val = TRUE;
+    }
 
     /* This must be called even if a drag isn't happening */
     drag_stop (notebook);
 
-    return FALSE;
+    return ret_val;
 }
 
 static gboolean
@@ -638,13 +652,13 @@ notebook_scroll_event_cb (XedNotebook    *notebook,
     switch (event->direction)
     {
         case GDK_SCROLL_DOWN:
-        case GDK_SCROLL_RIGHT:
-            gtk_notebook_next_page (GTK_NOTEBOOK (notebook));
-            break;
-        case GDK_SCROLL_UP:
         case GDK_SCROLL_LEFT:
             gtk_notebook_prev_page (GTK_NOTEBOOK (notebook));
             break;
+        case GDK_SCROLL_UP:
+        case GDK_SCROLL_RIGHT:
+            gtk_notebook_next_page (GTK_NOTEBOOK (notebook));
+            break;
         default:
             break;
     }