glib r7554 - in trunk/gio: . tests
- From: matthiasc svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r7554 - in trunk/gio: . tests
- Date: Fri, 26 Sep 2008 19:57:36 +0000 (UTC)
Author: matthiasc
Date: Fri Sep 26 19:57:36 2008
New Revision: 7554
URL: http://svn.gnome.org/viewvc/glib?rev=7554&view=rev
Log:
2008-09-26 Matthias Clasen <mclasen redhat com>
Bug 545350 â GAppInfo deletion
Bug 545351 â Reset associations for content type
* gio.symbols:
* gappinfo.[hc]: New functions g_app_info_can_delete,
g_app_info_delete and g_app_info_reset_type_associations.
* gdesktopappinfo.c:
* gwin32appinfo.c: Implementations of these.
* tests/Makefile.am:
* tests/desktop-app-info.c: Tests for GAppInfo functionality.
Added:
trunk/gio/tests/desktop-app-info.c
Modified:
trunk/gio/ChangeLog
trunk/gio/gappinfo.c
trunk/gio/gappinfo.h
trunk/gio/gdesktopappinfo.c
trunk/gio/gio.symbols
trunk/gio/gwin32appinfo.c
trunk/gio/tests/Makefile.am
Modified: trunk/gio/gappinfo.c
==============================================================================
--- trunk/gio/gappinfo.c (original)
+++ trunk/gio/gappinfo.c Fri Sep 26 19:57:36 2008
@@ -574,6 +574,62 @@
return res;
}
+/**
+ * g_app_info_can_delete:
+ * @appinfo: a #GAppInfo
+ *
+ * Obtains the information whether the GAppInfo can be deleted.
+ * See g_app_info_delete().
+ *
+ * Returns: %TRUE if @appinfo can be deleted
+ *
+ * Since: 2.20
+ */
+gboolean
+g_app_info_can_delete (GAppInfo *appinfo)
+{
+ GAppInfoIface *iface;
+
+ g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+ iface = G_APP_INFO_GET_IFACE (appinfo);
+
+ if (iface->can_delete)
+ return (* iface->can_delete) (appinfo);
+
+ return FALSE;
+}
+
+
+/**
+ * g_app_info_delete:
+ * @appinfo: a #GAppInfo
+ *
+ * Tries to delete an #GAppInfo.
+ *
+ * On some platforms, there may be a difference between user-defined
+ * #GAppInfo<!-- -->s which can be deleted, and system-wide ones which
+ * cannot. See g_app_info_can_delete().
+ *
+ * Returns: %TRUE if @appinfo has been deleted
+ *
+ * Since: 2.20
+ */
+gboolean
+g_app_info_delete (GAppInfo *appinfo)
+{
+ GAppInfoIface *iface;
+
+ g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+
+ iface = G_APP_INFO_GET_IFACE (appinfo);
+
+ if (iface->do_delete)
+ return (* iface->do_delete) (appinfo);
+
+ return FALSE;
+}
+
G_DEFINE_TYPE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT);
@@ -690,5 +746,6 @@
class->launch_failed (context, startup_notify_id);
}
+
#define __G_APP_INFO_C__
#include "gioaliasdef.c"
Modified: trunk/gio/gappinfo.h
==============================================================================
--- trunk/gio/gappinfo.h (original)
+++ trunk/gio/gappinfo.h Fri Sep 26 19:57:36 2008
@@ -75,6 +75,8 @@
* @add_supports_type: Adds to the #GAppInfo information about supported file types.
* @can_remove_supports_type: Checks for support for removing supported file types from a #GAppInfo.
* @remove_supports_type: Removes a supported application type from a #GAppInfo.
+ * @can_delete: Checks if a #GAppInfo can be deleted. Since 2.20
+ * @do_delete: Deletes a #GAppInfo. Since 2.20
*
* Application Information interface, for operating system portability.
*/
@@ -120,6 +122,8 @@
gboolean (* remove_supports_type) (GAppInfo *appinfo,
const char *content_type,
GError **error);
+ gboolean (* can_delete) (GAppInfo *appinfo);
+ gboolean (* do_delete) (GAppInfo *appinfo);
};
GType g_app_info_get_type (void) G_GNUC_CONST;
@@ -160,9 +164,12 @@
gboolean g_app_info_remove_supports_type (GAppInfo *appinfo,
const char *content_type,
GError **error);
+gboolean g_app_info_can_delete (GAppInfo *appinfo);
+gboolean g_app_info_delete (GAppInfo *appinfo);
GList * g_app_info_get_all (void);
GList * g_app_info_get_all_for_type (const char *content_type);
+void g_app_info_reset_type_associations (const char *content_type);
GAppInfo *g_app_info_get_default_for_type (const char *content_type,
gboolean must_support_uris);
GAppInfo *g_app_info_get_default_for_uri_scheme (const char *uri_scheme);
Modified: trunk/gio/gdesktopappinfo.c
==============================================================================
--- trunk/gio/gdesktopappinfo.c (original)
+++ trunk/gio/gdesktopappinfo.c Fri Sep 26 19:57:36 2008
@@ -1171,7 +1171,8 @@
char **list;
gsize length, data_size;
char *data;
- int i, j;
+ int i, j, k;
+ char **content_types;
/* Don't add both at start and end */
g_assert (!(add_at_start && add_at_end));
@@ -1191,75 +1192,109 @@
key_file = g_key_file_new ();
}
- /* Add to the right place in the list */
+ if (content_type)
+ {
+ content_types = g_new (char *, 2);
+ content_types[0] = g_strdup (content_type);
+ content_types[1] = NULL;
+ }
+ else
+ {
+ content_types = g_key_file_get_keys (key_file, ADDED_ASSOCIATIONS_GROUP, NULL, NULL);
+ }
+
+ for (k = 0; content_types && content_types[k]; k++)
+ {
+ /* Add to the right place in the list */
- length = 0;
- old_list = g_key_file_get_string_list (key_file, ADDED_ASSOCIATIONS_GROUP,
- content_type, &length, NULL);
+ length = 0;
+ old_list = g_key_file_get_string_list (key_file, ADDED_ASSOCIATIONS_GROUP,
+ content_types[k], &length, NULL);
- list = g_new (char *, 1 + length + 1);
+ list = g_new (char *, 1 + length + 1);
- i = 0;
- if (add_at_start)
- list[i++] = g_strdup (desktop_id);
- if (old_list)
- {
- for (j = 0; old_list[j] != NULL; j++)
- {
- if (strcmp (old_list[j], desktop_id) != 0)
- list[i++] = g_strdup (old_list[j]);
- }
+ i = 0;
+ if (add_at_start)
+ list[i++] = g_strdup (desktop_id);
+ if (old_list)
+ {
+ for (j = 0; old_list[j] != NULL; j++)
+ {
+ if (g_strcmp0 (old_list[j], desktop_id) != 0)
+ list[i++] = g_strdup (old_list[j]);
+ }
+ }
+ if (add_at_end)
+ list[i++] = g_strdup (desktop_id);
+ list[i] = NULL;
+
+ g_strfreev (old_list);
+
+ if (list[0] == NULL || desktop_id == NULL)
+ g_key_file_remove_key (key_file,
+ ADDED_ASSOCIATIONS_GROUP,
+ content_types[k],
+ NULL);
+ else
+ g_key_file_set_string_list (key_file,
+ ADDED_ASSOCIATIONS_GROUP,
+ content_types[k],
+ (const char * const *)list, i);
+
+ g_strfreev (list);
}
- if (add_at_end)
- list[i++] = g_strdup (desktop_id);
- list[i] = NULL;
- g_strfreev (old_list);
+ if (content_type)
+ {
+ /* reuse the list from above */
+ }
+ else
+ {
+ g_strfreev (content_types);
+ content_types = g_key_file_get_keys (key_file, REMOVED_ASSOCIATIONS_GROUP, NULL, NULL);
+ }
- g_key_file_set_string_list (key_file,
- ADDED_ASSOCIATIONS_GROUP,
- content_type,
- (const char * const *)list, i);
+ for (k = 0; content_types && content_types[k]; k++)
+ {
+ /* Remove from removed associations group (unless remove) */
+
+ length = 0;
+ old_list = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP,
+ content_types[k], &length, NULL);
- g_strfreev (list);
+ list = g_new (char *, 1 + length + 1);
- /* Remove from removed associations group (unless remove) */
+ i = 0;
+ if (remove)
+ list[i++] = g_strdup (desktop_id);
+ if (old_list)
+ {
+ for (j = 0; old_list[j] != NULL; j++)
+ {
+ if (g_strcmp0 (old_list[j], desktop_id) != 0)
+ list[i++] = g_strdup (old_list[j]);
+ }
+ }
+ list[i] = NULL;
- length = 0;
- old_list = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP,
- content_type, &length, NULL);
+ g_strfreev (old_list);
- list = g_new (char *, 1 + length + 1);
+ if (list[0] == NULL || desktop_id == NULL)
+ g_key_file_remove_key (key_file,
+ REMOVED_ASSOCIATIONS_GROUP,
+ content_types[k],
+ NULL);
+ else
+ g_key_file_set_string_list (key_file,
+ REMOVED_ASSOCIATIONS_GROUP,
+ content_types[k],
+ (const char * const *)list, i);
- i = 0;
- if (remove)
- list[i++] = g_strdup (desktop_id);
- if (old_list)
- {
- for (j = 0; old_list[j] != NULL; j++)
- {
- if (strcmp (old_list[j], desktop_id) != 0)
- list[i++] = g_strdup (old_list[j]);
- }
+ g_strfreev (list);
}
- list[i] = NULL;
- g_strfreev (old_list);
-
- if (list[0] == NULL)
- g_key_file_remove_key (key_file,
- REMOVED_ASSOCIATIONS_GROUP,
- content_type,
- NULL);
- else
- g_key_file_set_string_list (key_file,
- REMOVED_ASSOCIATIONS_GROUP,
- content_type,
- (const char * const *)list, i);
+ g_strfreev (content_types);
- g_strfreev (list);
-
-
data = g_key_file_to_data (key_file, &data_size, error);
g_key_file_free (key_file);
@@ -1513,6 +1548,40 @@
return TRUE;
}
+static gboolean
+g_desktop_app_info_can_delete (GAppInfo *appinfo)
+{
+ GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo);
+
+ if (info->filename)
+ return g_access (info->filename, W_OK) == 0;
+
+ return FALSE;
+}
+
+static gboolean
+g_desktop_app_info_delete (GAppInfo *appinfo)
+{
+ GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo);
+
+ if (info->filename)
+ {
+ if (g_remove (info->filename) == 0)
+ {
+ update_mimeapps_list (info->desktop_id, NULL, FALSE, FALSE, FALSE, NULL);
+
+ g_free (info->filename);
+ info->filename = NULL;
+ g_free (info->desktop_id);
+ info->desktop_id = NULL;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/**
* g_app_info_create_from_commandline:
* @commandline: the commandline to use
@@ -1586,6 +1655,8 @@
iface->add_supports_type = g_desktop_app_info_add_supports_type;
iface->can_remove_supports_type = g_desktop_app_info_can_remove_supports_type;
iface->remove_supports_type = g_desktop_app_info_remove_supports_type;
+ iface->can_delete = g_desktop_app_info_can_delete;
+ iface->do_delete = g_desktop_app_info_delete;
}
static gboolean
@@ -1643,6 +1714,22 @@
return g_list_reverse (infos);
}
+/**
+ * g_app_info_reset_type_associations:
+ * content_type: a content type
+ *
+ * Removes all changes to the type associations done by
+ * g_app_info_set_as_default_for_type(),
+ * g_app_info_set_as_default_for_extension(),
+ * g_app_info_add_supports_type() of g_app_info_remove_supports_type().
+ *
+ * Since: 2.20
+ */
+void
+g_app_info_reset_type_associations (const char *content_type)
+{
+ update_mimeapps_list (NULL, content_type, FALSE, FALSE, FALSE, NULL);
+}
/**
* g_app_info_get_default_for_type:
Modified: trunk/gio/gio.symbols
==============================================================================
--- trunk/gio/gio.symbols (original)
+++ trunk/gio/gio.symbols Fri Sep 26 19:57:36 2008
@@ -48,6 +48,8 @@
g_app_info_can_remove_supports_type
g_app_info_remove_supports_type
g_app_info_launch_default_for_uri
+g_app_info_can_delete
+g_app_info_delete
g_app_launch_context_new
g_app_launch_context_get_display
g_app_launch_context_get_startup_notify_id
@@ -60,6 +62,7 @@
g_app_info_get_all_for_type
g_app_info_get_default_for_type
g_app_info_get_default_for_uri_scheme
+g_app_info_reset_type_associations
#endif
#endif
Modified: trunk/gio/gwin32appinfo.c
==============================================================================
--- trunk/gio/gwin32appinfo.c (original)
+++ trunk/gio/gwin32appinfo.c Fri Sep 26 19:57:36 2008
@@ -661,3 +661,9 @@
return g_list_reverse (infos);
}
+
+void
+g_app_info_reset_type_associations (const char *content_type)
+{
+ /* nothing to do */
+}
Modified: trunk/gio/tests/Makefile.am
==============================================================================
--- trunk/gio/tests/Makefile.am (original)
+++ trunk/gio/tests/Makefile.am Fri Sep 26 19:57:36 2008
@@ -22,7 +22,8 @@
g-file \
g-file-info \
data-input-stream \
- data-output-stream
+ data-output-stream \
+ desktop-app-info
if OS_UNIX
TEST_PROGS += live-g-file unix-streams
@@ -49,7 +50,9 @@
live_g_file_SOURCES = live-g-file.c
live_g_file_LDADD = $(progs_ldadd)
+desktop_app_info_SOURCES = desktop-app-info.c
+desktop_app_info_LDADD = $(progs_ldadd)
+
unix_streams_SOURCES = unix-streams.c
unix_streams_LDADD = $(progs_ldadd) \
$(top_builddir)/gthread/libgthread-2.0.la
-
Added: trunk/gio/tests/desktop-app-info.c
==============================================================================
--- (empty file)
+++ trunk/gio/tests/desktop-app-info.c Fri Sep 26 19:57:36 2008
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Matthias Clasen
+ */
+
+#include <glib/glib.h>
+#include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *basedir;
+
+static GAppInfo *
+create_app_info (const char *name)
+{
+ GError *error;
+ GAppInfo *info;
+
+ error = NULL;
+ info = g_app_info_create_from_commandline ("/usr/bin/true blah",
+ name,
+ G_APP_INFO_CREATE_NONE,
+ &error);
+ g_assert (error == NULL);
+
+ /* this is necessary to ensure that the info is saved */
+ g_app_info_set_as_default_for_type (info, "application/x-blah", &error);
+ g_assert (error == NULL);
+ g_app_info_remove_supports_type (info, "application/x-blah", &error);
+ g_assert (error == NULL);
+ g_app_info_reset_type_associations ("application/x-blah");
+
+ return info;
+}
+
+static void
+test_delete (void)
+{
+ GAppInfo *info;
+
+ const char *id;
+ char *filename;
+ gboolean res;
+
+ info = create_app_info ("Blah");
+
+ id = g_app_info_get_id (info);
+ g_assert (id != NULL);
+
+ filename = g_build_filename (basedir, "applications", id, NULL);
+
+ res = g_file_test (filename, G_FILE_TEST_EXISTS);
+ g_assert (res);
+
+ res = g_app_info_can_delete (info);
+ g_assert (res);
+
+ res = g_app_info_delete (info);
+ g_assert (res);
+
+ res = g_file_test (filename, G_FILE_TEST_EXISTS);
+ g_assert (!res);
+
+ g_object_unref (info);
+
+ if (g_file_test ("/usr/share/applications/gedit.desktop", G_FILE_TEST_EXISTS))
+ {
+ info = (GAppInfo*)g_desktop_app_info_new ("gedit.desktop");
+ g_assert (info);
+
+ res = g_app_info_can_delete (info);
+ g_assert (!res);
+
+ res = g_app_info_delete (info);
+ g_assert (!res);
+ }
+}
+
+static void
+test_default (void)
+{
+ GAppInfo *info, *info1, *info2, *info3;
+ GList *list;
+ GError *error = NULL;
+
+ info1 = create_app_info ("Blah1");
+ info2 = create_app_info ("Blah2");
+ info3 = create_app_info ("Blah3");
+
+ g_app_info_set_as_default_for_type (info1, "application/x-test", &error);
+ g_assert (error == NULL);
+
+ g_app_info_set_as_default_for_type (info2, "application/x-test", &error);
+ g_assert (error == NULL);
+
+ list = g_app_info_get_all_for_type ("application/x-test");
+ g_assert (g_list_length (list) == 2);
+
+ /* check that both are in the list, info2 before info1 */
+ info = (GAppInfo *)list->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
+
+ info = (GAppInfo *)list->next->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info1)) == 0);
+
+ g_list_foreach (list, (GFunc)g_object_unref, NULL);
+ g_list_free (list);
+
+ /* now try adding something at the end */
+ g_app_info_add_supports_type (info3, "application/x-test", &error);
+ g_assert (error == NULL);
+
+ list = g_app_info_get_all_for_type ("application/x-test");
+ g_assert (g_list_length (list) == 3);
+
+ /* check that all are in the list, info2, info1, info3 */
+ info = (GAppInfo *)list->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
+
+ info = (GAppInfo *)list->next->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info1)) == 0);
+
+ info = (GAppInfo *)list->next->next->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info3)) == 0);
+
+ g_list_foreach (list, (GFunc)g_object_unref, NULL);
+ g_list_free (list);
+
+ /* now remove info1 again */
+ g_app_info_remove_supports_type (info1, "application/x-test", &error);
+ g_assert (error == NULL);
+
+ list = g_app_info_get_all_for_type ("application/x-test");
+ g_assert (g_list_length (list) == 2);
+
+ /* check that both are in the list, info2 before info3 */
+ info = (GAppInfo *)list->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info2)) == 0);
+
+ info = (GAppInfo *)list->next->data;
+ g_assert (g_strcmp0 (g_app_info_get_id (info), g_app_info_get_id (info3)) == 0);
+
+ g_list_foreach (list, (GFunc)g_object_unref, NULL);
+ g_list_free (list);
+
+ /* now clean it all up */
+ g_app_info_reset_type_associations ("application/x-test");
+
+ list = g_app_info_get_all_for_type ("application/x-test");
+ g_assert (list == NULL);
+
+ g_app_info_delete (info1);
+ g_app_info_delete (info2);
+ g_app_info_delete (info3);
+
+ g_object_unref (info1);
+ g_object_unref (info2);
+}
+
+static void
+cleanup_dir_recurse (GFile *parent, GFile *root)
+{
+ gboolean res;
+ GError *error;
+ GFileEnumerator *enumerator;
+ GFileInfo *info;
+ GFile *descend;
+ char *relative_path;
+
+ g_assert (root != NULL);
+
+ error = NULL;
+ enumerator =
+ g_file_enumerate_children (parent, "*",
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL,
+ &error);
+ if (! enumerator)
+ return;
+ error = NULL;
+ info = g_file_enumerator_next_file (enumerator, NULL, &error);
+ while ((info) && (!error))
+ {
+ descend = g_file_get_child (parent, g_file_info_get_name (info));
+ g_assert (descend != NULL);
+ relative_path = g_file_get_relative_path (root, descend);
+ g_assert (relative_path != NULL);
+
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+ cleanup_dir_recurse (descend, root);
+
+ error = NULL;
+ res = g_file_delete (descend, NULL, &error);
+ g_assert_cmpint (res, ==, TRUE);
+
+ g_object_unref (descend);
+ error = NULL;
+ info = g_file_enumerator_next_file (enumerator, NULL, &error);
+ }
+ g_assert (error == NULL);
+
+ error = NULL;
+ res = g_file_enumerator_close (enumerator, NULL, &error);
+ g_assert_cmpint (res, ==, TRUE);
+ g_assert (error == NULL);
+}
+
+static void
+cleanup_subdirs (const char *basedir)
+{
+ GFile *base, *file;
+
+ base = g_file_new_for_path (basedir);
+ file = g_file_get_child (base, "applications");
+ cleanup_dir_recurse (file, file);
+ g_object_unref (file);
+ file = g_file_get_child (base, "mime");
+ cleanup_dir_recurse (file, file);
+ g_object_unref (file);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ basedir = g_get_current_dir ();
+ g_setenv ("XDG_DATA_HOME", basedir, TRUE);
+ cleanup_subdirs (basedir);
+
+ g_test_add_func ("/desktop-app-info/delete", test_delete);
+ g_test_add_func ("/desktop-app-info/default", test_default);
+
+ return g_test_run();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]