[Xfce4-commits] [apps/mousepad] 29/45: Add preferences dialog

noreply at xfce.org noreply at xfce.org
Fri Jul 11 13:03:34 CEST 2014


This is an automated email from the git hooks/post-receive script.

mbrush pushed a commit to branch master
in repository apps/mousepad.

commit 43e987372941c4c4caca4428b00e60b3a618e00f
Author: Matthew Brush <mbrush at codebrainz.ca>
Date:   Mon Jul 7 22:04:05 2014 -0700

    Add preferences dialog
---
 .gitignore                           |    1 +
 mousepad/Makefile.am                 |   13 +-
 mousepad/mousepad-application.c      |   58 ++-
 mousepad/mousepad-application.h      |    3 +
 mousepad/mousepad-prefs-dialog.c     |  426 +++++++++++++++++++
 mousepad/mousepad-prefs-dialog.glade |  768 ++++++++++++++++++++++++++++++++++
 mousepad/mousepad-prefs-dialog.h     |   24 ++
 mousepad/mousepad-settings.c         |   67 +++
 mousepad/mousepad-settings.h         |   13 +
 mousepad/mousepad-window-ui.xml      |    2 +
 mousepad/mousepad-window.c           |   23 +
 mousepad/mousepad-window.h           |    2 +
 12 files changed, 1396 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore
index 893c216..378fbc4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ mousepad/mousepad
 mousepad/mousepad-dbus-infos.h
 mousepad/mousepad-marshal.c
 mousepad/mousepad-marshal.h
+/mousepad/mousepad-prefs-dialog-ui.h
 /mousepad/mousepad-settings.gschema.valid
 mousepad/mousepad-window-ui.h
 po/.intltool-merge-cache
diff --git a/mousepad/Makefile.am b/mousepad/Makefile.am
index 1e61781..b5e7a7f 100644
--- a/mousepad/Makefile.am
+++ b/mousepad/Makefile.am
@@ -33,6 +33,9 @@ mousepad_SOURCES = \
 	mousepad-encoding-dialog.h \
 	mousepad-file.c \
 	mousepad-file.h \
+	mousepad-prefs-dialog.c \
+	mousepad-prefs-dialog.h \
+	mousepad-prefs-dialog-ui.h \
 	mousepad-print.c \
 	mousepad-print.h \
 	mousepad-private.h \
@@ -94,11 +97,13 @@ endif
 if MAINTAINER_MODE
 DISTCLEANFILES = \
 	$(mousepad_built_sources) \
-	mousepad-window-ui.h
+	mousepad-window-ui.h \
+	mousepad-prefs-dialog-ui.h
 
 BUILT_SOURCES = \
 	$(mousepad_built_sources) \
-	mousepad-window-ui.h
+	mousepad-window-ui.h \
+	mousepad-prefs-dialog-ui.h
 
 if HAVE_DBUS
 mousepad-dbus-infos.h: mousepad-dbus-infos.xml Makefile
@@ -108,6 +113,9 @@ endif
 mousepad-window-ui.h: mousepad-window-ui.xml Makefile
 	$(AM_V_GEN) exo-csource --strip-comments --strip-content --static --name=mousepad_window_ui $< > $@
 
+mousepad-prefs-dialog-ui.h: mousepad-prefs-dialog.glade Makefile
+	$(AM_V_GEN) exo-csource --strip-comments --strip-content --static --name=mousepad_prefs_dialog_ui $< > $@
+
 mousepad-marshal.h: mousepad-marshal.list Makefile
 	$(AM_V_GEN) glib-genmarshal --header --prefix=_mousepad_marshal $< > $@
 
@@ -120,6 +128,7 @@ EXTRA_DIST = \
 	mousepad-dbus-infos.xml \
 	mousepad-marshal.list \
 	mousepad-window-ui.xml \
+	mousepad-prefs-dialog.glade \
 	org.xfce.Mousepad.gschema.xml
 
 gsettings_SCHEMAS = org.xfce.Mousepad.gschema.xml
diff --git a/mousepad/mousepad-application.c b/mousepad/mousepad-application.c
index e0c3e09..b1725c5 100644
--- a/mousepad/mousepad-application.c
+++ b/mousepad/mousepad-application.c
@@ -22,6 +22,7 @@
 #include <mousepad/mousepad-settings.h>
 #include <mousepad/mousepad-application.h>
 #include <mousepad/mousepad-document.h>
+#include <mousepad/mousepad-prefs-dialog.h>
 #include <mousepad/mousepad-replace-dialog.h>
 #include <mousepad/mousepad-window.h>
 
@@ -48,10 +49,13 @@ struct _MousepadApplicationClass
 
 struct _MousepadApplication
 {
-  GObject  __parent__;
+  GObject    __parent__;
 
   /* internal list of all the opened windows */
-  GSList  *windows;
+  GSList    *windows;
+
+  /* the preferences dialog when shown */
+  GtkWidget *prefs_dialog;
 };
 
 
@@ -77,6 +81,7 @@ mousepad_application_init (MousepadApplication *application)
   gchar *filename;
 
   mousepad_settings_init ();
+  application->prefs_dialog = NULL;
 
   /* check if we have a saved accel map */
   filename = mousepad_util_get_save_location (MOUSEPAD_ACCELS_RELPATH, FALSE);
@@ -99,6 +104,9 @@ mousepad_application_finalize (GObject *object)
   GSList              *li;
   gchar               *filename;
 
