Git Repositories

2006-01-11 Benedikt Meurer <benny@xfce.org>
authorBenedikt Meurer <benny@xfce.org>
Wed, 11 Jan 2006 17:23:46 +0000 (17:23 +0000)
committerBenedikt Meurer <benny@xfce.org>
Wed, 11 Jan 2006 17:23:46 +0000 (17:23 +0000)
* thunar/thunar-preferences.c, FAQ: Store preferences in an .ini file,
  $XDG_CONFIG_HOME/Thunar/thunarrc, similar to what Terminal does, so
  users can easily adjust hidden settings, and don't have to dive into
  the details of managing a tdb database file.
* thunar/thunar-icon-view.c, thunar/thunar-path-entry.c,
  thunar/thunar-preferences-dialog.c, thunar/thunar-preferences.c,
  thunar/thunar-standard-view.c: Rename "default-folders-first" to
  "misc-folders-first" and "default-text-beside-icons" to
  "misc-text-beside-icons", as those preferences aren't defaults.
* thunar/thunar-standard-view.c(thunar_standard_view_scroll_event),
  thunar/thunar-preferences.c: Add a new hidden preference,
  MiscHorizontalWheelNavigates, which controls whether the horizontal
  mouse wheel should be used to navigate back and forth within a
  Thunar view. This fixes bug #1319.
* docs/Makefile.am, docs/README.thunarrc: Add brief overview of the
  various Thunar configuration settings.

(Old svn revision: 19393)

ChangeLog
FAQ
docs/Makefile.am
docs/README.thunarrc [new file with mode: 0644]
thunar/thunar-icon-view.c
thunar/thunar-path-entry.c
thunar/thunar-preferences-dialog.c
thunar/thunar-preferences.c
thunar/thunar-standard-view.c

index 5e1dc85..46ba1fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2006-01-11     Benedikt Meurer <benny@xfce.org>
 
+       * thunar/thunar-preferences.c, FAQ: Store preferences in an .ini file,
+         $XDG_CONFIG_HOME/Thunar/thunarrc, similar to what Terminal does, so
+         users can easily adjust hidden settings, and don't have to dive into
+         the details of managing a tdb database file.
+       * thunar/thunar-icon-view.c, thunar/thunar-path-entry.c,
+         thunar/thunar-preferences-dialog.c, thunar/thunar-preferences.c,
+         thunar/thunar-standard-view.c: Rename "default-folders-first" to
+         "misc-folders-first" and "default-text-beside-icons" to
+         "misc-text-beside-icons", as those preferences aren't defaults.
+       * thunar/thunar-standard-view.c(thunar_standard_view_scroll_event),
+         thunar/thunar-preferences.c: Add a new hidden preference,
+         MiscHorizontalWheelNavigates, which controls whether the horizontal
+         mouse wheel should be used to navigate back and forth within a
+         Thunar view. This fixes bug #1319.
+       * docs/Makefile.am, docs/README.thunarrc: Add brief overview of the
+         various Thunar configuration settings.
+
+2006-01-11     Benedikt Meurer <benny@xfce.org>
+
        * thunar/thunar-standard-view.c: Fix compiler warnings. Again bug
          #1318.
 
diff --git a/FAQ b/FAQ
index 27dace2..93c79ab 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -40,13 +40,13 @@ appropriate answers to these questions.
 4. Where does Thunar store its preferences?
 ===========================================
 
-  Thunar stores the user configurable preferences in a tdb database file, which
-  is located at
+  Thunar stores the user configurable preferences (and hidden settings) in
+  an .ini file, which is located at
 
-    $XDG_CONFIG_HOME/Thunar/preferences.tdb
+    $XDG_CONFIG_HOME/Thunar/thunarrc
 
-  and can be examined using the tdbtool, which is part of the Thunar
-  distribution (located in the tdb/ subdirectory).
+  and can be examined using a text editor. See docs/README.thunarrc for an
+  overview of the various preferences.
 
 
 5. How to use mouse gestures in Thunar?
index 5311c00..c913ac5 100644 (file)
@@ -5,4 +5,11 @@ SUBDIRS =                                                              \
        papers                                                          \
        reference
 
