GDesktopAppInfo: Add "filename" property for bindings
authorColin Walters <walters@verbum.org>
Tue, 26 Apr 2011 19:08:54 +0000 (15:08 -0400)
committerColin Walters <walters@verbum.org>
Tue, 26 Apr 2011 19:08:54 +0000 (15:08 -0400)
GDesktopAppInfo violates the GObject rule that your C constructors
should just be thin wrappers around g_object_new().  While GKeyFile
isn't introspctable, this patch allows from JavaScript:

var app = new Gio.DesktopAppInfo({ filename: '/path/to/foo.desktop' });

https://bugzilla.gnome.org/show_bug.cgi?id=648425

gio/gdesktopappinfo.c

index d9d17b2..1236d36 100644 (file)
 #define MIME_CACHE_GROUP            "MIME Cache"
 #define FULL_NAME_KEY               "X-GNOME-FullName"
 
+enum {
+  PROP_0,
+  PROP_FILENAME
+};
+
 static void     g_desktop_app_info_iface_init         (GAppInfoIface    *iface);
 static GList *  get_all_desktop_entries_for_mime_type (const char       *base_mime_type,
                                                       const char      **except,
@@ -177,11 +182,63 @@ g_desktop_app_info_finalize (GObject *object)
 }
 
 static void
+g_desktop_app_info_set_property(GObject         *object,
+                               guint            prop_id,
+                               const GValue    *value,
+                               GParamSpec      *pspec)
+{
+  GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object);
+
+  switch (prop_id)
+    {
+    case PROP_FILENAME:
+      self->filename = g_value_dup_string (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_desktop_app_info_get_property(GObject         *object,
+                               guint            prop_id,
+                               GValue          *value,
+                               GParamSpec      *pspec)
+{
+  GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object);
+
+  switch (prop_id)
+    {
+    case PROP_FILENAME:
+      g_value_set_string (value, self->filename);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
 g_desktop_app_info_class_init (GDesktopAppInfoClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   
+  gobject_class->get_property = g_desktop_app_info_get_property;
+  gobject_class->set_property = g_desktop_app_info_set_property;
   gobject_class->finalize = g_desktop_app_info_finalize;
+
+  /**
+   * GDesktopAppInfo:filename
+   *
+   * The origin filename of this #GDesktopAppInfo
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_FILENAME,
+                                   g_param_spec_string ("filename", "Filename", "",
+                                                       NULL,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -205,29 +262,19 @@ binary_from_exec (const char *exec)
   
 }
 
-/**
- * g_desktop_app_info_new_from_keyfile:
- * @key_file: an opened #GKeyFile
- * 
- * Creates a new #GDesktopAppInfo.
- *
- * Returns: a new #GDesktopAppInfo or %NULL on error.
- *
- * Since: 2.18
- **/
-GDesktopAppInfo *
-g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
+static gboolean
+g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, 
+                                     GKeyFile        *key_file)
 {
-  GDesktopAppInfo *info;
   char *start_group;
   char *type;
   char *try_exec;
-  
+
   start_group = g_key_file_get_start_group (key_file);
   if (start_group == NULL || strcmp (start_group, G_KEY_FILE_DESKTOP_GROUP) != 0)
     {
       g_free (start_group);
-      return NULL;
+      return FALSE;
     }
   g_free (start_group);
 
@@ -238,7 +285,7 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
   if (type == NULL || strcmp (type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0)
     {
       g_free (type);
-      return NULL;
+      return FALSE;
     }
   g_free (type);
 
@@ -253,14 +300,11 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
       if (t == NULL)
        {
          g_free (try_exec);
-         return NULL;
+         return FALSE;
        }
       g_free (t);
     }
 
-  info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL);
-  info->filename = NULL;
-
   info->name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL);
   info->fullname = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, FULL_NAME_KEY, NULL, NULL);
   info->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL);
@@ -311,6 +355,53 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
       info->path = NULL;
     }
 
+  return TRUE;
+}
+
+static gboolean
+g_desktop_app_info_load_file (GDesktopAppInfo *self)
+{
+  GKeyFile *key_file;
+  gboolean retval = FALSE;
+  
+  g_return_val_if_fail (self->filename != NULL, FALSE);
+
+  key_file = g_key_file_new ();
+  
+  if (g_key_file_load_from_file (key_file,
+                                self->filename,
+                                G_KEY_FILE_NONE,
+                                NULL))
+    {
+      retval = g_desktop_app_info_load_from_keyfile (self, key_file);
+    }
+
+  g_key_file_free (key_file);
+  return retval;
+}
+
+/**
+ * g_desktop_app_info_new_from_keyfile:
+ * @key_file: an opened #GKeyFile
+ * 
+ * Creates a new #GDesktopAppInfo.
+ *
+ * Returns: a new #GDesktopAppInfo or %NULL on error.
+ *
+ * Since: 2.18
+ **/
+GDesktopAppInfo *
+g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
+{
+  GDesktopAppInfo *info;
+
+  info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL);
+  info->filename = NULL;
+  if (!g_desktop_app_info_load_from_keyfile (info, key_file))
+    {
+      g_object_unref (info);
+      return NULL;
+    }
   return info;
 }
 
@@ -325,23 +416,14 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
 GDesktopAppInfo *
 g_desktop_app_info_new_from_filename (const char *filename)
 {
-  GKeyFile *key_file;
   GDesktopAppInfo *info = NULL;
 
-  key_file = g_key_file_new ();
-  
-  if (g_key_file_load_from_file (key_file,
-                                filename,
-                                G_KEY_FILE_NONE,
-                                NULL))
+  info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL);
+  if (!g_desktop_app_info_load_file (info))
     {
-      info = g_desktop_app_info_new_from_keyfile (key_file);
-      if (info)
-        info->filename = g_strdup (filename);
-    }  
-
-  g_key_file_free (key_file);
-
+      g_object_unref (info);
+      return NULL;
+    }
   return info;
 }