From: Alexander Larsson Date: Tue, 29 Jan 2008 12:18:48 +0000 (+0000) Subject: Add g_file_query_default_handler utility to easily look up the GAppInfo X-Git-Tag: GLIB_2_15_5~88 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=431fef861755439c2c060a81a35805cdd023c3df;p=platform%2Fupstream%2Fglib.git Add g_file_query_default_handler utility to easily look up the GAppInfo 2008-01-29 Alexander Larsson * gfile.[ch]: Add g_file_query_default_handler utility to easily look up the GAppInfo that handles a file. * gdesktopappinfo.[ch]: * giomodule.c: Set up an extension point for g_app_info_get_default_for_uri_scheme() * gvfs.c: Remove unused function svn path=/trunk/; revision=6409 --- diff --git a/gio/ChangeLog b/gio/ChangeLog index c8143b7..6656947 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,5 +1,18 @@ 2008-01-29 Alexander Larsson + * gfile.[ch]: + Add g_file_query_default_handler utility to easily look up + the GAppInfo that handles a file. + + * gdesktopappinfo.[ch]: + * giomodule.c: + Set up an extension point for g_app_info_get_default_for_uri_scheme() + + * gvfs.c: + Remove unused function + +2008-01-29 Alexander Larsson + * gfileenumerator.c: Mention need to free returned value in g_file_enumerator_next_files_finish docs. diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 72ff00e..9f1c242 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -1607,7 +1607,6 @@ g_app_info_get_default_for_type (const char *content_type, return info; } - /** * g_app_info_get_default_for_uri_scheme: * @uri_scheme: a string containing a URI scheme. @@ -1622,10 +1621,54 @@ g_app_info_get_default_for_type (const char *content_type, GAppInfo * g_app_info_get_default_for_uri_scheme (const char *uri_scheme) { - /* TODO: Implement this using giomodules, reading the gconf settings - * in /desktop/gnome/url-handlers - */ - return NULL; + static gsize lookup = 0; + + if (g_once_init_enter (&lookup)) + { + gsize setup_value = 1; + GDesktopAppInfoLookup *lookup_instance; + const char *use_this; + GIOExtensionPoint *ep; + GIOExtension *extension; + GList *l; + + use_this = g_getenv ("GIO_USE_URI_ASSOCIATION"); + + /* Ensure vfs in modules loaded */ + _g_io_modules_ensure_loaded (); + + ep = g_io_extension_point_lookup (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME); + + lookup_instance = NULL; + if (use_this) + { + extension = g_io_extension_point_get_extension_by_name (ep, use_this); + if (extension) + lookup_instance = g_object_new (g_io_extension_get_type (extension), NULL); + } + + if (lookup_instance == NULL) + { + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + lookup_instance = g_object_new (g_io_extension_get_type (extension), NULL); + if (lookup_instance != NULL) + break; + } + } + + if (lookup_instance != NULL) + setup_value = (gsize)lookup_instance; + + g_once_init_leave (&lookup, setup_value); + } + + if (lookup == 1) + return NULL; + + return g_desktop_app_info_lookup_get_default_for_uri_scheme (G_DESKTOP_APP_INFO_LOOKUP (lookup), + uri_scheme); } @@ -2284,5 +2327,65 @@ get_all_desktop_entries_for_mime_type (const char *base_mime_type) return desktop_entries; } +/* GDesktopAppInfoLookup interface: */ + +static void g_desktop_app_info_lookup_base_init (gpointer g_class); +static void g_desktop_app_info_lookup_class_init (gpointer g_class, + gpointer class_data); + +GType +g_desktop_app_info_lookup_get_type (void) +{ + static GType desktop_app_info_lookup_type = 0; + + if (! desktop_app_info_lookup_type) + { + static const GTypeInfo desktop_app_info_lookup_info = + { + sizeof (GDesktopAppInfoLookupIface), /* class_size */ + g_desktop_app_info_lookup_base_init, /* base_init */ + NULL, /* base_finalize */ + g_desktop_app_info_lookup_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + desktop_app_info_lookup_type = + g_type_register_static (G_TYPE_INTERFACE, I_("GDesktopAppInfoLookup"), + &desktop_app_info_lookup_info, 0); + + g_type_interface_add_prerequisite (desktop_app_info_lookup_type, G_TYPE_OBJECT); + } + + return desktop_app_info_lookup_type; +} + +static void +g_desktop_app_info_lookup_class_init (gpointer g_class, + gpointer class_data) +{ +} + +static void +g_desktop_app_info_lookup_base_init (gpointer g_class) +{ +} + +GAppInfo * +g_desktop_app_info_lookup_get_default_for_uri_scheme (GDesktopAppInfoLookup *lookup, + const char *uri_scheme) +{ + GDesktopAppInfoLookupIface *iface; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO_LOOKUP (lookup), FALSE); + + iface = G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE (lookup); + + return (* iface->get_default_for_uri_scheme) (lookup, uri_scheme); +} + #define __G_DESKTOP_APP_INFO_C__ #include "gioaliasdef.c" diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h index e7fed43..d7a38e0 100644 --- a/gio/gdesktopappinfo.h +++ b/gio/gdesktopappinfo.h @@ -24,6 +24,7 @@ #define __G_DESKTOP_APP_INFO_H__ #include +#include "giomodule-priv.h" G_BEGIN_DECLS @@ -42,6 +43,7 @@ struct _GDesktopAppInfoClass GObjectClass parent_class; }; + GType g_desktop_app_info_get_type (void) G_GNUC_CONST; GDesktopAppInfo *g_desktop_app_info_new_from_filename (const char *filename); @@ -50,6 +52,29 @@ gboolean g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info); void g_desktop_app_info_set_desktop_env (const char *desktop_env); + +#define G_TYPE_DESKTOP_APP_INFO_LOOKUP (g_desktop_app_info_lookup_get_type ()) +#define G_DESKTOP_APP_INFO_LOOKUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP, GDesktopAppInfoLookup)) +#define G_IS_DESKTOP_APP_INFO_LOOKUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP)) +#define G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_DESKTOP_APP_INFO_LOOKUP, GDesktopAppInfoLookupIface)) + +#define G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME "gio-desktop-app-info-lookup" + +typedef struct _GDesktopAppInfoLookup GDesktopAppInfoLookup; +typedef struct _GDesktopAppInfoLookupIface GDesktopAppInfoLookupIface; + +struct _GDesktopAppInfoLookupIface +{ + GTypeInterface g_iface; + + GAppInfo * (*get_default_for_uri_scheme) (GDesktopAppInfoLookup *lookup, + const char *uri_scheme); +}; + +GType g_desktop_app_info_lookup_get_type (void) G_GNUC_CONST; +GAppInfo * g_desktop_app_info_lookup_get_default_for_uri_scheme (GDesktopAppInfoLookup *lookup, + const char *uri_scheme); + G_END_DECLS diff --git a/gio/gfile.c b/gio/gfile.c index 4eedbbb..0dec35a 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -4572,6 +4572,57 @@ g_file_mount_enclosing_volume_finish (GFile *location, * Utility functions * ********************************************/ +GAppInfo * +g_file_query_default_handler (GFile *file, + GCancellable *cancellable, + GError **error) +{ + char *uri_scheme; + const char *content_type; + GAppInfo *appinfo; + GFileInfo *info; + char *path; + + uri_scheme = g_file_get_uri_scheme (file); + appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme); + g_free (uri_scheme); + + if (appinfo != NULL) + return appinfo; + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, + cancellable, + error); + if (info == NULL) + return NULL; + + appinfo = NULL; + + content_type = g_file_info_get_content_type (info); + if (content_type) + { + /* Don't use is_native(), as we want to support fuse paths if availible */ + path = g_file_get_path (file); + appinfo = g_app_info_get_default_for_type (content_type, + path == NULL); + g_free (path); + } + + g_object_unref (info); + + if (appinfo != NULL) + return appinfo; + + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("No application is registered as handling this file")); + return NULL; + +} + + #define GET_CONTENT_BLOCK_SIZE 8192 /** diff --git a/gio/gfile.h b/gio/gfile.h index 196d040..0072224 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -33,6 +33,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -838,6 +839,9 @@ GFileMonitor* g_file_monitor_file (GFile /* Utilities */ +GAppInfo *g_file_query_default_handler (GFile *file, + GCancellable *cancellable, + GError **error); gboolean g_file_load_contents (GFile *file, GCancellable *cancellable, char **contents, diff --git a/gio/giomodule.c b/gio/giomodule.c index cee23d6..9ec12ff 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -30,7 +30,9 @@ #include "glocaldirectorymonitor.h" #include "gnativevolumemonitor.h" #include "gvfs.h" - +#ifdef G_OS_UNIX +#include "gdesktopappinfo.h" +#endif #include "gioalias.h" /** @@ -257,6 +259,11 @@ _g_io_modules_ensure_loaded (void) { loaded_dirs = TRUE; +#ifdef G_OS_UNIX + ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP); +#endif + ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME); g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR); diff --git a/gio/gvfs.c b/gio/gvfs.c index 67f0d38..7488c31 100644 --- a/gio/gvfs.c +++ b/gio/gvfs.c @@ -167,46 +167,6 @@ g_vfs_parse_name (GVfs *vfs, return (* class->parse_name) (vfs, parse_name); } -/* Note: This compares in reverse order. - Higher prio -> sort first - */ -static gint -compare_vfs_type (gconstpointer a, - gconstpointer b, - gpointer user_data) -{ - GType a_type, b_type; - char *a_name, *b_name; - int a_prio, b_prio; - gint res; - const char *use_this_monitor; - GQuark private_q, name_q; - - private_q = g_quark_from_static_string ("gio-prio"); - name_q = g_quark_from_static_string ("gio-name"); - - use_this_monitor = user_data; - a_type = *(GType *)a; - b_type = *(GType *)b; - a_prio = GPOINTER_TO_INT (g_type_get_qdata (a_type, private_q)); - a_name = g_type_get_qdata (a_type, name_q); - b_prio = GPOINTER_TO_INT (g_type_get_qdata (b_type, private_q)); - b_name = g_type_get_qdata (b_type, name_q); - - if (a_type == b_type) - res = 0; - else if (use_this_monitor != NULL && - strcmp (a_name, use_this_monitor) == 0) - res = -1; - else if (use_this_monitor != NULL && - strcmp (b_name, use_this_monitor) == 0) - res = 1; - else - res = b_prio - a_prio; - - return res; -} - static gpointer get_default_vfs (gpointer arg) {