+docdir = $(datadir)/doc/Thunar
+doc_DATA =                                                             \
+       README.thunarrc
+
+EXTRA_DIST =                                                           \
+       $(doc_DATA)
+
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/docs/README.thunarrc b/docs/README.thunarrc
new file mode 100644 (file)
index 0000000..8ce6470
--- /dev/null
@@ -0,0 +1,59 @@
+The Thunar Configuration File (thunarrc)
+========================================
+
+  Thunar stores most of its preferences in the thunarrc file, which is located
+  in $XDG_CONFIG_HOME/Thunar/thunarrc. Many, but not all, of the settings are
+  configurable from the preferences dialog, which is available from the Edit
+  menu of every Thunar window.
+
+  The following list gives a brief overview of the preferences known to Thunar:
+
+   * DefaultShowHidden (FALSE/TRUE)
+
+     Determines whether hidden files should be shown by default in newly
+     opened Thunar windows.
+
+   * DefaultView (ThunarDetailsView/ThunarIconView/void)
+
+     The name of the widget class, which should be used for the view pane
+     in new Thunar windows, or "void" to use the last selected view from
+     LastView preference.
+
+   * LastLocationBar (ThunarLocationButtons/ThunarLocationEntry/void)
+
+     The name of the widget class which should be used for the location bar
+     in Thunar windows or "void" to hide the location bar completely.
+
+   * LastSidePane (ThunarShortcutsPane/void)
+
+     The name of the widget class which should be used for the side pane
+     in Thunar windows or "void" to hide the side pane completely.
+
+   * LastView (ThunarDetailsView/ThunarIconView)
+
+     The name of the widget class which should be used for the main view
+     component in Thunar windows if the DefaultView preference is "void".
+
+   * MiscFoldersFirst (FALSE/TRUE)
+     
+     Determines whether folder should be sorted before files.
+
+   * MiscHorizontalWheelNavigates (FALSE/TRUE)
+
+     Controls whether the horizontal mouse wheel is used to navigate back
+     and forth within a Thunar view, or whether it should be used for
+     horizontal scrolling.
+
+   * MiscRecursivePermissions (THUNAR_RECURSIVE_PERMISSIONS_ASK/
+                               THUNAR_RECURSIVE_PERMISSIONS_ALWAYS/
+                               THUNAR_RECURSIVE_PERMISSIONS_NEVER)
+
+     Determines whether to apply permissions recursively everytime the
+     permissions are altered by the user.
+
+   * MiscTextBesidesIcons (FALSE/TRUE)
+
+     Controls whether the icon view should display the file names beside
+     the file icons instead of below the file icons.
+
+
index 453d000..428da4f 100644 (file)
@@ -1,6 +1,6 @@
 /* $Id$ */
 /*-
- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
  *
  * 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 the Free
@@ -273,7 +273,7 @@ thunar_icon_view_init (ThunarIconView *icon_view)
   thunar_icon_view_sort_column_changed (GTK_TREE_SORTABLE (THUNAR_STANDARD_VIEW (icon_view)->model), icon_view);
 
   /* synchronize the "text-beside-icons" property with the global preference */
-  exo_binding_new (G_OBJECT (THUNAR_STANDARD_VIEW (icon_view)->preferences), "default-text-beside-icons", G_OBJECT (icon_view), "text-beside-icons");
+  exo_binding_new (G_OBJECT (THUNAR_STANDARD_VIEW (icon_view)->preferences), "misc-text-beside-icons", G_OBJECT (icon_view), "text-beside-icons");
 }
 
 
index 7575e18..22dd8a0 100644 (file)
@@ -295,7 +295,7 @@ thunar_path_entry_init (ThunarPathEntry *path_entry)
   store = thunar_list_model_new ();
   preferences = thunar_preferences_get ();
   exo_binding_new (G_OBJECT (preferences), "default-show-hidden", G_OBJECT (store), "show-hidden");
-  exo_binding_new (G_OBJECT (preferences), "default-folders-first", G_OBJECT (store), "folders-first");
+  exo_binding_new (G_OBJECT (preferences), "misc-folders-first", G_OBJECT (store), "folders-first");
   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), THUNAR_LIST_MODEL_COLUMN_REAL_NAME, GTK_SORT_ASCENDING);
   gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (store));
   g_object_unref (G_OBJECT (preferences));
