region: Redo the language tab
Prepopulate the list with a small set of 'common' languages, as we already did in the user panel, and use a language chooser to add to that list.
This commit is contained in:
parent
60c8f11a12
commit
be235bd9ae
5 changed files with 269 additions and 272 deletions
|
@ -230,6 +230,20 @@ add_one_language (gpointer d)
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add separator between initial languages and new additions */
|
||||||
|
if (g_object_get_data (G_OBJECT (data->store), "needs-separator")) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
gtk_list_store_append (GTK_LIST_STORE (data->store), &iter);
|
||||||
|
gtk_list_store_set (GTK_LIST_STORE (data->store), &iter,
|
||||||
|
LOCALE_COL, NULL,
|
||||||
|
DISPLAY_LOCALE_COL, "Don't show",
|
||||||
|
SEPARATOR_COL, TRUE,
|
||||||
|
USER_LANGUAGE, FALSE,
|
||||||
|
-1);
|
||||||
|
g_object_set_data (G_OBJECT (data->store), "needs-separator", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_list_store_append (data->store, &iter);
|
gtk_list_store_append (data->store, &iter);
|
||||||
gtk_list_store_set (data->store, &iter, LOCALE_COL, name, DISPLAY_LOCALE_COL, language, -1);
|
gtk_list_store_set (data->store, &iter, LOCALE_COL, name, DISPLAY_LOCALE_COL, language, -1);
|
||||||
|
|
||||||
|
@ -315,6 +329,10 @@ cc_common_language_setup_list (GtkWidget *treeview,
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
|
|
||||||
cell = gtk_cell_renderer_text_new ();
|
cell = gtk_cell_renderer_text_new ();
|
||||||
|
g_object_set (cell,
|
||||||
|
"width-chars", 40,
|
||||||
|
"ellipsize", PANGO_ELLIPSIZE_END,
|
||||||
|
NULL);
|
||||||
column = gtk_tree_view_column_new_with_attributes (NULL, cell, "text", DISPLAY_LOCALE_COL, NULL);
|
column = gtk_tree_view_column_new_with_attributes (NULL, cell, "text", DISPLAY_LOCALE_COL, NULL);
|
||||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||||
store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
|
store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
|
||||||
|
@ -333,18 +351,10 @@ cc_common_language_setup_list (GtkWidget *treeview,
|
||||||
/* Add languages from the initial hashtable */
|
/* Add languages from the initial hashtable */
|
||||||
g_hash_table_foreach (initial, (GHFunc) languages_foreach_cb, store);
|
g_hash_table_foreach (initial, (GHFunc) languages_foreach_cb, store);
|
||||||
|
|
||||||
/* Add separator if we had any languages added */
|
/* Mark the need for a separator if we had any languages added */
|
||||||
if (initial != NULL &&
|
if (initial != NULL &&
|
||||||
g_hash_table_size (initial) > 0) {
|
g_hash_table_size (initial) > 0) {
|
||||||
GtkTreeIter iter;
|
g_object_set_data (G_OBJECT (store), "needs-separator", GINT_TO_POINTER (TRUE));
|
||||||
|
|
||||||
gtk_list_store_append (GTK_LIST_STORE (store), &iter);
|
|
||||||
gtk_list_store_set (GTK_LIST_STORE (store), &iter,
|
|
||||||
LOCALE_COL, NULL,
|
|
||||||
DISPLAY_LOCALE_COL, "Don't show",
|
|
||||||
SEPARATOR_COL, TRUE,
|
|
||||||
USER_LANGUAGE, FALSE,
|
|
||||||
-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,3 +390,112 @@ cc_common_language_select_current_language (GtkTreeView *treeview)
|
||||||
g_free (lang);
|
g_free (lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_other_users_language (GHashTable *ht)
|
||||||
|
{
|
||||||
|
GVariant *variant;
|
||||||
|
GVariantIter *vi;
|
||||||
|
GError *error = NULL;
|
||||||
|
const char *str;
|
||||||
|
GDBusProxy *proxy;
|
||||||
|
|
||||||
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
"org.freedesktop.Accounts",
|
||||||
|
"/org/freedesktop/Accounts",
|
||||||
|
"org.freedesktop.Accounts",
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (proxy == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
variant = g_dbus_proxy_call_sync (proxy,
|
||||||
|
"ListCachedUsers",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (variant == NULL) {
|
||||||
|
g_warning ("Failed to list existing users: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
g_object_unref (proxy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_variant_get (variant, "(ao)", &vi);
|
||||||
|
while (g_variant_iter_loop (vi, "o", &str)) {
|
||||||
|
GDBusProxy *user;
|
||||||
|
GVariant *props;
|
||||||
|
const char *lang;
|
||||||
|
char *name;
|
||||||
|
char *language;
|
||||||
|
|
||||||
|
user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
"org.freedesktop.Accounts",
|
||||||
|
str,
|
||||||
|
"org.freedesktop.Accounts.User",
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (user == NULL) {
|
||||||
|
g_warning ("Failed to get proxy for user '%s': %s",
|
||||||
|
str, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
error = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
props = g_dbus_proxy_get_cached_property (user, "Language");
|
||||||
|
lang = g_variant_get_string (props, NULL);
|
||||||
|
if (lang != NULL && *lang != '\0' &&
|
||||||
|
cc_common_language_has_font (lang)) {
|
||||||
|
name = gdm_normalize_language_name (lang);
|
||||||
|
if (!g_hash_table_lookup (ht, name)) {
|
||||||
|
language = gdm_get_language_from_name (name, NULL);
|
||||||
|
g_hash_table_insert (ht, name, language);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_free (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_variant_unref (props);
|
||||||
|
g_object_unref (user);
|
||||||
|
}
|
||||||
|
g_variant_iter_free (vi);
|
||||||
|
g_variant_unref (variant);
|
||||||
|
|
||||||
|
g_object_unref (proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
GHashTable *
|
||||||
|
cc_common_language_get_initial_languages (void)
|
||||||
|
{
|
||||||
|
GHashTable *ht;
|
||||||
|
char *name;
|
||||||
|
char *language;
|
||||||
|
|
||||||
|
ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
|
/* Add some common languages first */
|
||||||
|
g_hash_table_insert (ht, g_strdup ("en_US.utf8"), g_strdup (_("English")));
|
||||||
|
g_hash_table_insert (ht, g_strdup ("de_DE.utf8"), g_strdup (_("German")));
|
||||||
|
g_hash_table_insert (ht, g_strdup ("fr_FR.utf8"), g_strdup (_("French")));
|
||||||
|
g_hash_table_insert (ht, g_strdup ("es_ES.utf8"), g_strdup (_("Spanish")));
|
||||||
|
g_hash_table_insert (ht, g_strdup ("zh_CN.utf8"), g_strdup (_("Chinese")));
|
||||||
|
|
||||||
|
/* Add the languages used by other users on the system */
|
||||||
|
add_other_users_language (ht);
|
||||||
|
|
||||||
|
/* Add current locale */
|
||||||
|
name = cc_common_language_get_current_language ();
|
||||||
|
if (g_hash_table_lookup (ht, name) == NULL) {
|
||||||
|
language = gdm_get_language_from_name (name, NULL);
|
||||||
|
g_hash_table_insert (ht, name, language);
|
||||||
|
} else {
|
||||||
|
g_free (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ht;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ guint cc_common_language_add_available_languages (GtkListStore *store,
|
||||||
gboolean cc_common_language_has_font (const gchar *locale);
|
gboolean cc_common_language_has_font (const gchar *locale);
|
||||||
gchar *cc_common_language_get_current_language (void);
|
gchar *cc_common_language_get_current_language (void);
|
||||||
|
|
||||||
|
GHashTable *cc_common_language_get_initial_languages (void);
|
||||||
|
|
||||||
void cc_common_language_setup_list (GtkWidget *treeview,
|
void cc_common_language_setup_list (GtkWidget *treeview,
|
||||||
GHashTable *initial);
|
GHashTable *initial);
|
||||||
void cc_common_language_select_current_language (GtkTreeView *treeview);
|
void cc_common_language_select_current_language (GtkTreeView *treeview);
|
||||||
|
|
|
@ -72,111 +72,6 @@ row_activated (GtkTreeView *tree_view,
|
||||||
gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
|
gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
add_other_users_language (GHashTable *ht)
|
|
||||||
{
|
|
||||||
GVariant *variant;
|
|
||||||
GVariantIter *vi;
|
|
||||||
GError *error = NULL;
|
|
||||||
const char *str;
|
|
||||||
GDBusProxy *proxy;
|
|
||||||
|
|
||||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
|
||||||
NULL,
|
|
||||||
"org.freedesktop.Accounts",
|
|
||||||
"/org/freedesktop/Accounts",
|
|
||||||
"org.freedesktop.Accounts",
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (proxy == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
variant = g_dbus_proxy_call_sync (proxy,
|
|
||||||
"ListCachedUsers",
|
|
||||||
NULL,
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
-1,
|
|
||||||
NULL,
|
|
||||||
&error);
|
|
||||||
if (variant == NULL) {
|
|
||||||
g_warning ("Failed to list existing users: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
g_object_unref (proxy);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_variant_get (variant, "(ao)", &vi);
|
|
||||||
while (g_variant_iter_loop (vi, "o", &str)) {
|
|
||||||
GDBusProxy *user;
|
|
||||||
GVariant *props;
|
|
||||||
const char *lang;
|
|
||||||
char *name;
|
|
||||||
char *language;
|
|
||||||
|
|
||||||
user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
|
||||||
NULL,
|
|
||||||
"org.freedesktop.Accounts",
|
|
||||||
str,
|
|
||||||
"org.freedesktop.Accounts.User",
|
|
||||||
NULL,
|
|
||||||
&error);
|
|
||||||
if (user == NULL) {
|
|
||||||
g_warning ("Failed to get proxy for user '%s': %s",
|
|
||||||
str, error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
error = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
props = g_dbus_proxy_get_cached_property (user, "Language");
|
|
||||||
lang = g_variant_get_string (props, NULL);
|
|
||||||
if (lang != NULL && *lang != '\0' &&
|
|
||||||
cc_common_language_has_font (lang)) {
|
|
||||||
name = gdm_normalize_language_name (lang);
|
|
||||||
language = gdm_get_language_from_name (name, NULL);
|
|
||||||
g_hash_table_insert (ht, name, language);
|
|
||||||
}
|
|
||||||
g_variant_unref (props);
|
|
||||||
g_object_unref (user);
|
|
||||||
}
|
|
||||||
g_variant_iter_free (vi);
|
|
||||||
g_variant_unref (variant);
|
|
||||||
|
|
||||||
g_object_unref (proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GHashTable *
|
|
||||||
new_ht_for_user_languages (void)
|
|
||||||
{
|
|
||||||
GHashTable *ht;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
|
||||||
|
|
||||||
/* Add some common languages first */
|
|
||||||
g_hash_table_insert (ht, g_strdup ("en_US.utf8"), g_strdup (_("English")));
|
|
||||||
g_hash_table_insert (ht, g_strdup ("de_DE.utf8"), g_strdup (_("German")));
|
|
||||||
g_hash_table_insert (ht, g_strdup ("fr_FR.utf8"), g_strdup (_("French")));
|
|
||||||
g_hash_table_insert (ht, g_strdup ("es_ES.utf8"), g_strdup (_("Spanish")));
|
|
||||||
g_hash_table_insert (ht, g_strdup ("zh_CN.utf8"), g_strdup (_("Chinese")));
|
|
||||||
|
|
||||||
/* Add the languages used by other users on the system */
|
|
||||||
add_other_users_language (ht);
|
|
||||||
|
|
||||||
/* Make sure the current locale is present */
|
|
||||||
name = cc_common_language_get_current_language ();
|
|
||||||
if (g_hash_table_lookup (ht, name) == NULL) {
|
|
||||||
char *language;
|
|
||||||
language = gdm_get_language_from_name (name, NULL);
|
|
||||||
g_hash_table_insert (ht, name, language);
|
|
||||||
} else {
|
|
||||||
g_free (name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ht;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
languages_foreach_cb (gpointer key,
|
languages_foreach_cb (gpointer key,
|
||||||
gpointer value,
|
gpointer value,
|
||||||
|
@ -205,7 +100,7 @@ cc_add_user_languages (GtkTreeModel *model)
|
||||||
|
|
||||||
gtk_list_store_clear (store);
|
gtk_list_store_clear (store);
|
||||||
|
|
||||||
user_langs = new_ht_for_user_languages ();
|
user_langs = cc_common_language_get_initial_languages ();
|
||||||
|
|
||||||
/* Add the current locale first */
|
/* Add the current locale first */
|
||||||
name = cc_common_language_get_current_language ();
|
name = cc_common_language_get_current_language ();
|
||||||
|
@ -242,6 +137,15 @@ remove_async (gpointer data)
|
||||||
g_source_remove (async_id);
|
g_source_remove (async_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
selection_changed (GtkTreeSelection *selection,
|
||||||
|
GtkWidget *chooser)
|
||||||
|
{
|
||||||
|
gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
|
||||||
|
GTK_RESPONSE_OK,
|
||||||
|
gtk_tree_selection_get_selected (selection, NULL, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
finish_language_chooser (gpointer user_data)
|
finish_language_chooser (gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -252,6 +156,7 @@ finish_language_chooser (gpointer user_data)
|
||||||
GHashTable *user_langs;
|
GHashTable *user_langs;
|
||||||
guint timeout;
|
guint timeout;
|
||||||
guint async_id;
|
guint async_id;
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
|
||||||
/* Did we get called after the widget was destroyed? */
|
/* Did we get called after the widget was destroyed? */
|
||||||
if (chooser == NULL)
|
if (chooser == NULL)
|
||||||
|
@ -272,8 +177,10 @@ finish_language_chooser (gpointer user_data)
|
||||||
timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (chooser), "timeout"));
|
timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (chooser), "timeout"));
|
||||||
g_object_weak_unref (G_OBJECT (chooser), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout));
|
g_object_weak_unref (G_OBJECT (chooser), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout));
|
||||||
|
|
||||||
/* And select the current language */
|
/* And now listen for changes */
|
||||||
cc_common_language_select_current_language (GTK_TREE_VIEW (list));
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
|
||||||
|
g_signal_connect (G_OBJECT (selection), "changed",
|
||||||
|
G_CALLBACK (selection_changed), chooser);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -389,8 +296,7 @@ cc_language_chooser_new (GtkWidget *parent)
|
||||||
g_signal_connect (entry, "icon-release",
|
g_signal_connect (entry, "icon-release",
|
||||||
G_CALLBACK (filter_clear), NULL);
|
G_CALLBACK (filter_clear), NULL);
|
||||||
|
|
||||||
/* Add user languages */
|
user_langs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
user_langs = new_ht_for_user_languages ();
|
|
||||||
cc_common_language_setup_list (list, user_langs);
|
cc_common_language_setup_list (list, user_langs);
|
||||||
|
|
||||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
|
||||||
|
|
|
@ -28,93 +28,11 @@
|
||||||
|
|
||||||
#include "gnome-region-panel-lang.h"
|
#include "gnome-region-panel-lang.h"
|
||||||
#include "cc-common-language.h"
|
#include "cc-common-language.h"
|
||||||
|
#include "cc-language-chooser.h"
|
||||||
#include "gdm-languages.h"
|
#include "gdm-languages.h"
|
||||||
|
|
||||||
static GDBusProxy *proxy = NULL;
|
static GDBusProxy *proxy = NULL;
|
||||||
|
|
||||||
static void
|
|
||||||
add_other_users_language (GHashTable *ht)
|
|
||||||
{
|
|
||||||
GVariant *variant;
|
|
||||||
GVariantIter *vi;
|
|
||||||
GError *error = NULL;
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
if (proxy == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
variant = g_dbus_proxy_call_sync (proxy,
|
|
||||||
"ListCachedUsers",
|
|
||||||
NULL,
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
-1,
|
|
||||||
NULL,
|
|
||||||
&error);
|
|
||||||
if (variant == NULL) {
|
|
||||||
g_warning ("Failed to list existing users: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_variant_get (variant, "(ao)", &vi);
|
|
||||||
while (g_variant_iter_loop (vi, "o", &str)) {
|
|
||||||
GDBusProxy *user;
|
|
||||||
GVariant *props;
|
|
||||||
const char *name;
|
|
||||||
char *language;
|
|
||||||
|
|
||||||
user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
|
||||||
NULL,
|
|
||||||
"org.freedesktop.Accounts",
|
|
||||||
str,
|
|
||||||
"org.freedesktop.Accounts.User",
|
|
||||||
NULL,
|
|
||||||
&error);
|
|
||||||
if (user == NULL) {
|
|
||||||
g_warning ("Failed to get proxy for user '%s': %s",
|
|
||||||
str, error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
error = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
props = g_dbus_proxy_get_cached_property (user, "Language");
|
|
||||||
name = g_variant_get_string (props, NULL);
|
|
||||||
if (name != NULL && *name != '\0') {
|
|
||||||
language = gdm_get_language_from_name (name, NULL);
|
|
||||||
g_hash_table_insert (ht, g_strdup (name), language);
|
|
||||||
}
|
|
||||||
g_variant_unref (props);
|
|
||||||
g_object_unref (user);
|
|
||||||
}
|
|
||||||
g_variant_iter_free (vi);
|
|
||||||
g_variant_unref (variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GHashTable *
|
|
||||||
new_ht_for_user_languages (void)
|
|
||||||
{
|
|
||||||
GHashTable *ht;
|
|
||||||
char *name;
|
|
||||||
char *language;
|
|
||||||
|
|
||||||
ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
|
||||||
|
|
||||||
/* Add the languages used by other users on the system */
|
|
||||||
add_other_users_language (ht);
|
|
||||||
|
|
||||||
/* Add current locale */
|
|
||||||
name = cc_common_language_get_current_language ();
|
|
||||||
if (g_hash_table_lookup (ht, name) == NULL) {
|
|
||||||
language = gdm_get_language_from_name (name, NULL);
|
|
||||||
g_hash_table_insert (ht, name, language);
|
|
||||||
} else {
|
|
||||||
g_free (name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ht;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
selection_changed (GtkTreeSelection *selection,
|
selection_changed (GtkTreeSelection *selection,
|
||||||
GtkTreeView *list)
|
GtkTreeView *list)
|
||||||
|
@ -201,61 +119,64 @@ bail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_timeout (gpointer data,
|
language_response (GtkDialog *dialog,
|
||||||
GObject *where_the_object_was)
|
gint response_id,
|
||||||
|
GtkWidget *treeview)
|
||||||
{
|
{
|
||||||
guint timeout = GPOINTER_TO_UINT (data);
|
gchar *lang;
|
||||||
g_source_remove (timeout);
|
GtkTreeModel *model;
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
|
if (response_id != GTK_RESPONSE_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lang = cc_language_chooser_get_language (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
|
if (lang == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
|
||||||
|
|
||||||
|
if (cc_common_language_get_iter_for_language (model, lang, &iter)) {
|
||||||
|
gtk_tree_selection_select_iter (selection, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_grab_focus (treeview);
|
||||||
|
|
||||||
|
g_free (lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_async (gpointer data)
|
add_language (GtkWidget *button, GtkWidget *treeview)
|
||||||
{
|
{
|
||||||
guint id = GPOINTER_TO_UINT (data);
|
GtkWidget *toplevel;
|
||||||
|
GtkWidget *chooser;
|
||||||
|
|
||||||
/* if the idle is already done, this harmlessly fails */
|
toplevel = gtk_widget_get_toplevel (button);
|
||||||
g_source_remove (id);
|
chooser = g_object_get_data (G_OBJECT (button), "chooser");
|
||||||
}
|
if (chooser == NULL) {
|
||||||
|
chooser = cc_language_chooser_new (toplevel);
|
||||||
|
|
||||||
static gboolean
|
g_signal_connect (chooser, "response",
|
||||||
finish_language_setup (gpointer user_data)
|
G_CALLBACK (language_response), treeview);
|
||||||
{
|
g_signal_connect (chooser, "delete-event",
|
||||||
GtkWidget *list = (GtkWidget *) user_data;
|
G_CALLBACK (gtk_widget_hide_on_delete), NULL);
|
||||||
GtkTreeModel *model;
|
|
||||||
GtkWidget *parent;
|
|
||||||
GHashTable *user_langs;
|
|
||||||
guint timeout;
|
|
||||||
GtkTreeSelection *selection;
|
|
||||||
guint async_id;
|
|
||||||
|
|
||||||
/* Did we get called after the widget was destroyed? */
|
g_object_set_data_full (G_OBJECT (button), "chooser",
|
||||||
if (list == NULL)
|
chooser, (GDestroyNotify)gtk_widget_destroy);
|
||||||
return FALSE;
|
}
|
||||||
|
else {
|
||||||
|
cc_language_chooser_clear_filter (chooser);
|
||||||
|
}
|
||||||
|
|
||||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
|
gdk_window_set_cursor (gtk_widget_get_window (toplevel), NULL);
|
||||||
user_langs = g_object_get_data (G_OBJECT (list), "user-langs");
|
gtk_window_present (GTK_WINDOW (chooser));
|
||||||
|
|
||||||
async_id = cc_common_language_add_available_languages (GTK_LIST_STORE (model), user_langs);
|
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (list), "language-async",
|
|
||||||
GUINT_TO_POINTER (async_id), remove_async);
|
|
||||||
|
|
||||||
parent = gtk_widget_get_toplevel (list);
|
|
||||||
gdk_window_set_cursor (gtk_widget_get_window (parent), NULL);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (list), "user-langs", NULL);
|
|
||||||
timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (list), "timeout"));
|
|
||||||
g_object_weak_unref (G_OBJECT (list), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout));
|
|
||||||
|
|
||||||
/* And select the current language */
|
|
||||||
cc_common_language_select_current_language (GTK_TREE_VIEW (list));
|
|
||||||
|
|
||||||
/* And now listen for changes */
|
|
||||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
|
|
||||||
g_signal_connect (G_OBJECT (selection), "changed",
|
|
||||||
G_CALLBACK (selection_changed), list);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -263,13 +184,25 @@ setup_language (GtkBuilder *builder)
|
||||||
{
|
{
|
||||||
GtkWidget *treeview;
|
GtkWidget *treeview;
|
||||||
GHashTable *user_langs;
|
GHashTable *user_langs;
|
||||||
GtkWidget *parent;
|
|
||||||
GdkWindow *window;
|
|
||||||
guint timeout;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
GtkWidget *widget;
|
||||||
|
GtkStyleContext *context;
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
|
||||||
|
/* Setup junction between toolbar and treeview */
|
||||||
|
widget = (GtkWidget *)gtk_builder_get_object (builder, "language-swindow");
|
||||||
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
|
||||||
|
widget = (GtkWidget *)gtk_builder_get_object (builder, "language-toolbar");
|
||||||
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
|
||||||
|
|
||||||
treeview = GTK_WIDGET (gtk_builder_get_object (builder, "display_language_treeview"));
|
treeview = GTK_WIDGET (gtk_builder_get_object (builder, "display_language_treeview"));
|
||||||
parent = gtk_widget_get_toplevel (treeview);
|
|
||||||
|
/* Connect buttons */
|
||||||
|
widget = (GtkWidget *)gtk_builder_get_object (builder, "language_add");
|
||||||
|
g_signal_connect (widget, "clicked",
|
||||||
|
G_CALLBACK (add_language), treeview);
|
||||||
|
|
||||||
/* Setup accounts service */
|
/* Setup accounts service */
|
||||||
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
@ -280,6 +213,7 @@ setup_language (GtkBuilder *builder)
|
||||||
"org.freedesktop.Accounts",
|
"org.freedesktop.Accounts",
|
||||||
NULL,
|
NULL,
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
if (proxy == NULL) {
|
if (proxy == NULL) {
|
||||||
g_warning ("Failed to contact accounts service: %s", error->message);
|
g_warning ("Failed to contact accounts service: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
@ -288,22 +222,16 @@ setup_language (GtkBuilder *builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add user languages */
|
/* Add user languages */
|
||||||
user_langs = new_ht_for_user_languages ();
|
user_langs = cc_common_language_get_initial_languages ();
|
||||||
cc_common_language_setup_list (treeview, user_langs);
|
cc_common_language_setup_list (treeview, user_langs);
|
||||||
|
|
||||||
/* Setup so that the list is populated after the list appears */
|
/* And select the current language */
|
||||||
window = gtk_widget_get_window (parent);
|
cc_common_language_select_current_language (GTK_TREE_VIEW (treeview));
|
||||||
if (window) {
|
|
||||||
GdkCursor *cursor;
|
|
||||||
|
|
||||||
cursor = gdk_cursor_new (GDK_WATCH);
|
/* And now listen for changes */
|
||||||
gdk_window_set_cursor (gtk_widget_get_window (parent), cursor);
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
|
||||||
g_object_unref (cursor);
|
g_signal_connect (G_OBJECT (selection), "changed",
|
||||||
}
|
G_CALLBACK (selection_changed), treeview);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (treeview), "user-langs",
|
gtk_widget_grab_focus (treeview);
|
||||||
user_langs, (GDestroyNotify) g_hash_table_destroy);
|
|
||||||
timeout = g_idle_add ((GSourceFunc) finish_language_setup, treeview);
|
|
||||||
g_object_set_data (G_OBJECT (treeview), "timeout", GUINT_TO_POINTER (timeout));
|
|
||||||
g_object_weak_ref (G_OBJECT (treeview), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,12 +125,12 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkHBox" id="hbox1">
|
<object class="GtkBox" id="hbox1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="spacing">12</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
<object class="GtkScrolledWindow" id="language-swindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="hscrollbar_policy">never</property>
|
<property name="hscrollbar_policy">never</property>
|
||||||
|
@ -152,6 +152,48 @@
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolbar" id="language-toolbar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="show_arrow">False</property>
|
||||||
|
<property name="icon_size">1</property>
|
||||||
|
<property name="toolbar-style">icons</property>
|
||||||
|
<style>
|
||||||
|
<class name="inline-toolbar"/>
|
||||||
|
</style>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="language_add">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="icon_name">list-add-symbolic</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToolButton" id="language_remove">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="icon_name">list-remove-symbolic</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkVBox" id="vbox3">
|
<object class="GtkVBox" id="vbox3">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue