[gnome-desktop] gnome-desktop-thumbnail: Don't use GConf to handle external thumbnailers



commit 3036c247dfd8c618671a010c8d9ddd4141062bfb
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Thu Dec 30 12:51:23 2010 +0100

    gnome-desktop-thumbnail: Don't use GConf to handle external thumbnailers
    
    Thumbnailers are now registered using key files, similar to .desktop
    files. Bug #638172.

 configure.ac                               |    5 +-
 libgnome-desktop/gnome-desktop-thumbnail.c |  590 +++++++++++++++++++++-------
 2 files changed, 458 insertions(+), 137 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1c42cf8..c497eb2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,14 +89,13 @@ dnl it too, or it will never make it into the spec file!
 GDK_PIXBUF_REQUIRED=2.21.3
 GTK_REQUIRED=2.90.2
 GLIB_REQUIRED=2.19.1
-GCONF_REQUIRED=2.0.0
 STARTUP_NOTIFICATION_REQUIRED=0.5
 XRANDR_REQUIRED=1.2
+GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=0.1.4
 
 AC_SUBST(GTK_REQUIRED)
 AC_SUBST(GLIB_REQUIRED)
 AC_SUBST(GDK_PIXBUF_REQUIRED)
-AC_SUBST(GCONF_REQUIRED)
 AC_SUBST(STARTUP_NOTIFICATION_REQUIRED)
 AC_SUBST(XRANDR_REQUIRED)
 
@@ -150,7 +149,7 @@ AC_SUBST(RANDR_PACKAGE)
 
 dnl pkg-config dependency checks
 
-PKG_CHECK_MODULES(GNOME_DESKTOP, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED $STARTUP_NOTIFICATION_PACKAGE $RANDR_PACKAGE gsettings-desktop-schemas)
+PKG_CHECK_MODULES(GNOME_DESKTOP, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED gsettings-desktop-schemas >= $GSETTINGS_DESKTOP_SCHEMAS_REQUIRED $STARTUP_NOTIFICATION_PACKAGE $RANDR_PACKAGE)
 
 dnl gnome-doc-utils stuff
 
diff --git a/libgnome-desktop/gnome-desktop-thumbnail.c b/libgnome-desktop/gnome-desktop-thumbnail.c
index 9f2d7f4..fb42e79 100644
--- a/libgnome-desktop/gnome-desktop-thumbnail.c
+++ b/libgnome-desktop/gnome-desktop-thumbnail.c
@@ -2,6 +2,7 @@
  * gnome-thumbnail.c: Utilities for handling thumbnails
  *
  * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc gnome org>
  *
  * This file is part of the Gnome Library.
  *
@@ -41,8 +42,6 @@
 
 #define GNOME_DESKTOP_USE_UNSTABLE_API
 #include "gnome-desktop-thumbnail.h"
-#include <gconf/gconf.h>
-#include <gconf/gconf-client.h>
 #include <glib/gstdio.h>
 
 #define SECONDS_BETWEEN_STATS 10
@@ -52,9 +51,14 @@ struct _GnomeDesktopThumbnailFactoryPrivate {
 
   GMutex *lock;
 
-  GHashTable *scripts_hash;
-  guint thumbnailers_notify;
-  guint reread_scheduled;
+  GList *thumbnailers;
+  GHashTable *mime_types_map;
+  GList *monitors;
+
+  GSettings *settings;
+  gboolean loaded : 1;
+  gboolean disabled : 1;
+  gchar **disabled_types;
 };
 
 static const char *appname = "gnome-thumbnail-factory";
@@ -80,6 +84,174 @@ typedef struct {
 
 #define LOAD_BUFFER_SIZE 4096
 
+#define THUMBNAILER_ENTRY_GROUP "Thumbnailer Entry"
+#define THUMBNAILER_EXTENSION   ".thumbnailer"
+
+typedef struct {
+    volatile gint ref_count;
+
+    gchar *path;
+
+    gchar  *try_exec;
+    gchar  *command;
+    gchar **mime_types;
+} Thumbnailer;
+
+static Thumbnailer *
+thumbnailer_ref (Thumbnailer *thumb)
+{
+  g_return_val_if_fail (thumb != NULL, NULL);
+  g_return_val_if_fail (thumb->ref_count > 0, NULL);
+
+  g_atomic_int_inc (&thumb->ref_count);
+  return thumb;
+}
+
+static void
+thumbnailer_unref (Thumbnailer *thumb)
+{
+  g_return_if_fail (thumb != NULL);
+  g_return_if_fail (thumb->ref_count > 0);
+
+  if (g_atomic_int_dec_and_test (&thumb->ref_count))
+    {
+      g_free (thumb->path);
+      g_free (thumb->try_exec);
+      g_free (thumb->command);
+      g_strfreev (thumb->mime_types);
+
+      g_slice_free (Thumbnailer, thumb);
+    }
+}
+
+static Thumbnailer *
+thumbnailer_load (Thumbnailer *thumb)
+{
+  GKeyFile *key_file;
+  GError *error = NULL;
+
+  key_file = g_key_file_new ();
+  if (!g_key_file_load_from_file (key_file, thumb->path, 0, &error))
+    {
+      g_warning ("Failed to load thumbnailer from \"%s\": %s\n", thumb->path, error->message);
+      g_error_free (error);
+      thumbnailer_unref (thumb);
+      g_key_file_free (key_file);
+
+      return NULL;
+    }
+
+  if (!g_key_file_has_group (key_file, THUMBNAILER_ENTRY_GROUP))
+    {
+      g_warning ("Invalid thumbnailer: missing group \"%s\"\n", THUMBNAILER_ENTRY_GROUP);
+      thumbnailer_unref (thumb);
+      g_key_file_free (key_file);
+
+      return NULL;
+    }
+
+  thumb->command = g_key_file_get_string (key_file, THUMBNAILER_ENTRY_GROUP, "Exec", NULL);
+  if (!thumb->command)
+    {
+      g_warning ("Invalid thumbnailer: missing Exec key\n");
+      thumbnailer_unref (thumb);
+      g_key_file_free (key_file);
+
+      return NULL;
+    }
+
+  thumb->mime_types = g_key_file_get_string_list (key_file, THUMBNAILER_ENTRY_GROUP, "MimeType", NULL, NULL);
+  if (!thumb->mime_types)
+    {
+      g_warning ("Invalid thumbnailer: missing MimeType key\n");
+      thumbnailer_unref (thumb);
+      g_key_file_free (key_file);
+
+      return NULL;
+    }
+
+  thumb->try_exec = g_key_file_get_string (key_file, THUMBNAILER_ENTRY_GROUP, "TryExec", NULL);
+
+  g_key_file_free (key_file);
+
+  return thumb;
+}
+
+static Thumbnailer *
+thumbnailer_reload (Thumbnailer *thumb)
+{
+  g_return_val_if_fail (thumb != NULL, NULL);
+
+  g_free (thumb->command);
+  thumb->command = NULL;
+  g_strfreev (thumb->mime_types);
+  thumb->mime_types = NULL;
+  g_free (thumb->try_exec);
+  thumb->try_exec = NULL;
+
+  return thumbnailer_load (thumb);
+}
+
+static Thumbnailer *
+thumbnailer_new (const gchar *path)
+{
+  Thumbnailer *thumb;
+
+  thumb = g_slice_new0 (Thumbnailer);
+  thumb->ref_count = 1;
+  thumb->path = g_strdup (path);
+
+  return thumbnailer_load (thumb);
+}
+
+static gboolean
+thumbnailer_try_exec (Thumbnailer *thumb)
+{
+  gchar *path;
+  gboolean retval;
+
+  if (G_UNLIKELY (!thumb))
+    return FALSE;
+
+  /* TryExec is optinal, but Exec isn't, so we assume
+   * the thumbnailer can be run when TryExec is not present
+   */
+  if (!thumb->try_exec)
+    return TRUE;
+
+  path = g_find_program_in_path (thumb->try_exec);
+  retval = path != NULL;
+  g_free (path);
+
+  return retval;
+}
+
+static gpointer
+init_thumbnailers_dirs (gpointer data)
+{
+  const gchar * const *data_dirs;
+  gchar **thumbs_dirs;
+  guint i, length;
+
+  data_dirs = g_get_system_data_dirs ();
+  length = g_strv_length ((char **) data_dirs);
+
+  thumbs_dirs = g_new (gchar *, length + 2);
+  thumbs_dirs[0] = g_build_filename (g_get_user_data_dir (), "thumbnailers", NULL);
+  for (i = 1; i < length; i++)
+    thumbs_dirs[i] = g_build_filename (data_dirs[i], "thumbnailers", NULL);
+  thumbs_dirs[length] = NULL;
+
+  return thumbs_dirs;
+}
+
+static const gchar * const *
+get_thumbnailers_dirs (void)
+{
+  static GOnce once_init = G_ONCE_INIT;
+  return g_once (&once_init, init_thumbnailers_dirs, NULL);
+}
+
 static void
 size_prepared_cb (GdkPixbufLoader *loader, 
 		  int              width,
@@ -256,28 +428,27 @@ gnome_desktop_thumbnail_factory_finalize (GObject *object)
 {
   GnomeDesktopThumbnailFactory *factory;
   GnomeDesktopThumbnailFactoryPrivate *priv;
-  GConfClient *client;
   
   factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
 
   priv = factory->priv;
-  
-  if (priv->reread_scheduled != 0) {
-    g_source_remove (priv->reread_scheduled);
-    priv->reread_scheduled = 0;
-  }
 
-  if (priv->thumbnailers_notify != 0) {
-    client = gconf_client_get_default ();
-    gconf_client_notify_remove (client, priv->thumbnailers_notify);
-    priv->thumbnailers_notify = 0;
-    g_object_unref (client);
-  }
-  
-  if (priv->scripts_hash)
+  if (priv->thumbnailers)
+    {
+      g_list_free_full (priv->thumbnailers, (GDestroyNotify)thumbnailer_unref);
+      priv->thumbnailers = NULL;
+    }
+
+  if (priv->mime_types_map)
+    {
+      g_hash_table_destroy (priv->mime_types_map);
+      priv->mime_types_map = NULL;
+    }
+
+  if (priv->monitors)
     {
-      g_hash_table_destroy (priv->scripts_hash);
-      priv->scripts_hash = NULL;
+      g_list_free_full (priv->monitors, (GDestroyNotify)g_object_unref);
+      priv->monitors = NULL;
     }
 
   if (priv->lock)
@@ -285,146 +456,286 @@ gnome_desktop_thumbnail_factory_finalize (GObject *object)
       g_mutex_free (priv->lock);
       priv->lock = NULL;
     }
-  
+
+  if (priv->disabled_types)
+    {
+      g_strfreev (priv->disabled_types);
+      priv->disabled_types = NULL;
+    }
+
+  if (priv->settings)
+    {
+      g_object_unref (priv->settings);
+      priv->settings = NULL;
+    }
+
   if (G_OBJECT_CLASS (parent_class)->finalize)
     (* G_OBJECT_CLASS (parent_class)->finalize) (object);
 }
 
-/* Must be called on main thread */
-static GHashTable *
-read_scripts (void)
+/* These should be called with the lock held */
+static void
+gnome_desktop_thumbnail_factory_register_mime_types (GnomeDesktopThumbnailFactory *factory,
+                                                     Thumbnailer                  *thumb)
 {
-  GHashTable *scripts_hash;
-  GConfClient *client;
-  GSList *subdirs, *l;
-  char *subdir, *enable, *escape, *commandkey, *command, *mimetype;
-
-  client = gconf_client_get_default ();
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+  gint i;
 
-  if (gconf_client_get_bool (client,
-			     "/desktop/gnome/thumbnailers/disable_all",
-			     NULL))
+  for (i = 0; thumb->mime_types[i]; i++)
     {
-      g_object_unref (G_OBJECT (client));
-      return NULL;
+      if (!g_hash_table_lookup (priv->mime_types_map, thumb->mime_types[i]))
+        g_hash_table_insert (priv->mime_types_map,
+                             g_strdup (thumb->mime_types[i]),
+                             thumbnailer_ref (thumb));
     }
-  
-  scripts_hash = g_hash_table_new_full (g_str_hash,
-					g_str_equal,
-					g_free, g_free);
+}
 
-  
-  subdirs = gconf_client_all_dirs (client, "/desktop/gnome/thumbnailers", NULL);
+static void
+gnome_desktop_thumbnail_factory_add_thumbnailer (GnomeDesktopThumbnailFactory *factory,
+                                                 Thumbnailer                  *thumb)
+{
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
 
-  for (l = subdirs; l != NULL; l = l->next)
-    {
-      subdir = l->data;
+  gnome_desktop_thumbnail_factory_register_mime_types (factory, thumb);
+  priv->thumbnailers = g_list_prepend (priv->thumbnailers, thumb);
+}
 
-      enable = g_strdup_printf ("%s/enable", subdir);
-      if (gconf_client_get_bool (client,
-				 enable,
-				 NULL))
-	{
-	  commandkey = g_strdup_printf ("%s/command", subdir);
-	  command = gconf_client_get_string (client, commandkey, NULL);
-	  g_free (commandkey);
-
-	  if (command != NULL) {
-	    mimetype = strrchr (subdir, '/');
-	    if (mimetype != NULL)
-	      {
-		mimetype++; /* skip past slash */
-		
-		/* Convert '@' to slash in mimetype */
-		escape = strchr (mimetype, '@');
-		if (escape != NULL)
-		  *escape = '/';
-
-		/* Convert any remaining '@' to '+' in mimetype */
-		while ((escape = strchr (mimetype, '@')) != NULL)
-                  *escape = '+';
-
-		g_hash_table_insert (scripts_hash,
-				     g_strdup (mimetype), command);
-	      }
-	    else
-	      {
-		g_free (command);
-	      }
-	  }
-	}
-      g_free (enable);
-      
-      g_free (subdir);
+static gboolean
+gnome_desktop_thumbnail_factory_is_disabled (GnomeDesktopThumbnailFactory *factory,
+                                             const gchar                  *mime_type)
+{
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+  guint i;
+
+  if (priv->disabled)
+    return TRUE;
+
+  if (!priv->disabled_types)
+    return FALSE;
+
+  for (i = 0; priv->disabled_types[i]; i++)
+    {
+      if (g_strcmp0 (priv->disabled_types[i], mime_type) == 0)
+        return TRUE;
     }
-  
-  g_slist_free(subdirs);
 
-  g_object_unref (G_OBJECT (client));
-  
-  return scripts_hash;
+  return FALSE;
+}
+
+static gboolean
+remove_thumbnailer_from_mime_type_map (gchar       *key,
+                                       Thumbnailer *value,
+                                       gchar       *path)
+{
+  return (strcmp (value->path, path) == 0);
 }
 
 
-/* Must be called on main thread */
 static void
-gnome_desktop_thumbnail_factory_reread_scripts (GnomeDesktopThumbnailFactory *factory)
+update_or_create_thumbnailer (GnomeDesktopThumbnailFactory *factory,
+                              const gchar                  *path)
 {
   GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
-  GHashTable *scripts_hash;
-
-  scripts_hash = read_scripts ();
+  GList *l;
+  Thumbnailer *thumb;
+  gboolean found = FALSE;
 
   g_mutex_lock (priv->lock);
 
-  if (priv->scripts_hash != NULL)
-    g_hash_table_destroy (priv->scripts_hash);
-  
-  priv->scripts_hash = scripts_hash;
-  
+  for (l = priv->thumbnailers; l && !found; l = g_list_next (l))
+    {
+      thumb = (Thumbnailer *)l->data;
+
+      if (strcmp (thumb->path, path) == 0)
+        {
+          found = TRUE;
+
+          /* First remove the mime_types associated to this thumbnailer */
+          g_hash_table_foreach_remove (priv->mime_types_map,
+                                       (GHRFunc)remove_thumbnailer_from_mime_type_map,
+                                       (gpointer)path);
+          if (!thumbnailer_reload (thumb))
+              priv->thumbnailers = g_list_delete_link (priv->thumbnailers, l);
+          else
+              gnome_desktop_thumbnail_factory_register_mime_types (factory, thumb);
+        }
+    }
+
+  if (!found)
+    {
+      thumb = thumbnailer_new (path);
+      if (thumb)
+        gnome_desktop_thumbnail_factory_add_thumbnailer (factory, thumb);
+    }
+
   g_mutex_unlock (priv->lock);
 }
 
-static gboolean
-reread_idle_callback (gpointer user_data)
+static void
+remove_thumbnailer (GnomeDesktopThumbnailFactory *factory,
+                    const gchar                  *path)
 {
-  GnomeDesktopThumbnailFactory *factory = user_data;
   GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
-
-  gnome_desktop_thumbnail_factory_reread_scripts (factory);
+  GList *l;
+  Thumbnailer *thumb;
 
   g_mutex_lock (priv->lock);
-  priv->reread_scheduled = 0;
+
+  for (l = priv->thumbnailers; l; l = g_list_next (l))
+    {
+      thumb = (Thumbnailer *)l->data;
+
+      if (strcmp (thumb->path, path) == 0)
+        {
+          priv->thumbnailers = g_list_delete_link (priv->thumbnailers, l);
+          g_hash_table_foreach_remove (priv->mime_types_map,
+                                       (GHRFunc)remove_thumbnailer_from_mime_type_map,
+                                       (gpointer)path);
+          thumbnailer_unref (thumb);
+
+          break;
+        }
+    }
+
   g_mutex_unlock (priv->lock);
-   
-  return FALSE;
 }
 
 static void
-schedule_reread (GConfClient* client,
-		 guint cnxn_id,
-		 GConfEntry *entry,
-		 gpointer user_data)
+thumbnailers_directory_changed (GFileMonitor                 *monitor,
+                                GFile                        *file,
+                                GFile                        *other_file,
+                                GFileMonitorEvent             event_type,
+                                GnomeDesktopThumbnailFactory *factory)
+{
+  gchar *path;
+
+  switch (event_type)
+    {
+    case G_FILE_MONITOR_EVENT_CREATED:
+    case G_FILE_MONITOR_EVENT_CHANGED:
+    case G_FILE_MONITOR_EVENT_DELETED:
+      path = g_file_get_path (file);
+      if (!g_str_has_suffix (path, THUMBNAILER_EXTENSION))
+        {
+          g_free (path);
+          return;
+        }
+
+      if (event_type == G_FILE_MONITOR_EVENT_DELETED)
+        remove_thumbnailer (factory, path);
+      else
+        update_or_create_thumbnailer (factory, path);
+
+      g_free (path);
+      break;
+    default:
+      break;
+    }
+}
+
+static void
+gnome_desktop_thumbnail_factory_load_thumbnailers (GnomeDesktopThumbnailFactory *factory)
+{
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+  const gchar * const *dirs;
+  guint i;
+
+  if (priv->loaded)
+    return;
+
+  dirs = get_thumbnailers_dirs ();
+  for (i = 0; dirs[i]; i++)
+    {
+      const gchar *path = dirs[i];
+      GDir *dir;
+      GFile *dir_file;
+      GFileMonitor *monitor;
+      const gchar *dirent;
+
+      dir = g_dir_open (path, 0, NULL);
+      if (!dir)
+        continue;
+
+      /* Monitor dir */
+      dir_file = g_file_new_for_path (path);
+      monitor = g_file_monitor_directory (dir_file,
+                                          G_FILE_MONITOR_NONE,
+                                          NULL, NULL);
+      if (monitor)
+        {
+          g_signal_connect (monitor, "changed",
+                            G_CALLBACK (thumbnailers_directory_changed),
+                            factory);
+          priv->monitors = g_list_prepend (priv->monitors, monitor);
+        }
+      g_object_unref (dir_file);
+
+      while ((dirent = g_dir_read_name (dir)))
+        {
+          Thumbnailer *thumb;
+          gchar       *filename;
+
+          if (!g_str_has_suffix (dirent, THUMBNAILER_EXTENSION))
+            continue;
+
+          filename = g_build_filename (path, dirent, NULL);
+          thumb = thumbnailer_new (filename);
+          g_free (filename);
+
+          if (thumb)
+            gnome_desktop_thumbnail_factory_add_thumbnailer (factory, thumb);
+        }
+
+      g_dir_close (dir);
+    }
+
+  priv->loaded = TRUE;
+}
+
+static void
+external_thumbnailers_disabled_all_changed_cb (GSettings                    *settings,
+                                               const gchar                  *key,
+                                               GnomeDesktopThumbnailFactory *factory)
 {
-  GnomeDesktopThumbnailFactory *factory = user_data;
   GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
 
   g_mutex_lock (priv->lock);
 
-  if (priv->reread_scheduled == 0)
+  priv->disabled = g_settings_get_boolean (priv->settings, "disable-all");
+  if (priv->disabled)
     {
-      priv->reread_scheduled = g_idle_add (reread_idle_callback,
-					   factory);
+      g_strfreev (priv->disabled_types);
+      priv->disabled_types = NULL;
     }
-  
+  else
+    {
+      priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
+      gnome_desktop_thumbnail_factory_load_thumbnailers (factory);
+    }
+
   g_mutex_unlock (priv->lock);
 }
 
+static void
+external_thumbnailers_disabled_changed_cb (GSettings                    *settings,
+                                           const gchar                  *key,
+                                           GnomeDesktopThumbnailFactory *factory)
+{
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+
+  g_mutex_lock (priv->lock);
+
+  if (priv->disabled)
+    return;
+  g_strfreev (priv->disabled_types);
+  priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
+
+  g_mutex_unlock (priv->lock);
+}
 
 static void
 gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory)
 {
-  GConfClient *client;
   GnomeDesktopThumbnailFactoryPrivate *priv;
   
   factory->priv = GNOME_DESKTOP_THUMBNAIL_FACTORY_GET_PRIVATE (factory);
@@ -433,22 +744,26 @@ gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory)
 
   priv->size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
   
-  priv->scripts_hash = NULL;
+  priv->mime_types_map = g_hash_table_new_full (g_str_hash,
+                                                g_str_equal,
+                                                (GDestroyNotify)g_free,
+                                                (GDestroyNotify)thumbnailer_unref);
   
   priv->lock = g_mutex_new ();
 
-  client = gconf_client_get_default ();
-  gconf_client_add_dir (client,
-			"/desktop/gnome/thumbnailers",
-			GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
-
-  gnome_desktop_thumbnail_factory_reread_scripts (factory);
-  
-  priv->thumbnailers_notify = gconf_client_notify_add (client, "/desktop/gnome/thumbnailers",
-						       schedule_reread, factory, NULL,
-						       NULL);
-
-  g_object_unref (G_OBJECT (client));
+  priv->settings = g_settings_new ("org.gnome.desktop.thumbnailers");
+  priv->disabled = g_settings_get_boolean (priv->settings, "disable-all");
+  if (!priv->disabled)
+    priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
+  g_signal_connect (priv->settings, "changed::disable-all",
+                    G_CALLBACK (external_thumbnailers_disabled_all_changed_cb),
+                    factory);
+  g_signal_connect (priv->settings, "changed::disable",
+                    G_CALLBACK (external_thumbnailers_disabled_changed_cb),
+                    factory);
+
+  if (!priv->disabled)
+    gnome_desktop_thumbnail_factory_load_thumbnailers (factory);
 }
 
 static void
@@ -675,7 +990,7 @@ gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *fac
 					       const char            *mime_type,
 					       time_t                 mtime)
 {
-  gboolean have_script;
+  gboolean have_script = FALSE;
 
   /* Don't thumbnail thumbnails */
   if (uri &&
@@ -687,8 +1002,13 @@ gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *fac
     return FALSE;
 
   g_mutex_lock (factory->priv->lock);
-  have_script = (factory->priv->scripts_hash != NULL &&
-                 g_hash_table_lookup (factory->priv->scripts_hash, mime_type));
+  if (!gnome_desktop_thumbnail_factory_is_disabled (factory, mime_type))
+    {
+      Thumbnailer *thumb;
+
+      thumb = g_hash_table_lookup (factory->priv->mime_types_map, mime_type);
+      have_script = thumbnailer_try_exec (thumb);
+    }
   g_mutex_unlock (factory->priv->lock);
 
   if (have_script || mimetype_supported_by_gdk_pixbuf (mime_type))
@@ -813,11 +1133,13 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
 
   script = NULL;
   g_mutex_lock (factory->priv->lock);
-  if (factory->priv->scripts_hash != NULL)
+  if (!gnome_desktop_thumbnail_factory_is_disabled (factory, mime_type))
     {
-      script = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
-      if (script)
-	script = g_strdup (script);
+      Thumbnailer *thumb;
+
+      thumb = g_hash_table_lookup (factory->priv->mime_types_map, mime_type);
+      if (thumb)
+        script = g_strdup (thumb->command);
     }
   g_mutex_unlock (factory->priv->lock);
   



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