index 7ca397f..14fc9cf 100644 (file)
@@ -247,7 +247,7 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog)
   g_object_unref (G_OBJECT (relation));
 
   button = gtk_check_button_new_with_mnemonic (_("Sort _folders before files"));
-  exo_mutual_binding_new (G_OBJECT (dialog->preferences), "default-folders-first", G_OBJECT (button), "active");
+  exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-folders-first", G_OBJECT (button), "active");
   gtk_tooltips_set_tip (dialog->tooltips, button, _("Select this option to list folders before files when you sort a folder."), NULL);
   gtk_table_attach (GTK_TABLE (table), button, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
   gtk_widget_show (button);
@@ -277,7 +277,7 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog)
   gtk_widget_show (table);
 
   button = gtk_check_button_new_with_mnemonic (_("_Text beside icons"));
-  exo_mutual_binding_new (G_OBJECT (dialog->preferences), "default-text-beside-icons", G_OBJECT (button), "active");
+  exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-text-beside-icons", G_OBJECT (button), "active");
   gtk_tooltips_set_tip (dialog->tooltips, button, _("Select this option to place the icon captions for items "
                                                     "beside the icon rather than below the icon."), NULL);
   gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
index 9ff4059..7247cde 100644 (file)
@@ -37,9 +37,7 @@
 #include <string.h>
 #endif
 
-#include <exo/exo.h>
-
-#include <tdb/tdb.h>
+#include <thunar-vfs/thunar-vfs.h>
 
 #include <thunar/thunar-enum-types.h>
 #include <thunar/thunar-gobject-extensions.h>
 enum
 {
   PROP_0,
-  PROP_DEFAULT_FOLDERS_FIRST,
   PROP_DEFAULT_SHOW_HIDDEN,
-  PROP_DEFAULT_TEXT_BESIDE_ICONS,
   PROP_DEFAULT_VIEW,
   PROP_LAST_LOCATION_BAR,
   PROP_LAST_SIDE_PANE,
   PROP_LAST_VIEW,
+  PROP_MISC_FOLDERS_FIRST,
+  PROP_MISC_HORIZONTAL_WHEEL_NAVIGATES,
   PROP_MISC_RECURSIVE_PERMISSIONS,
+  PROP_MISC_TEXT_BESIDE_ICONS,
   N_PROPERTIES,
 };
 
 
 
-static void thunar_preferences_class_init   (ThunarPreferencesClass *klass);
-static void thunar_preferences_init         (ThunarPreferences      *preferences);
-static void thunar_preferences_finalize     (GObject                *object);
-static void thunar_preferences_get_property (GObject                *object,
-                                             guint                   prop_id,
-                                             GValue                 *value,
-                                             GParamSpec             *pspec);
-static void thunar_preferences_set_property (GObject                *object,
-                                             guint                   prop_id,
-                                             const GValue           *value,
-                                             GParamSpec             *pspec);
+static void     thunar_preferences_class_init         (ThunarPreferencesClass *klass);
+static void     thunar_preferences_init               (ThunarPreferences      *preferences);
+static void     thunar_preferences_finalize           (GObject                *object);
+static void     thunar_preferences_get_property       (GObject                *object,
+                                                       guint                   prop_id,
+                                                       GValue                 *value,
+                                                       GParamSpec             *pspec);
+static void     thunar_preferences_set_property       (GObject                *object,
+                                                       guint                   prop_id,
+                                                       const GValue           *value,
+                                                       GParamSpec             *pspec);
+static void     thunar_preferences_resume_monitor     (ThunarPreferences      *preferences);
+static void     thunar_preferences_suspend_monitor    (ThunarPreferences      *preferences);
+static void     thunar_preferences_monitor            (ThunarVfsMonitor       *monitor,
+                                                       ThunarVfsMonitorHandle *handle,
+                                                       ThunarVfsMonitorEvent   event,
+                                                       ThunarVfsPath          *handle_path,
+                                                       ThunarVfsPath          *event_path,
+                                                       gpointer                user_data);
+static void     thunar_preferences_queue_load         (ThunarPreferences      *preferences);
+static void     thunar_preferences_queue_store        (ThunarPreferences      *preferences);
+static gboolean thunar_preferences_load_idle          (gpointer                user_data);
+static void     thunar_preferences_load_idle_destroy  (gpointer                user_data);
+static gboolean thunar_preferences_store_idle         (gpointer                user_data);
+static void     thunar_preferences_store_idle_destroy (gpointer                user_data);
 
 
 
