Support tel:, callto: and refactor MIME supporting (including Hildon)

This commit is contained in:
Christian Dywan 2009-11-24 23:54:29 +01:00
parent ea7c5f9de4
commit d02d1db97f
4 changed files with 176 additions and 46 deletions

View file

@ -3433,36 +3433,20 @@ _action_source_view_activate (GtkAction* action,
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri); webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri);
gtk_widget_show (source); gtk_widget_show (source);
midori_browser_add_tab (browser, source); midori_browser_add_tab (browser, source);
g_free (text_editor);
return; return;
#else #else
GFile* file = g_file_new_for_uri (uri); GError* error = NULL;
gchar* content_type;
GAppInfo* app_info;
GList* files;
gpointer context;
#if GLIB_CHECK_VERSION (2, 18, 0) /* FIXME: Handling http transparently in the function would be nice */
content_type = g_content_type_from_mime_type ("text/plain"); if (g_str_has_prefix (uri, "file://"))
#else
content_type = g_strdup ("text/plain");
#endif
app_info = g_app_info_get_default_for_type (content_type,
!g_str_has_prefix (uri, "file://"));
g_free (content_type);
files = g_list_prepend (NULL, file);
#if GTK_CHECK_VERSION (2, 14, 0)
context = gdk_app_launch_context_new ();
gdk_app_launch_context_set_screen (context, gtk_widget_get_screen (view));
gdk_app_launch_context_set_timestamp (context, gtk_get_current_event_time ());
#else
context = g_app_launch_context_new ();
#endif
if (g_app_info_launch (app_info, files, context, NULL))
{ {
g_object_unref (app_info); if (!sokoke_show_uri_with_mime_type (gtk_widget_get_screen (view),
g_list_free (files); uri, "text/plain", gtk_get_current_event_time (), &error))
g_object_unref (file); sokoke_error_dialog (_("Could not run external program."),
error ? error->message : "");
if (error)
g_error_free (error);
g_free (text_editor); g_free (text_editor);
return; return;
} }

View file

@ -706,12 +706,14 @@ midori_view_web_view_navigation_decision_cb (WebKitWebView* web_view
MidoriView* view) MidoriView* view)
{ {
const gchar* uri = webkit_network_request_get_uri (request); const gchar* uri = webkit_network_request_get_uri (request);
if (g_str_has_prefix (uri, "mailto:")) if (g_str_has_prefix (uri, "mailto:") || g_str_has_prefix (uri, "tel:"))
{ {
webkit_web_policy_decision_ignore (decision); if (sokoke_show_uri (gtk_widget_get_screen (GTK_WIDGET (web_view)),
sokoke_show_uri (gtk_widget_get_screen (GTK_WIDGET (web_view)), uri, GDK_CURRENT_TIME, NULL))
uri, GDK_CURRENT_TIME, NULL); {
return TRUE; webkit_web_policy_decision_ignore (decision);
return TRUE;
}
} }
/* TODO: Handle more external protocols */ /* TODO: Handle more external protocols */
return FALSE; return FALSE;
@ -3001,7 +3003,9 @@ midori_view_set_uri (MidoriView* view,
{ {
midori_view_execute_script (view, &uri[11], NULL); midori_view_execute_script (view, &uri[11], NULL);
} }
else if (g_str_has_prefix (uri, "mailto:")) else if (g_str_has_prefix (uri, "mailto:")
|| g_str_has_prefix (uri, "tel:")
|| g_str_has_prefix (uri, "callto:"))
{ {
sokoke_show_uri (NULL, uri, GDK_CURRENT_TIME, NULL); sokoke_show_uri (NULL, uri, GDK_CURRENT_TIME, NULL);
} }

View file

@ -44,6 +44,12 @@
#include <hildon/hildon-file-chooser-dialog.h> #include <hildon/hildon-file-chooser-dialog.h>
#endif #endif
#if HAVE_HILDON
#include <libosso.h>
#include <hildon-mime.h>
#include <hildon-uri.h>
#endif
static gchar* static gchar*
sokoke_js_string_utf8 (JSStringRef js_string) sokoke_js_string_utf8 (JSStringRef js_string)
{ {
@ -90,9 +96,9 @@ sokoke_js_script_eval (JSContextRef js_context,
return value; return value;
} }
static void void
error_dialog (const gchar* short_message, sokoke_error_dialog (const gchar* short_message,
const gchar* detailed_message) const gchar* detailed_message)
{ {
GtkWidget* dialog = gtk_message_dialog_new ( GtkWidget* dialog = gtk_message_dialog_new (
NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", short_message); NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", short_message);
@ -103,6 +109,88 @@ error_dialog (const gchar* short_message,
G_CALLBACK (gtk_widget_destroy), dialog); G_CALLBACK (gtk_widget_destroy), dialog);
} }
/**
* sokoke_show_uri_with_mime_type:
* @screen: a #GdkScreen, or %NULL
* @uri: the URI to show
* @mime_type: a MIME type
* @timestamp: the timestamp of the event
* @error: the location of a #GError, or %NULL
*
* Shows the specified URI with an appropriate application,
* as though it had the specified MIME type.
*
* On Maemo, hildon_mime_open_file_with_mime_type() is used.
*
* See also: sokoke_show_uri().
*
* Return value: %TRUE on success, %FALSE if an error occurred
**/
gboolean
sokoke_show_uri_with_mime_type (GdkScreen* screen,
const gchar* uri,
const gchar* mime_type,
guint32 timestamp,
GError** error)
{
gboolean success;
#if HAVE_HILDON
osso_context_t* osso;
DBusConnection* dbus;
osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
if (!osso)
{
g_print ("Failed to initialize libosso\n");
return FALSE;
}
dbus = (DBusConnection *) osso_get_dbus_connection (osso);
if (!dbus)
{
osso_deinitialize (osso);
g_print ("Failed to get dbus connection from osso context\n");
return FALSE;
}
success = (hildon_mime_open_file_with_mime_type (dbus,
uri, mime_type) == 1);
osso_deinitialize (osso);
#else
GFile* file = g_file_new_for_uri (uri);
gchar* content_type;
GAppInfo* app_info;
GList* files;
gpointer context;
#if GLIB_CHECK_VERSION (2, 18, 0)
content_type = g_content_type_from_mime_type (mime_type);
#else
content_type = g_strdup (mime_type);
#endif
app_info = g_app_info_get_default_for_type (content_type,
!g_str_has_prefix (uri, "file://"));
g_free (content_type);
files = g_list_prepend (NULL, file);
#if GTK_CHECK_VERSION (2, 14, 0)
context = gdk_app_launch_context_new ();
gdk_app_launch_context_set_screen (context, screen);
gdk_app_launch_context_set_timestamp (context, timestamp);
#else
context = g_app_launch_context_new ();
#endif
success = g_app_info_launch (app_info, files, context, error);
g_object_unref (app_info);
g_list_free (files);
g_object_unref (file);
#endif
return success;
}
/** /**
* sokoke_show_uri: * sokoke_show_uri:
* @screen: a #GdkScreen, or %NULL * @screen: a #GdkScreen, or %NULL
@ -114,6 +202,8 @@ error_dialog (const gchar* short_message,
* supports xdg-open, exo-open and gnome-open as fallbacks if * supports xdg-open, exo-open and gnome-open as fallbacks if
* GIO doesn't do the trick. * GIO doesn't do the trick.
* *
* On Maemo, hildon_uri_open() is used.
*
* Return value: %TRUE on success, %FALSE if an error occurred * Return value: %TRUE on success, %FALSE if an error occurred
**/ **/
gboolean gboolean
@ -122,6 +212,11 @@ sokoke_show_uri (GdkScreen* screen,
guint32 timestamp, guint32 timestamp,
GError** error) GError** error)
{ {
#if HAVE_HILDON
HildonURIAction* action = hildon_uri_get_default_action_by_uri (uri, NULL);
return hildon_uri_open (uri, action, error);
#else
const gchar* fallbacks [] = { "xdg-open", "exo-open", "gnome-open" }; const gchar* fallbacks [] = { "xdg-open", "exo-open", "gnome-open" };
gsize i; gsize i;
@ -144,6 +239,7 @@ sokoke_show_uri (GdkScreen* screen,
} }
return FALSE; return FALSE;
#endif
} }
gboolean gboolean
@ -158,6 +254,34 @@ sokoke_spawn_program (const gchar* command,
if (filename) if (filename)
{ {
gboolean success;
#if HAVE_HILDON
osso_context_t* osso;
DBusConnection* dbus;
osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
if (!osso)
{
sokoke_error_dialog (_("Could not run external program."),
"Failed to initialize libosso");
return FALSE;
}
dbus = (DBusConnection *) osso_get_dbus_connection (osso);
if (!dbus)
{
osso_deinitialize (osso);
sokoke_error_dialog (_("Could not run external program."),
"Failed to get dbus connection from osso context");
return FALSE;
}
error = NULL;
/* FIXME: This is not correct, find a proper way to do this */
success = (osso_application_top (osso, command, argument) == OSSO_OK);
osso_deinitialize (osso);
#else
GAppInfo* info; GAppInfo* info;
GFile* file; GFile* file;
GList* files; GList* files;
@ -168,20 +292,23 @@ sokoke_spawn_program (const gchar* command,
files = g_list_append (NULL, file); files = g_list_append (NULL, file);
error = NULL; error = NULL;
if (!g_app_info_launch (info, files, NULL, &error)) success = g_app_info_launch (info, files, NULL, &error);
{
error_dialog (_("Could not run external program."), error->message);
g_error_free (error);
g_object_unref (file);
g_list_free (files);
return FALSE;
}
g_object_unref (file); g_object_unref (file);
g_list_free (files); g_list_free (files);
#endif
if (!success)
{
sokoke_error_dialog (_("Could not run external program."),
error ? error->message : "");
if (error)
g_error_free (error);
return FALSE;
}
} }
else else
{ {
/* FIXME: Implement Hildon specific version */
gchar* command_ready; gchar* command_ready;
gchar** argv; gchar** argv;
@ -193,7 +320,8 @@ sokoke_spawn_program (const gchar* command,
error = NULL; error = NULL;
if (!g_shell_parse_argv (command_ready, NULL, &argv, &error)) if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
{ {
error_dialog (_("Could not run external program."), error->message); sokoke_error_dialog (_("Could not run external program."),
error->message);
g_error_free (error); g_error_free (error);
g_free (command_ready); g_free (command_ready);
return FALSE; return FALSE;
@ -205,7 +333,8 @@ sokoke_spawn_program (const gchar* command,
(GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, (GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, NULL, &error)) NULL, NULL, NULL, &error))
{ {
error_dialog (_("Could not run external program."), error->message); sokoke_error_dialog (_("Could not run external program."),
error->message);
g_error_free (error); g_error_free (error);
} }
@ -395,6 +524,8 @@ sokoke_magic_uri (const gchar* uri,
/* Just return if it's a javascript: or mailto: uri */ /* Just return if it's a javascript: or mailto: uri */
if (g_str_has_prefix (uri, "javascript:") if (g_str_has_prefix (uri, "javascript:")
|| g_str_has_prefix (uri, "mailto:") || g_str_has_prefix (uri, "mailto:")
|| g_str_has_prefix (uri, "tel:")
|| g_str_has_prefix (uri, "callto:")
|| g_str_has_prefix (uri, "data:")) || g_str_has_prefix (uri, "data:"))
return g_strdup (uri); return g_strdup (uri);
/* Add file:// if we have a local path */ /* Add file:// if we have a local path */

View file

@ -26,6 +26,17 @@ sokoke_js_script_eval (JSContextRef js_context,
/* Many themes need this hack for small toolbars to work */ /* Many themes need this hack for small toolbars to work */
#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON #define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
void
sokoke_error_dialog (const gchar* short_message,
const gchar* detailed_message);
gboolean
sokoke_show_uri_with_mime_type (GdkScreen* screen,
const gchar* uri,
const gchar* mime_type,
guint32 timestamp,
GError** error);
gboolean gboolean
sokoke_show_uri (GdkScreen* screen, sokoke_show_uri (GdkScreen* screen,
const gchar* uri, const gchar* uri,