diff --git a/libxfce4util/xfce-desktopentry.c b/libxfce4util/xfce-desktopentry.c index 3548d33..a4e8f31 100644 --- a/libxfce4util/xfce-desktopentry.c +++ b/libxfce4util/xfce-desktopentry.c @@ -46,94 +46,36 @@ -/* fallback for g_intern_static_string() with GLib < 2.9.0 */ -#if !GLIB_CHECK_VERSION(2,9,0) -#define g_intern_static_string(string) (g_quark_to_string (g_quark_from_static_string ((string)))) -#endif - - - #define XFCE_DESKTOP_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), XFCE_TYPE_DESKTOP_ENTRY, XfceDesktopEntryPrivate)) -typedef struct _XfceDesktopEntryItem XfceDesktopEntryItem; - - - static void xfce_desktop_entry_class_init (XfceDesktopEntryClass *klass); static void xfce_desktop_entry_init (XfceDesktopEntry *desktop_entry); static void xfce_desktop_entry_finalize (GObject *object); -static const XfceDesktopEntryItem *xfce_desktop_entry_lookup (XfceDesktopEntry *desktop_entry, - const gchar *key); -static gboolean xfce_desktop_entry_parse (XfceDesktopEntry *desktop_entry); struct _XfceDesktopEntryPrivate { - gchar *file; - gchar *locale; - gchar *data; - - XfceDesktopEntryItem *items; - gint num_items; -}; - -struct _XfceDesktopEntryItem -{ - gchar *key; - gchar *value; - gchar *section; - gchar *translated_value; + gchar *file; + GKeyFile *key_file; }; -static GObject *xfce_desktop_entry_parent_class; - - - -GType -xfce_desktop_entry_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (XfceDesktopEntryClass), - NULL, - NULL, - (GClassInitFunc) xfce_desktop_entry_class_init, - NULL, - NULL, - sizeof (XfceDesktopEntry), - 0, - (GInstanceInitFunc) xfce_desktop_entry_init, - NULL, - }; - - type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("XfceDesktopEntry"), &info, 0); - } - - return type; -} +G_DEFINE_TYPE (XfceDesktopEntry, xfce_desktop_entry, G_TYPE_OBJECT) static void -xfce_desktop_entry_class_init (XfceDesktopEntryClass * klass) +xfce_desktop_entry_class_init (XfceDesktopEntryClass *klass) { GObjectClass *gobject_class; /* install private data for the type */ g_type_class_add_private (klass, sizeof (XfceDesktopEntryPrivate)); - /* determine the parent type class */ - xfce_desktop_entry_parent_class = g_type_class_peek_parent (klass); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = xfce_desktop_entry_finalize; } @@ -152,214 +94,17 @@ static void xfce_desktop_entry_finalize (GObject *object) { XfceDesktopEntry *desktop_entry = XFCE_DESKTOP_ENTRY (object); - gint n; - /* release the items */ - for (n = 0; n < desktop_entry->priv->num_items; ++n) - { - g_free (desktop_entry->priv->items[n].translated_value); - g_free (desktop_entry->priv->items[n].section); - g_free (desktop_entry->priv->items[n].value); - g_free (desktop_entry->priv->items[n].key); - } + if (G_LIKELY (desktop_entry->priv->key_file != NULL)) + g_key_file_free (desktop_entry->priv->key_file); - g_free (desktop_entry->priv->items); g_free (desktop_entry->priv->file); - g_free (desktop_entry->priv->data); (*G_OBJECT_CLASS (xfce_desktop_entry_parent_class)->finalize) (object); } -static const XfceDesktopEntryItem* -xfce_desktop_entry_lookup (XfceDesktopEntry *desktop_entry, - const gchar *key) -{ - XfceDesktopEntryItem *item; - gint n; - - for (item = desktop_entry->priv->items, n = 0; n < desktop_entry->priv->num_items; ++item, ++n) - if (strcmp (item->key, key) == 0) - return item; - - return NULL; -} - - - -static gboolean -parse_desktop_entry_line (const gchar *line, - gchar **section_return, - gchar **key_return, - gchar **value_return, - gchar **locale_return) -{ - const gchar *p = line; - const gchar *q; - const gchar *r; - const gchar *s; - - /* initialize to NULL, so we don't have tho think about it anymore */ - *section_return = NULL; - *key_return = NULL; - *value_return = NULL; - *locale_return = NULL; - - /* skip whitespace */ - while (g_ascii_isspace (*p)) - ++p; - - if (*p == '#' || *p == '\n' || *p == '\0') - return FALSE; - - if (*p == '[') - { - ++p; - - q = strchr (p, ']'); - if (G_UNLIKELY (q == NULL)) - return FALSE; - - *section_return = g_strndup (p, q - p); - } - else - { - q = strchr (p, '='); - if (G_UNLIKELY (q == NULL)) - return FALSE; - - r = q + 1; - - for (--q; g_ascii_isspace (*q); ) - --q; - - if (*q == ']') - { - s = strchr (p, '['); - if (G_UNLIKELY (s == NULL)) - return FALSE; - - *key_return = g_strndup (p, s - p); - - ++s; - - *locale_return = g_strndup (s, q - s); - } - else - { - *key_return = g_strndup (p, (q + 1) - p); - } - - while (g_ascii_isspace (*r)) - ++r; - - q = r + strlen (r); - - while (q > r && (g_ascii_isspace (*(q - 1)) || ((*(q - 1)) == '\r'))) - --q; - - if (q > r) - *value_return = g_strndup (r, q - r); - else - *value_return = g_new0 (gchar, 1); - } - - return TRUE; -} - - - -static gboolean -xfce_desktop_entry_parse (XfceDesktopEntry *desktop_entry) -{ - XfceDesktopEntryItem *item; - const gchar *current_locale; - gboolean in_d_e_section = FALSE; - gboolean result = FALSE; - gchar *current_section = NULL; - gchar *section; - gchar *locale; - gchar *value; - gchar *key; - gchar **lines; - gchar **p; - gint locale_matched = 0; - gint i; - - current_locale = setlocale (LC_MESSAGES, NULL); - - lines = g_strsplit (desktop_entry->priv->data, "\n", -1); - for (p = lines; *p != NULL; ++p) - { - /* some .desktop files have multiple sections. we're only interested - * in the "[Desktop Entry]" section */ - if (!in_d_e_section) - { - if (!g_ascii_strncasecmp (*p, "[Desktop Entry]", 15)) - in_d_e_section = TRUE; - } - else if (**p == '[' && g_ascii_strncasecmp(*p, "[Desktop Entry]", 15)) - in_d_e_section = FALSE; - - if (!in_d_e_section) - continue; - - if (!parse_desktop_entry_line (*p, §ion, &key, &value, &locale)) - continue; - - if (G_UNLIKELY (section != NULL)) - { - g_free (current_section); - current_section = section; - continue; - } - - item = desktop_entry->priv->items; - - for (i = 0; i < desktop_entry->priv->num_items; ++i, ++item) - { - if (key != NULL && item->key != NULL && strcmp (key, item->key) == 0) - { - if (current_locale != NULL && locale != NULL) - { - gint match = xfce_locale_match (current_locale, locale); - if (match > locale_matched) - { - g_free (item->translated_value); - item->translated_value = g_strdup (value); - } - } - else - { - g_free (item->value); - item->value = g_strdup (value); - result = TRUE; - } - - if (current_section != NULL) - { - g_free (item->section); - item->section = g_strdup (current_section); - } - - break; - } - } - - g_free (value); - g_free (key); - g_free (locale); - } - - g_free (current_section); - g_strfreev (lines); - - return result; -} - - - /** * xfce_desktop_entry_new: * @file : full path to the desktop entry file to use. @@ -380,33 +125,25 @@ xfce_desktop_entry_new (const gchar *file, const gchar **categories, gint num_categories) { - XfceDesktopEntryItem *item; - XfceDesktopEntry *desktop_entry; - gint n; + XfceDesktopEntry *desktop_entry; + GError *error = NULL; + GKeyFile *key_file; g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (categories != NULL, NULL); - - desktop_entry = g_object_new (XFCE_TYPE_DESKTOP_ENTRY, NULL); - desktop_entry->priv->file = g_strdup (file); - desktop_entry->priv->items = g_new0 (XfceDesktopEntryItem, num_categories); - desktop_entry->priv->num_items = num_categories; - if (!g_file_get_contents (desktop_entry->priv->file, &(desktop_entry->priv->data), NULL, NULL)) + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, file, G_KEY_FILE_NONE, &error)) { - g_warning ("Could not get contents of file %s", desktop_entry->priv->file); - g_object_unref (G_OBJECT (desktop_entry)); + g_critical ("Could not create entry from file \"%s\": %s", file, error->message); + g_error_free (error); + g_key_file_free (key_file); + return NULL; } - for (item = desktop_entry->priv->items, n = 0; n < desktop_entry->priv->num_items; ++item, ++n) - item->key = g_strdup (categories[n]); - - if (!xfce_desktop_entry_parse (desktop_entry)) - { - g_object_unref (G_OBJECT (desktop_entry)); - desktop_entry = NULL; - } + desktop_entry = g_object_new (XFCE_TYPE_DESKTOP_ENTRY, NULL); + desktop_entry->priv->file = g_strdup (file); + desktop_entry->priv->key_file = key_file; return desktop_entry; } @@ -433,28 +170,25 @@ xfce_desktop_entry_new_from_data (const gchar *data, const gchar **categories, gint num_categories) { - XfceDesktopEntryItem *item; - XfceDesktopEntry *desktop_entry; - gint n; + XfceDesktopEntry *desktop_entry; + GError *error = NULL; + GKeyFile *key_file; g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (categories != NULL, NULL); - desktop_entry = g_object_new (XFCE_TYPE_DESKTOP_ENTRY, NULL); - desktop_entry->priv->file = g_strdup (""); /* or "data" or ... */ - desktop_entry->priv->data = g_strdup (data); - desktop_entry->priv->items = g_new0 (XfceDesktopEntryItem, num_categories); - desktop_entry->priv->num_items = num_categories; - - for (item = desktop_entry->priv->items, n = 0; n < desktop_entry->priv->num_items; ++item, ++n) - item->key = g_strdup (categories[n]); - - if (!xfce_desktop_entry_parse (desktop_entry)) + key_file = g_key_file_new (); + if (!g_key_file_load_from_data (key_file, data, -1, G_KEY_FILE_NONE, &error)) { - g_object_unref (G_OBJECT (desktop_entry)); - desktop_entry = NULL; + g_critical ("Could not create entry from data: %s", error->message); + g_error_free (error); + g_key_file_free (key_file); + + return NULL; } + desktop_entry = g_object_new (XFCE_TYPE_DESKTOP_ENTRY, NULL); + desktop_entry->priv->key_file = key_file; + return desktop_entry; } @@ -502,20 +236,31 @@ xfce_desktop_entry_get_string (XfceDesktopEntry *desktop_entry, gboolean translated, gchar **value_return) { - const XfceDesktopEntryItem *item; + gchar *value; + GKeyFile *key_file; + GError *error = NULL; g_return_val_if_fail (XFCE_IS_DESKTOP_ENTRY (desktop_entry), FALSE); - g_return_val_if_fail (value_return != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); - item = xfce_desktop_entry_lookup (desktop_entry, key); - if (G_UNLIKELY (item == NULL || item->value == NULL || *item->value == '\0')) - return FALSE; + key_file = desktop_entry->priv->key_file; - if (translated && item->translated_value != NULL) - *value_return = g_strdup (item->translated_value); + if (translated) + value = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, key, NULL, &error); else - *value_return = g_strdup (item->value); + value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, key, &error); + + if (G_UNLIKELY (error != NULL)) + { + if (G_UNLIKELY (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + g_warning ("The key \"%s\" was not found: %s", key, error->message); + + g_error_free (error); + return FALSE; + } + + if (G_LIKELY (value_return != NULL)) + *value_return = value; return TRUE; } @@ -540,22 +285,28 @@ xfce_desktop_entry_get_int (XfceDesktopEntry *desktop_entry, const gchar *key, gint *value_return) { - const XfceDesktopEntryItem *item; - gchar *endptr; + gint value; + GError *error = NULL; g_return_val_if_fail (XFCE_IS_DESKTOP_ENTRY (desktop_entry), FALSE); - g_return_val_if_fail (value_return != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); - item = xfce_desktop_entry_lookup (desktop_entry, key); - if (G_UNLIKELY (item == NULL || item->value == NULL || *item->value == '\0')) - return FALSE; + value = g_key_file_get_integer (desktop_entry->priv->key_file, + G_KEY_FILE_DESKTOP_GROUP, key, &error); + + if (G_UNLIKELY (error != NULL)) + { + if (G_UNLIKELY (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + g_warning ("The key \"%s\" was not found: %s", key, error->message); - *value_return = strtol (item->value, &endptr, 10); - if (*endptr == '\0') - return TRUE; + g_error_free (error); + return FALSE; + } - return FALSE; + if (G_LIKELY (value_return != NULL)) + *value_return = value; + + return TRUE; } @@ -576,26 +327,27 @@ gboolean xfce_desktop_entry_has_translated_entry (XfceDesktopEntry *desktop_entry, const gchar *key) { - const XfceDesktopEntryItem *item; - const gchar *current_locale; - + const gchar * const *locales; + guint i; + gchar *locale_key; + gboolean found = FALSE; + g_return_val_if_fail (XFCE_IS_DESKTOP_ENTRY (desktop_entry), FALSE); g_return_val_if_fail (key != NULL, FALSE); - - item = xfce_desktop_entry_lookup (desktop_entry, key); - if (G_UNLIKELY (item == NULL || item->value == NULL || *item->value == '\0')) - return FALSE; - - current_locale = setlocale (LC_MESSAGES, NULL); - - if (item->translated_value == NULL - && !xfce_locale_match (current_locale, "C") - && !xfce_locale_match (current_locale, "POSIX")) - { - return FALSE; - } - - return TRUE; + + locales = g_get_language_names (); + for (i = 0; !found && locales[i] != NULL; i++) + { + if (strcmp (locales[i], "C") == 0 || strcmp (locales[i], "POSIX") == 0) + continue; + + locale_key = g_strdup_printf ("%s[%s]", key, locales[i]); + found = g_key_file_has_key (desktop_entry->priv->key_file, + G_KEY_FILE_DESKTOP_GROUP, locale_key, NULL); + g_free (locale_key); + } + + return found; } diff --git a/libxfce4util/xfce-desktopentry.h b/libxfce4util/xfce-desktopentry.h index bddead8..b741484 100644 --- a/libxfce4util/xfce-desktopentry.h +++ b/libxfce4util/xfce-desktopentry.h @@ -30,6 +30,8 @@ G_BEGIN_DECLS +#ifndef XFCE_DISABLE_DEPRECATED + typedef struct _XfceDesktopEntryPrivate XfceDesktopEntryPrivate; typedef struct _XfceDesktopEntryClass XfceDesktopEntryClass; typedef struct _XfceDesktopEntry XfceDesktopEntry; @@ -81,6 +83,8 @@ gboolean xfce_desktop_entry_get_string (XfceDesktopEntr gboolean xfce_desktop_entry_has_translated_entry (XfceDesktopEntry *desktop_entry, const gchar *key); +#endif + G_END_DECLS #endif /* !__XFCE_DESKTOPENTRY_H__ */