@@ -87,8 +100,15 @@ struct _ThunarPreferences
 {
   GObject __parent__;
 
-  /* the database context */
-  TDB_CONTEXT *context;
+  ThunarVfsMonitorHandle *handle;
+  ThunarVfsMonitor       *monitor;
+
+  GValue                  values[N_PROPERTIES];
+
+  gboolean                loading_in_progress;
+
+  gint                    load_idle_id;
+  gint                    store_idle_id;
 };
 
 
@@ -143,19 +163,6 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
   thunar_g_initialize_transformations ();
 
   /**
-   * ThunarPreferences::default-folders-first:
-   *
-   * Whether to sort folders before files.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_DEFAULT_FOLDERS_FIRST,
-                                   g_param_spec_boolean ("default-folders-first",
-                                                         "default-folders-first",
-                                                         "default-folders-first",
-                                                         TRUE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
    * ThunarPreferences::default-show-hidden:
    *
    * Whether to show hidden files by default in new windows.
@@ -169,20 +176,6 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
                                                          EXO_PARAM_READWRITE));
 
   /**
-   * ThunarPreferences::default-text-beside-icons:
-   *
-   * Whether the icon view should display the file names beside the
-   * file icons instead of below the file icons.
-   **/
-  g_object_class_install_property (gobject_class,
-                                   PROP_DEFAULT_TEXT_BESIDE_ICONS,
-                                   g_param_spec_boolean ("default-text-beside-icons",
-                                                         "default-text-beside-icons",
-                                                         "default-text-beside-icons",
-                                                         FALSE,
-                                                         EXO_PARAM_READWRITE));
-
-  /**
    * ThunarPreferences::default-view:
    *
    * The name of the widget class, which should be used for the
@@ -242,6 +235,33 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
                                                         EXO_PARAM_READWRITE));
 
   /**
+   * ThunarPreferences::misc-folders-first:
+   *
+   * Whether to sort folders before files.
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_FOLDERS_FIRST,
+                                   g_param_spec_boolean ("misc-folders-first",
+                                                         "misc-folders-first",
+                                                         "misc-folders-first",
+                                                         TRUE,
+                                                         EXO_PARAM_READWRITE));
+
+  /**
+   * ThunarPreferences:misc-horizontal-wheel-navigates:
+   *
+   * Whether the horizontal mouse wheel is used to navigate
+   * forth and back within a Thunar view.
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_HORIZONTAL_WHEEL_NAVIGATES,
+                                   g_param_spec_boolean ("misc-horizontal-wheel-navigates",
+                                                         "misc-horizontal-wheel-navigates",
+                                                         "misc-horizontal-wheel-navigates",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  /**
    * ThunarPreferences:misc-recursive-permissions:
    *
    * Whether to apply permissions recursively everytime the
@@ -255,6 +275,20 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
                                                       THUNAR_TYPE_RECURSIVE_PERMISSIONS,
                                                       THUNAR_RECURSIVE_PERMISSIONS_ASK,
                                                       EXO_PARAM_READWRITE));
+
+  /**
+   * ThunarPreferences::misc-text-beside-icons:
+   *
+   * Whether the icon view should display the file names beside the
+   * file icons instead of below the file icons.
+   **/
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_TEXT_BESIDE_ICONS,
+                                   g_param_spec_boolean ("misc-text-beside-icons",
+                                                         "misc-text-beside-icons",
+                                                         "misc-text-beside-icons",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
 }
 
 
