From 2a3f7f49b46abdaf2d82e704a3ee044ed57fb61f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Apr 2011 15:08:54 -0400 Subject: [PATCH] GDesktopAppInfo: Add "filename" property for bindings 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 | 150 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 34 deletions(-) diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index d9d17b2..1236d36 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -66,6 +66,11 @@ #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; } -- 2.7.4