[Xfce4-commits] <midori:master> Implement 'Preferred languages' preference, ACCEPT_LANGUAGE header
Christian Dywan
noreply at xfce.org
Thu Jan 7 01:40:02 CET 2010
Updating branch refs/heads/master
to b5b32495f9301cb184f4e995d9dc21e8a9b51c67 (commit)
from e126271ad8dc614b209164d86f64b5e11d15c318 (commit)
commit b5b32495f9301cb184f4e995d9dc21e8a9b51c67
Author: André Stösel <Midori-Plugin at PyIT.de>
Date: Thu Jan 7 00:49:41 2010 +0100
Implement 'Preferred languages' preference, ACCEPT_LANGUAGE header
midori/main.c | 31 +++++++++++++++
midori/midori-preferences.c | 5 ++
midori/midori-websettings.c | 24 ++++++++++++
midori/sokoke.c | 86 +++++++++++++++++++++++++++++++++++++++++++
midori/sokoke.h | 3 +
5 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/midori/main.c b/midori/main.c
index 2c4c614..fe0789c 100644
--- a/midori/main.c
+++ b/midori/main.c
@@ -1117,6 +1117,34 @@ soup_session_settings_notify_ident_string_cb (MidoriWebSettings* settings,
#endif
static void
+midori_soup_session_settings_accept_language_cb (SoupSession* session,
+ SoupMessage* msg,
+ MidoriWebSettings* settings)
+{
+ gchar* languages = katze_object_get_string (settings, "preferred-languages");
+ gchar* accpt;
+
+ /* Empty, use the system locales */
+ if (!(languages && *languages))
+ accpt = sokoke_accept_languages (g_get_language_names ());
+ /* No =, no ., looks like a list of language names */
+ else if (!(strchr (languages, '=') && strchr (languages, '.')))
+ {
+ gchar ** lang_names = g_strsplit_set (languages, ",; ", -1);
+ accpt = sokoke_accept_languages ((const gchar* const *)lang_names);
+ g_strfreev (lang_names);
+ }
+ /* Presumably a well formatted list including priorities */
+ else
+ accpt = languages;
+
+ if (accpt != languages)
+ g_free (languages);
+ soup_message_headers_append (msg->request_headers, "ACCEPT_LANGUAGE", accpt);
+ g_free (accpt);
+}
+
+static void
midori_soup_session_debug (SoupSession* session)
{
const char* soup_debug = g_getenv ("MIDORI_SOUP_DEBUG");
@@ -1150,6 +1178,9 @@ midori_soup_session_prepare (SoupSession* session,
G_CALLBACK (soup_session_settings_notify_ident_string_cb), session);
#endif
+ g_signal_connect (session, "request-queued",
+ G_CALLBACK (midori_soup_session_settings_accept_language_cb), settings);
+
config_file = build_config_filename ("logins");
feature = g_object_new (KATZE_TYPE_HTTP_AUTH, "filename", config_file, NULL);
g_free (config_file);
diff --git a/midori/midori-preferences.c b/midori/midori-preferences.c
index 75d7a67..82c5241 100644
--- a/midori/midori-preferences.c
+++ b/midori/midori-preferences.c
@@ -495,6 +495,11 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
INDENTED_ADD (label);
button = katze_property_proxy (settings, "identify-as", "custom-ident-string");
SPANNED_ADD (button);
+ label = katze_property_label (settings, "preferred-languages");
+ INDENTED_ADD (label);
+ entry = katze_property_proxy (settings, "preferred-languages", NULL);
+ SPANNED_ADD (entry);
+
/* Page "Privacy" */
PAGE_NEW (GTK_STOCK_INDEX, _("Privacy"));
diff --git a/midori/midori-websettings.c b/midori/midori-websettings.c
index 9c04704..33e1b55 100644
--- a/midori/midori-websettings.c
+++ b/midori/midori-websettings.c
@@ -86,6 +86,7 @@ struct _MidoriWebSettings
gboolean remember_last_downloaded_files;
gchar* http_proxy;
+ gchar* http_accept_language;
gboolean auto_detect_proxy;
MidoriIdentity identify_as;
gchar* ident_string;
@@ -170,6 +171,7 @@ enum
PROP_AUTO_DETECT_PROXY,
PROP_IDENTIFY_AS,
PROP_IDENT_STRING,
+ PROP_PREFERRED_LANGUAGES,
PROP_CLEAR_PRIVATE_DATA
};
@@ -1049,6 +1051,22 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
+ * MidoriWebSettings:preferred-languages:
+ *
+ * A comma separated list of languages preferred for rendering multilingual webpages.
+ *
+ * Since: 0.2.3
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_PREFERRED_LANGUAGES,
+ g_param_spec_string (
+ "preferred-languages",
+ _("Preferred languages"),
+ _("A comma separated list of languages preferred for rendering multilingual webpages, for example \"de\", \"ru,nl\" or \"en-us;q=1.0, fr-fr;q=0.667\""),
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
* MidoriWebSettings:clear-private-data:
*
* The private data selected for deletion.
@@ -1462,6 +1480,9 @@ midori_web_settings_set_property (GObject* object,
#endif
}
break;
+ case PROP_PREFERRED_LANGUAGES:
+ katze_assign (web_settings->http_accept_language, g_value_dup_string (value));
+ break;
case PROP_CLEAR_PRIVATE_DATA:
web_settings->clear_private_data = g_value_get_int (value);
break;
@@ -1677,6 +1698,9 @@ midori_web_settings_get_property (GObject* object,
}
g_value_set_string (value, web_settings->ident_string);
break;
+ case PROP_PREFERRED_LANGUAGES:
+ g_value_set_string (value, web_settings->http_accept_language);
+ break;
case PROP_CLEAR_PRIVATE_DATA:
g_value_set_int (value, web_settings->clear_private_data);
break;
diff --git a/midori/sokoke.c b/midori/sokoke.c
index bd74132..c917d7e 100644
--- a/midori/sokoke.c
+++ b/midori/sokoke.c
@@ -1633,3 +1633,89 @@ sokoke_prefetch_uri (const char* uri)
soup_uri_free (s_uri);
return TRUE;
}
+
+/* Provide a new way for SoupSession to assume an 'Accept-Language'
+ string automatically from the return value of g_get_language_names(),
+ properly formatted according to RFC2616.
+ Copyright (C) 2009 Mario Sanchez Prada <msanchez at igalia.com>
+ Copyright (C) 2009 Dan Winship <danw at gnome.org>
+ Mostly copied from libSoup 2.29, coding style adjusted */
+
+/* Converts a language in POSIX format and to be RFC2616 compliant */
+/* Based on code from epiphany-webkit (ephy_langs_append_languages()) */
+static gchar *
+sokoke_posix_lang_to_rfc2616 (const gchar *language)
+{
+ if (!strchr (language, '.') && !strchr (language, '@') && language[0] != 'C')
+ /* change to lowercase and '_' to '-' */
+ return g_strdelimit (g_ascii_strdown (language, -1), "_", '-');
+
+ return NULL;
+}
+
+/* Adds a quality value to a string (any value between 0 and 1). */
+static gchar *
+sokoke_add_quality_value (const gchar *str,
+ float qvalue)
+{
+ if ((qvalue >= 0.0) && (qvalue <= 1.0))
+ {
+ int qv_int = (qvalue * 1000 + 0.5);
+ return g_strdup_printf ("%s;q=%d.%d",
+ str, (int) (qv_int / 1000), qv_int % 1000);
+ }
+
+ return g_strdup (str);
+}
+
+/* Returns a RFC2616 compliant languages list from system locales */
+gchar *
+sokoke_accept_languages (const gchar* const * lang_names)
+{
+ GArray *langs_garray = NULL;
+ char *cur_lang = NULL;
+ char *prev_lang = NULL;
+ char **langs_array;
+ char *langs_str;
+ float delta;
+ int i, n_lang_names;
+
+ /* Calculate delta for setting the quality values */
+ n_lang_names = g_strv_length ((gchar **)lang_names);
+ delta = 0.999 / (n_lang_names - 1);
+
+ /* Build the array of languages */
+ langs_garray = g_array_new (TRUE, FALSE, sizeof (char*));
+ for (i = 0; lang_names[i] != NULL; i++)
+ {
+ cur_lang = sokoke_posix_lang_to_rfc2616 (lang_names[i]);
+
+ /* Apart from getting a valid RFC2616 compliant
+ language, also get rid of extra variants */
+ if (cur_lang && (!prev_lang ||
+ (!strcmp (prev_lang, cur_lang) || !strstr (prev_lang, cur_lang))))
+ {
+
+ gchar *qv_lang = NULL;
+
+ /* Save reference for further comparison */
+ prev_lang = cur_lang;
+
+ /* Add the quality value and append it */
+ qv_lang = sokoke_add_quality_value (cur_lang, 1 - i * delta);
+ g_array_append_val (langs_garray, qv_lang);
+ }
+ }
+
+ /* Fallback: add "en" if list is empty */
+ if (langs_garray->len == 0)
+ {
+ gchar* fallback = g_strdup ("en");
+ g_array_append_val (langs_garray, fallback);
+ }
+
+ langs_array = (char **) g_array_free (langs_garray, FALSE);
+ langs_str = g_strjoinv (", ", langs_array);
+
+ return langs_str;
+}
diff --git a/midori/sokoke.h b/midori/sokoke.h
index 621ca99..1960650 100644
--- a/midori/sokoke.h
+++ b/midori/sokoke.h
@@ -204,4 +204,7 @@ sokoke_file_chooser_dialog_new (const gchar* title,
gboolean
sokoke_prefetch_uri (const char* uri);
+gchar *
+sokoke_accept_languages (const gchar* const * lang_names);
+
#endif /* !__SOKOKE_H__ */
More information about the Xfce4-commits
mailing list