@@ -262,25 +296,18 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass)
 static void
 thunar_preferences_init (ThunarPreferences *preferences)
 {
-  gchar *path;
+  /* setup the preferences object */
+  preferences->load_idle_id = -1;
+  preferences->store_idle_id = -1;
 
-  /* determine the path to the preferences database */
-  path = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Thunar/preferences.tdb", TRUE);
-  if (G_UNLIKELY (path == NULL))
-    {
-      path = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Thunar/", FALSE);
-      g_warning (_("Failed to create the Thunar configuration directory in %s"), path);
-      g_free (path);
-      return;
-    }
+  /* grab a reference on the VFS monitor */
+  preferences->monitor = thunar_vfs_monitor_get_default ();
 
-  /* try to open the preferences database file */
-  preferences->context = tdb_open (path, 0, TDB_DEFAULT, O_CREAT | O_RDWR, 0600);
-  if (G_UNLIKELY (preferences->context == NULL))
-    g_warning (_("Failed to open preferences database in %s: %s"), path, g_strerror (errno));
+  /* load the settings */
+  thunar_preferences_load_idle (preferences);
 
-  /* release the path */
-  g_free (path);
+  /* launch the file monitor */
+  thunar_preferences_resume_monitor (preferences);
 }
 
 
@@ -289,29 +316,32 @@ static void
 thunar_preferences_finalize (GObject *object)
 {
   ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
+  guint              n;
 
-  /* close the database (if open) */
-  if (G_LIKELY (preferences->context != NULL))
-    tdb_close (preferences->context);
-
-  (*G_OBJECT_CLASS (thunar_preferences_parent_class)->finalize) (object);
-}
-
-
-
-static inline void
-value_take_string (GValue  *value,
-                   gpointer data)
-{
-  if (G_LIKELY (g_mem_is_system_malloc ()))
+  /* flush preferences */
+  if (G_UNLIKELY (preferences->store_idle_id >= 0))
     {
-      g_value_take_string (value, data);
+      thunar_preferences_store_idle (preferences);
+      g_source_remove (preferences->store_idle_id);
     }
-  else
+
+  /* stop any pending load idle source */
+  if (G_UNLIKELY (preferences->load_idle_id >= 0))
+    g_source_remove (preferences->load_idle_id);
+
+  /* stop the file monitor */
+  if (G_LIKELY (preferences->monitor != NULL))
     {
-      g_value_set_string (value, data);
-      free (data);
+      thunar_preferences_suspend_monitor (preferences);
+      g_object_unref (G_OBJECT (preferences->monitor));
     }
+
+  /* release the property values */
+  for (n = 1; n < N_PROPERTIES; ++n)
+    if (G_IS_VALUE (preferences->values + n))
+      g_value_unset (preferences->values + n);
+
+  (*G_OBJECT_CLASS (thunar_preferences_parent_class)->finalize) (object);
 }
 
 
@@ -323,100 +353,321 @@ thunar_preferences_get_property (GObject    *object,
                                  GParamSpec *pspec)
 {
   ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
-  TDB_DATA           data;
-  GValue             tmp = { 0, };
+  GValue            *src;
 
-  g_return_if_fail (prop_id > PROP_0 && prop_id < N_PROPERTIES);
+  g_return_if_fail (prop_id < N_PROPERTIES);
 
-  /* check if we have a database handle */
-  if (G_LIKELY (preferences->context != NULL))
+  src = preferences->values + prop_id;
+  if (G_IS_VALUE (src))
+    g_value_copy (src, value);
+  else
+    g_param_value_set_default (pspec, value);
+}
+
+
+
+static void
+thunar_preferences_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
+  GValue            *dst;
+
+  g_return_if_fail (prop_id < N_PROPERTIES);
+
+  dst = preferences->values + prop_id;
+  if (G_UNLIKELY (!G_IS_VALUE (dst)))
+    g_value_init (dst, pspec->value_type);
+
+  if (g_param_values_cmp (pspec, value, dst) != 0)
     {
-      /* use the param spec's name as key */
-      data.dptr = pspec->name;
-      data.dsize = strlen (data.dptr);
+      g_value_copy (value, dst);
+      g_object_notify (object, pspec->name);
+      thunar_preferences_queue_store (preferences);
+    }
+}
+
 