+  if (GTK_IS_WIDGET (application->prefs_dialog))
+    gtk_widget_destroy (application->prefs_dialog);
+
   /* flush the history items of the replace dialog
    * this is a bit of an ugly place, but cleaning on a window close
    * isn't a good option eighter */
@@ -302,3 +310,49 @@ mousepad_application_new_window_with_files (MousepadApplication  *application,
   /* show the window */
   gtk_widget_show (window);
 }
+
+
+
+static void
+mousepad_application_prefs_dialog_response (MousepadApplication *application,
+                                            gint                 response_id,
+                                            MousepadPrefsDialog *dialog)
+{
+  gtk_widget_destroy (GTK_WIDGET (application->prefs_dialog));
+  application->prefs_dialog = NULL;
+}
+
+
+
+void
+mousepad_application_show_preferences (MousepadApplication  *application,
+                                       GtkWindow            *transient_for)
+{
+  /* if the dialog isn't already shown, create one */
+  if (! GTK_IS_WIDGET (application->prefs_dialog))
+    {
+      application->prefs_dialog = mousepad_prefs_dialog_new ();
+
+      /* destroy the dialog when it's close button is pressed */
+      g_signal_connect_swapped (application->prefs_dialog,
+                                "response",
+                                G_CALLBACK (mousepad_application_prefs_dialog_response),
+                                application);
+    }
+
+  /* if no transient window was specified, used the first application window
+   * or NULL if no windows exists (shouldn't happen) */
+  if (! GTK_IS_WINDOW (transient_for))
+    {
+      if (application->windows && GTK_IS_WINDOW (application->windows->data))
+        transient_for = GTK_WINDOW (application->windows->data);
+      else
+        transient_for = NULL;
+    }
+
+  /* associate it with one of the windows */
+  gtk_window_set_transient_for (GTK_WINDOW (application->prefs_dialog), transient_for);
+
+  /* show it to the user */
+  gtk_window_present (GTK_WINDOW (application->prefs_dialog));
+}
diff --git a/mousepad/mousepad-application.h b/mousepad/mousepad-application.h
index 28e382c..2296234 100644
--- a/mousepad/mousepad-application.h
+++ b/mousepad/mousepad-application.h
@@ -43,6 +43,9 @@ void                 mousepad_application_new_window_with_files  (MousepadApplic
                                                                   const gchar          *working_directory,
                                                                   gchar               **filenames);
 
+void                 mousepad_application_show_preferences       (MousepadApplication  *application,
+                                                                  GtkWindow            *transient_for);
+
 G_END_DECLS
 
 #endif /* !__MOUSEPAD_APPLICATION_H__ */