-      /* lookup the data for the key */
-      data = tdb_fetch (preferences->context, data);
-      if (data.dptr != NULL && data.dsize > 0 && data.dptr[data.dsize - 1] == '\0')
+
+static void
+thunar_preferences_resume_monitor (ThunarPreferences *preferences)
+{
+  ThunarVfsPath *path;
+  gchar         *filename;
+
+  /* verify that the monitor is suspended */
+  if (G_LIKELY (preferences->handle == NULL))
+    {
+      /* determine the save location for thunarrc to monitor */
+      filename = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Thunar/thunarrc", TRUE);
+      if (G_LIKELY (filename != NULL))
         {
-          /* check if we have a string or can transform */
-          if (G_VALUE_TYPE (value) == G_TYPE_STRING)
+          /* determine the VFS path for the filename */
+          path = thunar_vfs_path_new (filename, NULL);
+          if (G_LIKELY (path != NULL))
             {
-              value_take_string (value, data.dptr);
-              return;
-            }
-          else if (g_value_type_transformable (G_TYPE_STRING, G_VALUE_TYPE (value)))
-            {
-              /* try to transform the string */
-              g_value_init (&tmp, G_TYPE_STRING);
-              value_take_string (&tmp, data.dptr);
-              if (g_value_transform (&tmp, value))
-                {
-                  g_value_unset (&tmp);
-                  return;
-                }
-              g_value_unset (&tmp);
-
-              /* data.dptr was freed by the g_value_unset() call */
-              data.dptr = NULL;
+              /* add the monitor handle for the file */
+              preferences->handle = thunar_vfs_monitor_add_file (preferences->monitor, path, thunar_preferences_monitor, preferences);
+              thunar_vfs_path_unref (path);
             }
+
+          /* release the filename */
+          g_free (filename);
         }
+    }
+}
+
+
 
-      /* release the data (if any) */
-      if (data.dptr != NULL)
-        free (data.dptr);
+static void
+thunar_preferences_suspend_monitor (ThunarPreferences *preferences)
+{
+  /* verify that the monitor is active */
+  if (G_LIKELY (preferences->handle != NULL))
+    {
+      /* disconnect the handle from the monitor */
+      thunar_vfs_monitor_remove (preferences->monitor, preferences->handle);
+      preferences->handle = NULL;
     }
+}
+
 
-  /* set the default value */
-  g_param_value_set_default (pspec, value);
+
+static void
+thunar_preferences_monitor (ThunarVfsMonitor       *monitor,
+                            ThunarVfsMonitorHandle *handle,
+                            ThunarVfsMonitorEvent   event,
+                            ThunarVfsPath          *handle_path,
+                            ThunarVfsPath          *event_path,
+                            gpointer                user_data)
+{
+  ThunarPreferences *preferences = THUNAR_PREFERENCES (user_data);
+
+  g_return_if_fail (THUNAR_IS_PREFERENCES (preferences));
+  g_return_if_fail (THUNAR_VFS_IS_MONITOR (monitor));
+  g_return_if_fail (preferences->monitor == monitor);
+  g_return_if_fail (preferences->handle == handle);
+
+  /* schedule a reload whenever the file is created/changed */
+  if (event == THUNAR_VFS_MONITOR_EVENT_CHANGED || event == THUNAR_VFS_MONITOR_EVENT_CREATED)
+    thunar_preferences_queue_load (preferences);
 }
 
 
 
 static void
-thunar_preferences_set_property (GObject      *object,
-                                 guint         prop_id,
-                                 const GValue *value,
-                                 GParamSpec   *pspec)
+thunar_preferences_queue_load (ThunarPreferences *preferences)
 {
-  ThunarPreferences *preferences = THUNAR_PREFERENCES (object);
-  TDB_DATA           data;
-  TDB_DATA           key;
-  GValue             dst = { 0, };
+  if (preferences->load_idle_id < 0 && preferences->store_idle_id < 0)
+    {
+      preferences->load_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_preferences_load_idle,
+                                                   preferences, thunar_preferences_load_idle_destroy);
+    }
+}
+
 
-  g_return_if_fail (prop_id > PROP_0 && prop_id < N_PROPERTIES);
 
-  /* save the new value if we have a database handle */
-  if (G_LIKELY (preferences->context != NULL))
+static void
+thunar_preferences_queue_store (ThunarPreferences *preferences)
+{
+  if (preferences->store_idle_id < 0 && !preferences->loading_in_progress)
     {
-      /* generate the key for the operation */
-      key.dptr = pspec->name;
-      key.dsize = strlen (key.dptr);
+      preferences->store_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_preferences_store_idle,
+                                                    preferences, thunar_preferences_store_idle_destroy);
+    }
+}
+
+
 
-      /* check if we have the default value here */
-      if (g_param_value_defaults (pspec, (GValue *) value))
+static gchar*
+property_name_to_option_name (const gchar *property_name)
+{
+  const gchar *s;
+  gboolean     upper = TRUE;
+  gchar       *option;
+  gchar       *t;
+
+  option = g_new (gchar, strlen (property_name) + 1);
+  for (s = property_name, t = option; *s != '\0'; ++s)
+    {
+      if (*s == '-')
         {
-          /* just delete as we don't store defaults */
-          tdb_delete (preferences->context, key);
+          upper = TRUE;
+        }
+      else if (upper)
+        {
+          *t++ = g_ascii_toupper (*s);
+          upper = FALSE;
         }
       else
         {
-          /* transform the value to a string */
-          g_value_init (&dst, G_TYPE_STRING);
-          if (!g_value_transform (value, &dst))
-            g_warning ("Unable to transform %s to %s", g_type_name (G_VALUE_TYPE (value)), g_type_name (G_VALUE_TYPE (&dst)));
+          *t++ = *s;
+        }
+    }
+  *t = '\0';
+
+  return option;
+}
 
-          /* setup the data value (we also store the '\0' byte) */
-          data.dptr = (gchar *) g_value_get_string (&dst);
-          data.dsize = strlen (data.dptr) + 1;
 
-          /* perform the store operation */
-          tdb_store (preferences->context, key, data, TDB_REPLACE);
 
-          /* release the string */
+static gboolean
+thunar_preferences_load_idle (gpointer user_data)
+{
+  ThunarPreferences *preferences = THUNAR_PREFERENCES (user_data);
+  const gchar       *string;
+  GParamSpec       **specs;
+  GParamSpec        *spec;
+  XfceRc            *rc;
+  GValue             dst = { 0, };
+  GValue             src = { 0, };
+  gchar             *option;
+  guint              nspecs;
+  guint              n;
+
+  rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Thunar/thunarrc", TRUE);
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_warning ("Unable to load thunar preferences.");
+      return FALSE;
+    }
+
+  g_object_freeze_notify (G_OBJECT (preferences));
+
+  xfce_rc_set_group (rc, "Configuration");
+
+  preferences->loading_in_progress = TRUE;
+
+  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (preferences), &nspecs);
+  for (n = 0; n < nspecs; ++n)
+    {
+      spec = specs[n];
+
+      option = property_name_to_option_name (spec->name);
+      string = xfce_rc_read_entry (rc, option, NULL);
+      g_free (option);
+
+      if (G_UNLIKELY (string == NULL))
+        continue;
+
+      g_value_init (&src, G_TYPE_STRING);
+      g_value_set_static_string (&src, string);
+
+      if (spec->value_type == G_TYPE_STRING)
+        {
+          g_object_set_property (G_OBJECT (preferences), spec->name, &src);
+        }
+      else if (g_value_type_transformable (G_TYPE_STRING, spec->value_type))
+        {
+          g_value_init (&dst, spec->value_type);
+          if (g_value_transform (&src, &dst))
+            g_object_set_property (G_OBJECT (preferences), spec->name, &dst);
           g_value_unset (&dst);
         }
+      else
+        {
+          g_warning ("Unable to load property \"%s\"", spec->name);
+        }
+
+      g_value_unset (&src);
+    }
+  g_free (specs);
+
+  preferences->loading_in_progress = FALSE;
+
+  xfce_rc_close (rc);
+
+  g_object_thaw_notify (G_OBJECT (preferences));
+
+  return FALSE;
+}
+
+
+
+static void
+thunar_preferences_load_idle_destroy (gpointer user_data)
+{
+  THUNAR_PREFERENCES (user_data)->load_idle_id = -1;
+}
+
+
+
+static gboolean
+thunar_preferences_store_idle (gpointer user_data)
+{
+  ThunarPreferences *preferences = THUNAR_PREFERENCES (user_data);
+  const gchar       *string;
+  GParamSpec       **specs;
+  GParamSpec        *spec;
+  XfceRc            *rc;
+  GValue             dst = { 0, };
+  GValue             src = { 0, };
+  gchar             *option;
+  guint              nspecs;
+  guint              n;
+
+  rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Thunar/thunarrc", FALSE);
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_warning ("Unable to store thunar preferences.");
+      return FALSE;
     }