diff --git a/mousepad/mousepad-prefs-dialog.c b/mousepad/mousepad-prefs-dialog.c
new file mode 100644
index 0000000..3562a61
--- /dev/null
+++ b/mousepad/mousepad-prefs-dialog.c
@@ -0,0 +1,426 @@
+#include <mousepad/mousepad-prefs-dialog.h>
+#include <mousepad/mousepad-prefs-dialog-ui.h>
+#include <mousepad/mousepad-settings.h>
+#include <mousepad/mousepad-private.h>
+
+
+
+#define WID_NOTEBOOK                        "/prefs/main-notebook"
+
+/* View page */
+#define WID_SHOW_LINE_NUMBERS_CHECK         "/prefs/view/display/show-line-numbers-check"
+#define WID_SHOW_WHITESPACE_CHECK           "/prefs/view/display/display-whitespace-check"
+#define WID_SHOW_LINE_ENDINGS_CHECK         "/prefs/view/display/display-line-endings-check"
+#define WID_SHOW_RIGHT_MARGIN_CHECK         "/prefs/view/display/long-line-check"
+#define WID_RIGHT_MARGIN_SPIN               "/prefs/view/display/long-line-spin"
+#define WID_HIGHLIGHT_CURRENT_LINE_CHECK    "/prefs/view/display/highlight-current-line-check"
+#define WID_HIGHLIGHT_MATCHING_BRACES_CHECK "/prefs/view/display/highlight-braces-check"
+#define WID_WORD_WRAP_CHECK                 "/prefs/view/display/word-wrap-check"
+
+#define WID_DEFAULT_FONT_CHECK              "/prefs/view/font/default-check"
+#define WID_FONT_BUTTON                     "/prefs/view/font/chooser-button"
+#define WID_SCHEME_COMBO                    "/prefs/view/color-scheme-combo"
+#define WID_SCHEME_MODEL                    "/prefs/view/color-scheme-model"
+
+/* Editor page */
+#define WID_TAB_WIDTH_SPIN                  "/prefs/editor/tab-width-spin"
+#define WID_TAB_MODE_COMBO                  "/prefs/editor/tab-mode-combo"
+#define WID_AUTO_INDENT_CHECK               "/prefs/editor/auto-indent-check"
+#define WID_SMART_HOME_END_COMBO            "/prefs/editor/smart-home-end-combo"
+
+/* Window page */
+#define WID_STATUSBAR_VISIBLE_CHECK         "/prefs/window/general/show-statusbar-check"
+#define WID_PATH_IN_TITLE_CHECK             "/prefs/window/general/show-path-in-title-check"
+#define WID_REMEMBER_GEOMETRY_CHECK         "/prefs/window/general/remember-window-size-check"
+#define WID_ALWAYS_SHOW_TABS_CHECK          "/prefs/window/notebook/always-show-tabs-check"
+#define WID_CYCLE_TABS_CHECK                "/prefs/window/notebook/cycle-tabs-check"
+
+
+
+enum
+{
+  COLUMN_ID,
+  COLUMN_NAME,
+};
+
+
+
+struct MousepadPrefsDialog_
+{
+  GtkDialog   parent;
+  GtkBuilder *builder;
+  gboolean    blocked;
+  gulong      color_scheme_signal;
+  gulong      tab_mode_signal;
+  gulong      home_end_signal;
+};
+
+struct MousepadPrefsDialogClass_
+{
+  GtkDialogClass parent_class;
+};
+
+
+
+static void mousepad_prefs_dialog_finalize (GObject *object);
+
+
+
+G_DEFINE_TYPE (MousepadPrefsDialog, mousepad_prefs_dialog, GTK_TYPE_DIALOG)
+
+
+
+static void
+mousepad_prefs_dialog_class_init (MousepadPrefsDialogClass *klass)
+{
+  GObjectClass *g_object_class;
+
+  g_object_class = G_OBJECT_CLASS (klass);
+
+  g_object_class->finalize = mousepad_prefs_dialog_finalize;
+}
+
+
+
+static void
+mousepad_prefs_dialog_finalize (GObject *object)
+{
+  MousepadPrefsDialog *self;
+
+  g_return_if_fail (MOUSEPAD_IS_PREFS_DIALOG (object));
+
+  self = MOUSEPAD_PREFS_DIALOG (object);
+
+  /* disconnect the "changed" signals from the settings that we connected manually */
+  if (self->color_scheme_signal > 0)
+    MOUSEPAD_SETTING_DISCONNECT (COLOR_SCHEME, self->color_scheme_signal);
+  if (self->tab_mode_signal > 0)
+    MOUSEPAD_SETTING_DISCONNECT (INSERT_SPACES, self->tab_mode_signal);
+  if (self->home_end_signal > 0)
+    MOUSEPAD_SETTING_DISCONNECT (SMART_HOME_END, self->home_end_signal);
+
+  /* destroy the GtkBuilder instance */
+  if (G_IS_OBJECT (self->builder))
+    g_object_unref (self->builder);
+
+  G_OBJECT_CLASS (mousepad_prefs_dialog_parent_class)->finalize (object);
+}
+
+
+
+/* update the color scheme when the prefs dialog widget changes */
+static void
+mousepad_prefs_dialog_color_scheme_changed (MousepadPrefsDialog *self,
+                                            GtkComboBox         *combo)
+{
+  GtkListStore *store;
+  GtkTreeIter   iter;
+  gchar        *scheme_id = NULL;
+
+  store = GTK_LIST_STORE (gtk_builder_get_object (self->builder, WID_SCHEME_MODEL));
+
+  gtk_combo_box_get_active_iter (combo, &iter);
+
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COLUMN_ID, &scheme_id,-1);
+
+  self->blocked = TRUE;
+  MOUSEPAD_SETTING_SET_STRING (COLOR_SCHEME, scheme_id);
+  self->blocked = FALSE;
+
+  g_free (scheme_id);
+}
+
+
+
+/* udpate the color schemes combo when the setting changes */
+static void
+mousepad_prefs_dialog_color_scheme_setting_changed (MousepadPrefsDialog *self,
+                                                    gchar               *key,
+                                                    GSettings           *settings)
+{
+  gchar        *new_id;
+  GtkTreeIter   iter;
+  gboolean      iter_valid;
+  GtkComboBox  *combo;
+  GtkTreeModel *model;
+
+  /* don't do anything when the combo box is itself updating the setting */
+  if (self->blocked)
+    return;
+
+  new_id = MOUSEPAD_SETTING_GET_STRING (COLOR_SCHEME);
+
+  combo = GTK_COMBO_BOX (gtk_builder_get_object (self->builder, WID_SCHEME_COMBO));
+  model = GTK_TREE_MODEL (gtk_builder_get_object (self->builder, WID_SCHEME_MODEL));
+
+  iter_valid = gtk_tree_model_get_iter_first (model, &iter);
+  while (iter_valid)
+    {
+      gchar   *id = NULL;
+      gboolean equal;
+
+      gtk_tree_model_get (model, &iter, COLUMN_ID, &id, -1);
+      equal = (g_strcmp0 (id, new_id) == 0);
+      g_free (id);
+
+      if (equal)
+        {
+          gtk_combo_box_set_active_iter (combo, &iter);
+          break;
+        }
+
+      iter_valid = gtk_tree_model_iter_next (model, &iter);
+    }
+
+  g_free (new_id);
+}
+
+
+
+/* add available color schemes to the combo box model */
+static void
+mousepad_prefs_dialog_setup_color_schemes_combo (MousepadPrefsDialog *self)
+{
+  GtkSourceStyleSchemeManager *manager;
+  const gchar *const          *ids;
+  const gchar *const          *id_iter;
+  GtkListStore                *store;
+  GtkTreeIter                  iter;
+
+  store = GTK_LIST_STORE (gtk_builder_get_object (self->builder, WID_SCHEME_MODEL));
+  manager = gtk_source_style_scheme_manager_get_default ();
+  ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+
+  for (id_iter = ids; *id_iter; id_iter++)
+    {
+      GtkSourceStyleScheme *scheme;
+
+      scheme = gtk_source_style_scheme_manager_get_scheme (manager, *id_iter);
+      gtk_list_store_append (store, &iter);
+      gtk_list_store_set (store, &iter,
+                          COLUMN_ID, gtk_source_style_scheme_get_id (scheme),
+                          COLUMN_NAME, gtk_source_style_scheme_get_name (scheme),
+                          -1);
+    }
+
+  /* set the active item from the settings */
+  mousepad_prefs_dialog_color_scheme_setting_changed (self, NULL, NULL);
+
+  g_signal_connect_swapped (gtk_builder_get_object (self->builder, WID_SCHEME_COMBO),
+                            "changed",
+                            G_CALLBACK (mousepad_prefs_dialog_color_scheme_changed),
+                            self);
+
+  self->color_scheme_signal =
+    MOUSEPAD_SETTING_CONNECT (COLOR_SCHEME,
+                              G_CALLBACK (mousepad_prefs_dialog_color_scheme_setting_changed),
+                              self,
+                              G_CONNECT_SWAPPED);
+}
+
+
+
+/* update the setting when the prefs dialog widget changes */
+static void
+mousepad_prefs_dialog_tab_mode_changed (MousepadPrefsDialog *self,
+                                        GtkComboBox         *combo)
+{
+  self->blocked = TRUE;
+  /* in the combo box, id 0 is tabs, and 1 is spaces */
+  MOUSEPAD_SETTING_SET_BOOLEAN (INSERT_SPACES,
+                                (gtk_combo_box_get_active (combo) == 1));
+
+  self->blocked = FALSE;
+}
+
+
+
+/* update the combo box when the setting changes */
+static void
+mousepad_prefs_dialog_tab_mode_setting_changed (MousepadPrefsDialog *self,
+                                                gchar               *key,
+                                                GSettings           *settings)
+{
+  gboolean     insert_spaces;
+  GtkComboBox *combo;
+
+  /* don't do anything when the combo box is itself updating the setting */
+  if (self->blocked)
+    return;
+
+  insert_spaces = MOUSEPAD_SETTING_GET_BOOLEAN (INSERT_SPACES);
+
+  combo = GTK_COMBO_BOX (gtk_builder_get_object (self->builder, WID_TAB_MODE_COMBO));
+
+  /* in the combo box, id 0 is tabs, and 1 is spaces */
+  gtk_combo_box_set_active (combo, insert_spaces ? 1 : 0);
+}
+
+
+
+/* update the home/end key setting when the combo changes */
+static void
+mousepad_prefs_dialog_home_end_changed (MousepadPrefsDialog *self,
+                                        GtkComboBox         *combo)
+{
+  self->blocked = TRUE;
+  MOUSEPAD_SETTING_SET_ENUM (SMART_HOME_END, gtk_combo_box_get_active (combo));
+  self->blocked = FALSE;
+}
+
+
+
+/* update the combo when the setting changes */
+static void
+mousepad_prefs_dialog_home_end_setting_changed (MousepadPrefsDialog *self,
+                                                gchar               *key,
+                                                GSettings           *settings)
+{
+  GtkComboBox *combo;
+  gint         value;
+
+  /* don't do anything when the combo box is itself updating the setting */
+  if (self->blocked)
+    return;
+
+  combo = GTK_COMBO_BOX (gtk_builder_get_object (self->builder, WID_SMART_HOME_END_COMBO));
+
+  gtk_combo_box_set_active (combo, MOUSEPAD_SETTING_GET_ENUM (SMART_HOME_END));
+}
+
+
+
+#define mousepad_builder_get_widget(builder, name) \
+  GTK_WIDGET (gtk_builder_get_object (builder, name))
+
+
+
+static void
+mousepad_prefs_dialog_init (MousepadPrefsDialog *self)
+{
+  GError *error = NULL;
+  GtkWidget *notebook;
+  GtkWidget *content_area;
+  GtkWidget *check, *widget;
+
+  self->builder = gtk_builder_new ();
+
+  /* load the gtkbuilder xml that is compiled into the binary, or else die */
+  if (! gtk_builder_add_from_string (self->builder,
+                                     mousepad_prefs_dialog_ui,
+                                     mousepad_prefs_dialog_ui_length,
+                                     &error))
+    {
+      g_error ("Failed to load the internal preferences dialog: %s", error->message);
+      g_error_free (error); // not reached
+    }
+
+  /* add the Glade/GtkBuilder notebook into this dialog */
+  notebook = mousepad_builder_get_widget (self->builder, WID_NOTEBOOK);
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (self));
+  gtk_container_add (GTK_CONTAINER (content_area), notebook);
+  gtk_widget_show (notebook);
+
+  /* add the close button */
+  gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+  gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_CLOSE);
+
+  /* setup the window properties */
+  gtk_window_set_title (GTK_WINDOW (self), _("Preferences"));
+  gtk_window_set_icon_name (GTK_WINDOW (self), "preferences-desktop");
+
+  /* enable/disable right margin spin button when checkbox is changed */
+  check = mousepad_builder_get_widget (self->builder, WID_SHOW_RIGHT_MARGIN_CHECK);
+  widget = mousepad_builder_get_widget (self->builder, WID_RIGHT_MARGIN_SPIN);
+  g_object_bind_property (check, "active", widget, "sensitive", G_BINDING_SYNC_CREATE);
+
+  /* enable/disable font chooser button when the default font checkbox is changed */
+  check = mousepad_builder_get_widget (self->builder, WID_DEFAULT_FONT_CHECK);
+  widget = mousepad_builder_get_widget (self->builder, WID_FONT_BUTTON);
+  g_object_bind_property (check, "active", widget, "sensitive", G_BINDING_SYNC_CREATE);
+
+  /* bind checkboxes to settings */
+#define BIND_CHECKBOX(setting)                                           \
+  MOUSEPAD_SETTING_BIND (setting,                                        \
+                         gtk_builder_get_object (self->builder,          \
+                                                 WID_##setting##_CHECK), \
+                         "active",                                       \
+                         G_BINDING_DEFAULT)
+
+  /* View */
+  BIND_CHECKBOX (SHOW_LINE_NUMBERS);
+  BIND_CHECKBOX (SHOW_WHITESPACE);
+  BIND_CHECKBOX (SHOW_LINE_ENDINGS);
+  BIND_CHECKBOX (SHOW_RIGHT_MARGIN);
+  BIND_CHECKBOX (HIGHLIGHT_CURRENT_LINE);
+  BIND_CHECKBOX (WORD_WRAP);
+
+  /* Editor */
+  BIND_CHECKBOX (AUTO_INDENT);
+
+  /* Window */
+  BIND_CHECKBOX (STATUSBAR_VISIBLE);
+  BIND_CHECKBOX (PATH_IN_TITLE);
+  BIND_CHECKBOX (REMEMBER_GEOMETRY);
+  BIND_CHECKBOX (ALWAYS_SHOW_TABS);
+  BIND_CHECKBOX (CYCLE_TABS);
+
+#undef BIND_CHECKBOX
+
+  /* bind the right-margin-position setting to the spin button */
+  MOUSEPAD_SETTING_BIND (RIGHT_MARGIN_POSITION,
+                         gtk_builder_get_object (self->builder, WID_RIGHT_MARGIN_SPIN),
+                         "value",
+                         G_SETTINGS_BIND_DEFAULT);
+
+  /* bind the font button font-name to the font-name setting */
+  MOUSEPAD_SETTING_BIND (FONT_NAME,
+                         gtk_builder_get_object (self->builder, WID_FONT_BUTTON),
+                         "font-name",
+                         G_SETTINGS_BIND_DEFAULT);
+
+  mousepad_prefs_dialog_setup_color_schemes_combo (self);
+
+
+  /* bind the tab-width spin button to the setting */
+  MOUSEPAD_SETTING_BIND (TAB_WIDTH,
+                         gtk_builder_get_object (self->builder, WID_TAB_WIDTH_SPIN),
+                         "value",
+                         G_SETTINGS_BIND_DEFAULT);
+
+  /* update tab-mode when changed */
+  g_signal_connect_swapped (gtk_builder_get_object (self->builder, WID_TAB_MODE_COMBO),
+                            "changed",
+                            G_CALLBACK (mousepad_prefs_dialog_tab_mode_changed),
+                            self);
+
+  /* update tab mode combo when setting changes */
+  self->tab_mode_signal =
+    MOUSEPAD_SETTING_CONNECT (INSERT_SPACES,
+                              G_CALLBACK (mousepad_prefs_dialog_tab_mode_setting_changed),
+                              self,
+                              G_CONNECT_SWAPPED);
+
+  /* update home/end when changed */
+  g_signal_connect_swapped (gtk_builder_get_object (self->builder, WID_SMART_HOME_END_COMBO),
+                            "changed",
+                            G_CALLBACK (mousepad_prefs_dialog_home_end_changed),
+                            self);
+
+  /* update home/end combo when setting changes */
+  self->home_end_signal =
+    MOUSEPAD_SETTING_CONNECT (SMART_HOME_END,
+                              G_CALLBACK (mousepad_prefs_dialog_home_end_setting_changed),
+                              self,
+                              G_CONNECT_SWAPPED);
+
+  /* TODO: match-braces */
+}
+
+
+
+GtkWidget *
+mousepad_prefs_dialog_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_PREFS_DIALOG, NULL);
+}
diff --git a/mousepad/mousepad-prefs-dialog.glade b/mousepad/mousepad-prefs-dialog.glade
new file mode 100644
index 0000000..365ffeb
--- /dev/null
+++ b/mousepad/mousepad-prefs-dialog.glade
@@ -0,0 +1,768 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="2.24"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="/prefs/editor/smart-home-end-model">
+    <columns>
+      <!-- column-name id -->
+      <column type="gint"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0">0</col>
+        <col id="1" translatable="yes">Disabled</col>
+      </row>
+      <row>
+        <col id="0">1</col>
+        <col id="1" translatable="yes">Before</col>
+      </row>
+      <row>
+        <col id="0">2</col>
+        <col id="1" translatable="yes">After</col>
+      </row>
+      <row>
+        <col id="0">3</col>
+        <col id="1" translatable="yes">Always</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="/prefs/editor/tab-mode-store">
+    <columns>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Insert Tabs</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Insert Spaces</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkAdjustment" id="/prefs/editor/tab-width-adjustment">
+    <property name="upper">128</property>
+    <property name="value">8</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkListStore" id="/prefs/view/color-scheme-model">
+    <columns>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">none</col>
+        <col id="1" translatable="yes">None</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkAdjustment" id="/prefs/view/right-margin-adjustment">
+    <property name="upper">9999</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkNotebook" id="/prefs/main-notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <child>
+      <object class="GtkVBox" id="/prefs/view/content-area">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">6</property>
+        <child>
+          <object class="GtkFrame" id="/prefs/view/display/frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/view/display/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkVBox" id="/prefs/view/display/content-area">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">2</property>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/show-line-numbers-check">
+                        <property name="label" translatable="yes">Show line numbers</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="on_show_line_numbers_toggled" object="prefs_dialog" swapped="yes"/>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/display-whitespace-check">
+                        <property name="label" translatable="yes">Display whitespace</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/display-line-endings-check">
+                        <property name="label" translatable="yes">Display line endings</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkHBox" id="/prefs/view/display/long-line-margin-box">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkCheckButton" id="/prefs/view/display/long-line-check">
+                            <property name="label" translatable="yes">Long line margin at column:</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="draw_indicator">True</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="/prefs/view/display/long-line-spin">
+                            <property name="visible">True</property>
+                            <property name="sensitive">False</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">•</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <property name="adjustment">/prefs/view/right-margin-adjustment</property>
+                            <property name="numeric">True</property>
+                          </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="position">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/highlight-current-line-check">
+                        <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="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/highlight-braces-check">
+                        <property name="label" translatable="yes">Highlight matching brackets</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/display/word-wrap-check">
+                        <property name="label" translatable="yes">Wrap long lines</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">6</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/view/display/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Display</b></property>
+                <property name="use_markup">True</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="GtkFrame" id="/prefs/view/font-frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/view/font/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkVBox" id="/prefs/view/font/box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">2</property>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/view/font/default-check">
+                        <property name="label" translatable="yes">Use system monospace font</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkFontButton" id="/prefs/view/font/chooser-button">
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/view/font/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Font</b></property>
+                <property name="use_markup">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="/prefs/view/color-scheme-frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/view/color-scheme-alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkVBox" id="/prefs/view/color-scheme-box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">2</property>
+                    <child>
+                      <object class="GtkComboBox" id="/prefs/view/color-scheme-combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="model">/prefs/view/color-scheme-model</property>
+                        <property name="active">0</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="/prefs/view/color-scheme-cell-renderer"/>
+                          <attributes>
+                            <attribute name="text">1</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/view/color-scheme-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Colour scheme</b></property>
+                <property name="use_markup">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="/prefs/view/tab-label">
+        <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="/prefs/editor/content-area">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">6</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkFrame" id="/prefs/editor/indentation/frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/editor/indentation/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkTable" id="/prefs/editor/indentation/table">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="n_rows">3</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">6</property>
+                    <property name="row_spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="/prefs/editor/indentation/tab-width-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Tab width:</property>
+                      </object>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="/prefs/editor/indentation/tab-mode-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Tab mode:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="/prefs/editor/tab-width-spin">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">•</property>
+                        <property name="invisible_char_set">True</property>
+                        <property name="primary_icon_activatable">False</property>
+                        <property name="secondary_icon_activatable">False</property>
+                        <property name="primary_icon_sensitive">True</property>
+                        <property name="secondary_icon_sensitive">True</property>
+                        <property name="adjustment">/prefs/editor/tab-width-adjustment</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="/prefs/editor/tab-mode-combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="model">/prefs/editor/tab-mode-store</property>
+                        <property name="active">0</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="editor.tab_mode.cellrenderer"/>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/editor/auto-indent-check">
+                        <property name="label" translatable="yes">Enable automatic indentation</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/editor/indentation/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Indentation</b></property>
+                <property name="use_markup">True</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="GtkFrame" id="/prefs/editor/home-end/frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/editor/home-end/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkHBox" id="/prefs/editor/home-end/box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="/prefs/editor/home-end/behaviour-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Behaviour:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBox" id="/prefs/editor/smart-home-end-combo">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="model">/prefs/editor/smart-home-end-model</property>
+                        <property name="active">0</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="/prefs/editor/smart-home-end-cellrenderer"/>
+                          <attributes>
+                            <attribute name="text">1</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/editor/home-end/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Home/End Keys</b></property>
+                <property name="use_markup">True</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="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="/prefs/editor/tab-label">
+        <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>
+    <child>
+      <object class="GtkVBox" id="/prefs/window/content-area">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">6</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkFrame" id="/prefs/window/general/frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/window/general/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkVBox" id="/prefs/window/general/box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">2</property>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/window/general/show-statusbar-check">
+                        <property name="label" translatable="yes">Show status bar</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/window/general/show-path-in-title-check">
+                        <property name="label" translatable="yes">Show full filename in title bar</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/window/general/remember-window-size-check">
+                        <property name="label" translatable="yes">Remember window size</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/window/general/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>General</b></property>
+                <property name="use_markup">True</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="GtkFrame" id="/prefs/window/notebook/frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <object class="GtkAlignment" id="/prefs/window/notebook/alignment">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="top_padding">6</property>
+                <property name="bottom_padding">6</property>
+                <property name="left_padding">12</property>
+                <property name="right_padding">6</property>
+                <child>
+                  <object class="GtkVBox" id="/prefs/window/notebook/box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">2</property>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/window/notebook/always-show-tabs-check">
+                        <property name="label" translatable="yes">Always show tabs even with one file</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="/prefs/window/notebook/cycle-tabs-check">
+                        <property name="label" translatable="yes">Cycled notebook tab switching</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="yalign">0.55000001192092896</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="/prefs/window/notebook/label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes"><b>Notebook tabs</b></property>
+                <property name="use_markup">True</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="position">2</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="/prefs/window/tab-label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Window</property>
+      </object>
+      <packing>
+        <property name="position">2</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/mousepad/mousepad-prefs-dialog.h b/mousepad/mousepad-prefs-dialog.h
new file mode 100644
index 0000000..01e1c60
--- /dev/null
+++ b/mousepad/mousepad-prefs-dialog.h
@@ -0,0 +1,24 @@
+#ifndef MOUSEPADPREFSDIALOG_H_
+#define MOUSEPADPREFSDIALOG_H_ 1
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_PREFS_DIALOG             (mousepad_prefs_dialog_get_type ())
+#define MOUSEPAD_PREFS_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_PREFS_DIALOG, MousepadPrefsDialog))
+#define MOUSEPAD_PREFS_DIALOG_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_PREFS_DIALOG, MousepadPrefsDialogClass))
+#define MOUSEPAD_IS_PREFS_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_PREFS_DIALOG))
+#define MOUSEPAD_IS_PREFS_DIALOG_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_PREFS_DIALOG))
+#define MOUSEPAD_PREFS_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_PREFS_DIALOG, MousepadPrefsDialogClass))
+
+typedef struct MousepadPrefsDialog_         MousepadPrefsDialog;
+typedef struct MousepadPrefsDialogClass_    MousepadPrefsDialogClass;
+
+GType      mousepad_prefs_dialog_get_type (void);
+
+GtkWidget *mousepad_prefs_dialog_new      (void);
+
+G_END_DECLS
+
+#endif /* MOUSEPADPREFSDIALOG_H_ */
diff --git a/mousepad/mousepad-settings.c b/mousepad/mousepad-settings.c
index db6fb20..0f48765 100644
--- a/mousepad/mousepad-settings.c
+++ b/mousepad/mousepad-settings.c
@@ -379,6 +379,25 @@ mousepad_setting_connect (const gchar  *path,
 
 
 
+void
+mousepad_setting_disconnect (const gchar *path,
+                             gulong       handler_id)
+{
+  MousepadSchema schema;
+
+  g_return_if_fail (path != NULL);
+  g_return_if_fail (handler_id > 0);
+
+  schema = mousepad_settings_parse_path (path, NULL);
+
+  if (G_LIKELY (schema != MOUSEPAD_NUM_SCHEMAS))
+    g_signal_handler_disconnect (mousepad_settings[schema], handler_id);
+  else
+    g_warn_if_reached ();
+}
+
+
+
 gboolean
 mousepad_setting_get (const gchar *path,
                       const gchar *format_string,
@@ -516,3 +535,51 @@ mousepad_setting_set_string (const gchar *path,
 {
   mousepad_setting_set (path, "s", value);
 }
+
+
+
+gint
+mousepad_setting_get_enum (const gchar *path)
+{
+  gint           result = 0;
+  const gchar   *key_name;
+  MousepadSchema schema;
+
+  g_return_val_if_fail (path != NULL, FALSE);
+
+  schema = mousepad_settings_parse_path (path, &key_name);
+
+  if (G_LIKELY (schema != MOUSEPAD_NUM_SCHEMAS))
+    {
+      MOUSEPAD_SETTINGS_LOCK ();
+      result = g_settings_get_enum (mousepad_settings[schema], key_name);
+      MOUSEPAD_SETTINGS_UNLOCK ();
+    }
+  else
+    g_warn_if_reached ();
+
+  return result;
+}
+
+
+
+void
+mousepad_setting_set_enum (const gchar *path,
+                           gint         value)
+{
+  const gchar   *key_name;
+  MousepadSchema schema;
+
+  g_return_val_if_fail (path != NULL, FALSE);
+
+  schema = mousepad_settings_parse_path (path, &key_name);
+
+  if (G_LIKELY (schema != MOUSEPAD_NUM_SCHEMAS))
+    {
+      MOUSEPAD_SETTINGS_LOCK ();
+      g_settings_set_enum (mousepad_settings[schema], key_name, value);
+      MOUSEPAD_SETTINGS_UNLOCK ();
+    }
+  else
+    g_warn_if_reached ();
+}
diff --git a/mousepad/mousepad-settings.h b/mousepad/mousepad-settings.h
index 8b44cae..7d8fb6b 100644
--- a/mousepad/mousepad-settings.h
+++ b/mousepad/mousepad-settings.h
@@ -53,6 +53,9 @@ gulong   mousepad_setting_connect     (const gchar       *path,
                                        gpointer           user_data,
                                        GSignalFlags       connect_flags);
 
+void     mousepad_setting_disconnect  (const gchar       *path,
+                                       gulong             handler_id);
+
 /* functions for reading and writing settings */
 
 gboolean mousepad_setting_get         (const gchar       *path,
@@ -80,6 +83,11 @@ gchar   *mousepad_setting_get_string  (const gchar       *path);
 void     mousepad_setting_set_string  (const gchar       *path,
                                        const gchar       *value);
 
+gint     mousepad_setting_get_enum    (const gchar       *path);
+
+void     mousepad_setting_set_enum    (const gchar       *path,
+                                       gint               value);
+
 /* wrappers for above read/write functions with shorter arguments */
 
 #define MOUSEPAD_SETTING_BIND(setting, object, prop, flags) \
@@ -88,15 +96,20 @@ void     mousepad_setting_set_string  (const gchar       *path,
 #define MOUSEPAD_SETTING_CONNECT(setting, callback, user_data, connect_flags) \
   mousepad_setting_connect (MOUSEPAD_SETTING_##setting, callback, user_data, connect_flags)
 
+#define MOUSEPAD_SETTING_DISCONNECT(setting, id) \
+  mousepad_setting_disconnect (MOUSEPAD_SETTING_##setting, id)
+
 #define MOUSEPAD_SETTING_GET(setting, ...)           mousepad_setting_get (MOUSEPAD_SETTING_##setting, __VA_ARGS__)
 #define MOUSEPAD_SETTING_GET_BOOLEAN(setting)        mousepad_setting_get_boolean (MOUSEPAD_SETTING_##setting)
 #define MOUSEPAD_SETTING_GET_INT(setting)            mousepad_setting_get_int (MOUSEPAD_SETTING_##setting)
 #define MOUSEPAD_SETTING_GET_STRING(setting)         mousepad_setting_get_string (MOUSEPAD_SETTING_##setting)
+#define MOUSEPAD_SETTING_GET_ENUM(setting)           mousepad_setting_get_enum (MOUSEPAD_SETTING_##setting)
 
 #define MOUSEPAD_SETTING_SET(setting, ...)           mousepad_setting_set (MOUSEPAD_SETTING_##setting, __VA_ARGS__)
 #define MOUSEPAD_SETTING_SET_BOOLEAN(setting, value) mousepad_setting_set_boolean (MOUSEPAD_SETTING_##setting, value)
 #define MOUSEPAD_SETTING_SET_INT(setting, value)     mousepad_setting_set_int (MOUSEPAD_SETTING_##setting, value)
 #define MOUSEPAD_SETTING_SET_STRING(setting, value)  mousepad_setting_set_string (MOUSEPAD_SETTING_##setting, value)
+#define MOUSEPAD_SETTING_SET_ENUM(setting, value)    mousepad_setting_set_enum (MOUSEPAD_SETTING_##setting, value)
 
 G_END_DECLS
 
diff --git a/mousepad/mousepad-window-ui.xml b/mousepad/mousepad-window-ui.xml
index f960bc6..07a8d2f 100644
--- a/mousepad/mousepad-window-ui.xml
+++ b/mousepad/mousepad-window-ui.xml
@@ -62,6 +62,8 @@
       <menuitem action="find-next" />
       <menuitem action="find-previous" />
       <menuitem action="replace" />
+      <separator />
+      <menuitem action="preferences" />
     </menu>
 
     <menu action="view-menu">
diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
index 78878af..8e9df26 100644
--- a/mousepad/mousepad-window.c
+++ b/mousepad/mousepad-window.c
@@ -288,6 +288,8 @@ static void              mousepad_window_action_find_previous         (GtkAction
 static void              mousepad_window_action_replace_destroy       (MousepadWindow         *window);
 static void              mousepad_window_action_replace               (GtkAction              *action,
                                                                        MousepadWindow         *window);
+static void              mousepad_window_action_preferences           (GtkAction              *action,
+                                                                       MousepadWindow         *window);
 static void              mousepad_window_action_select_font           (GtkAction              *action,
                                                                        MousepadWindow         *window);
 static void              mousepad_window_action_color_scheme          (GtkToggleAction        *action,
@@ -433,6 +435,7 @@ static const GtkActionEntry action_entries[] =
     { "find-next", NULL, N_("Find _Next"), "F3", N_("Search forwards for the same text"), G_CALLBACK (mousepad_window_action_find_next), },
     { "find-previous", NULL, N_("Find _Previous"), "<shift>F3", N_("Search backwards for the same text"), G_CALLBACK (mousepad_window_action_find_previous), },
     { "replace", GTK_STOCK_FIND_AND_REPLACE, N_("Find and Rep_lace..."), NULL, N_("Search for and replace text"), G_CALLBACK (mousepad_window_action_replace), },
+    { "preferences", GTK_STOCK_PREFERENCES, N_("Preferences"), NULL, N_("Show the preferences dialog"), G_CALLBACK (mousepad_window_action_preferences), },
 
   { "view-menu", NULL, N_("_View"), NULL, NULL, NULL, },
     { "font", GTK_STOCK_SELECT_FONT, N_("Select F_ont..."), NULL, N_("Change the editor font"), G_CALLBACK (mousepad_window_action_select_font), },
@@ -4496,6 +4499,15 @@ mousepad_window_action_replace (GtkAction      *action,
 
 
 static void
+mousepad_window_action_preferences (GtkAction      *action,
+                                    MousepadWindow *window)
+{
+  mousepad_window_show_preferences (window);
+}
+
+
+
+static void
 mousepad_window_action_select_font (GtkAction      *action,
                                     MousepadWindow *window)
 {
@@ -5084,3 +5096,14 @@ mousepad_window_action_about (GtkAction      *action,
   /* show about dialog */
   mousepad_dialogs_show_about (GTK_WINDOW (window));
 }
+
+
+
+void
+mousepad_window_show_preferences (MousepadWindow  *window)
+{
+  MousepadApplication *application;
+  g_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+  application = mousepad_application_get ();
+  mousepad_application_show_preferences (application, GTK_WINDOW (window));
+}
diff --git a/mousepad/mousepad-window.h b/mousepad/mousepad-window.h
index cf68bc4..4bd85e9 100644
--- a/mousepad/mousepad-window.h
+++ b/mousepad/mousepad-window.h
@@ -54,6 +54,8 @@ gboolean        mousepad_window_open_files       (MousepadWindow  *window,
                                                   const gchar     *working_directory,
                                                   gchar          **filenames);
 
+void            mousepad_window_show_preferences (MousepadWindow  *window);
+
 G_END_DECLS
 
 #endif /* !__MOUSEPAD_WINDOW_H__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list