+
+  /* suspend the monitor (hopefully tricking FAM to avoid unnecessary reloads) */
+  thunar_preferences_suspend_monitor (preferences);
+
+  xfce_rc_set_group (rc, "Configuration");
+
+  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (preferences), &nspecs);
+  for (n = 0; n < nspecs; ++n)
+    {
+      spec = specs[n];
+
+      g_value_init (&dst, G_TYPE_STRING);
+
+      if (spec->value_type == G_TYPE_STRING)
+        {
+          g_object_get_property (G_OBJECT (preferences), spec->name, &dst);
+        }
+      else
+        {
+          g_value_init (&src, spec->value_type);
+          g_object_get_property (G_OBJECT (preferences), spec->name, &src);
+          g_value_transform (&src, &dst);
+          g_value_unset (&src);
+        }
+
+      /* determine the option name for the spec */
+      option = property_name_to_option_name (spec->name);
+
+      /* store the setting */
+      string = g_value_get_string (&dst);
+      if (G_LIKELY (string != NULL))
+        xfce_rc_write_entry (rc, option, string);
+
+      /* cleanup */
+      g_value_unset (&dst);
+      g_free (option);
+    }
+
+  /* cleanup */
+  xfce_rc_close (rc);
+  g_free (specs);
+
+  /* restart the monitor */
+  thunar_preferences_resume_monitor (preferences);
+
+  return FALSE;
+}
+
+
+
+static void
+thunar_preferences_store_idle_destroy (gpointer user_data)
+{
+  THUNAR_PREFERENCES (user_data)->store_idle_id = -1;
 }
 
 
index e66093a..faf84cb 100644 (file)
@@ -475,7 +475,7 @@ thunar_standard_view_init (ThunarStandardView *standard_view)
   /* setup the list model */
   standard_view->model = thunar_list_model_new ();
   g_signal_connect (G_OBJECT (standard_view->model), "error", G_CALLBACK (thunar_standard_view_error), standard_view);
-  exo_binding_new (G_OBJECT (standard_view->preferences), "default-folders-first", G_OBJECT (standard_view->model), "folders-first");
+  exo_binding_new (G_OBJECT (standard_view->preferences), "misc-folders-first", G_OBJECT (standard_view->model), "folders-first");
 
   /* setup the icon renderer */
   standard_view->icon_renderer = thunar_icon_renderer_new ();
@@ -1921,20 +1921,26 @@ thunar_standard_view_scroll_event (GtkWidget          *view,
                                    ThunarStandardView *standard_view)
 {
   GtkAction *action = NULL;
+  gboolean   misc_horizontal_wheel_navigates;
 
   g_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE);
 
-  /* determine the appropriate action ("back" for scroll left, "forward" for scroll right) */
-  if (G_UNLIKELY (event->type == GDK_SCROLL && event->direction == GDK_SCROLL_LEFT))
-    action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/back");
-  else if (G_UNLIKELY (event->type == GDK_SCROLL && event->direction == GDK_SCROLL_RIGHT))
-    action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/forward");
-
-  /* perform the action (if any) */
-  if (G_UNLIKELY (action != NULL))
+  /* check if we should use the horizontal mouse wheel for navigation */
+  g_object_get (G_OBJECT (standard_view->preferences), "misc-horizontal-wheel-navigates", &misc_horizontal_wheel_navigates, NULL);
+  if (G_UNLIKELY (misc_horizontal_wheel_navigates))
     {
-      gtk_action_activate (action);
-      return TRUE;
+      /* determine the appropriate action ("back" for scroll left, "forward" for scroll right) */
+      if (G_UNLIKELY (event->type == GDK_SCROLL && event->direction == GDK_SCROLL_LEFT))
+        action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/back");
+      else if (G_UNLIKELY (event->type == GDK_SCROLL && event->direction == GDK_SCROLL_RIGHT))
+        action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/forward");
+
+      /* perform the action (if any) */
+      if (G_UNLIKELY (action != NULL))
+        {
+          gtk_action_activate (action);
+          return TRUE;
+        }
     }
 
   /* next please... */