~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/region/gnome-region-panel-formats.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2011 Rodrigo Moya
 
3
 *
 
4
 * Written by: Rodrigo Moya <rodrigo@gnome.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2, or (at your option)
 
9
 * any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 */
 
21
 
 
22
#ifdef HAVE_CONFIG_H
 
23
#  include <config.h>
 
24
#endif
 
25
 
 
26
#include <glib/gi18n-lib.h>
 
27
#include <locale.h>
 
28
#include <langinfo.h>
 
29
#include <stdlib.h>
 
30
#include "cc-common-language.h"
 
31
#include "cc-language-chooser.h"
 
32
#include "gdm-languages.h"
 
33
#include "gnome-region-panel-formats.h"
 
34
#include "gnome-region-panel-system.h"
 
35
 
 
36
static void
 
37
display_date (GtkLabel *label, GDateTime *dt, const gchar *format)
 
38
{
 
39
        gchar *s;
 
40
 
 
41
        s = g_date_time_format (dt, format);
 
42
        s = g_strstrip (s);
 
43
        gtk_label_set_text (label, s);
 
44
        g_free (s);
 
45
}
 
46
 
 
47
static void
 
48
select_region (GtkTreeView *treeview, const gchar *lang)
 
49
{
 
50
        GtkTreeModel *model;
 
51
        GtkTreeSelection *selection;
 
52
        GtkTreeIter iter;
 
53
        GtkTreePath *path;
 
54
        gboolean cont;
 
55
 
 
56
        model = gtk_tree_view_get_model (treeview);
 
57
        selection = gtk_tree_view_get_selection (treeview);
 
58
        cont = gtk_tree_model_get_iter_first (model, &iter);
 
59
        while (cont) {
 
60
                gchar *locale;
 
61
 
 
62
                gtk_tree_model_get (model, &iter, 0, &locale, -1);
 
63
                if (g_strcmp0 (locale, lang) == 0) {
 
64
                        gtk_tree_selection_select_iter (selection, &iter);
 
65
                        path = gtk_tree_model_get_path (model, &iter);
 
66
                        gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
 
67
                        gtk_tree_path_free (path);
 
68
                        g_free (locale);
 
69
                        break;
 
70
                }
 
71
                g_free (locale);
 
72
 
 
73
                cont = gtk_tree_model_iter_next (model, &iter);
 
74
        }
 
75
}
 
76
 
 
77
static void
 
78
update_examples_cb (GtkTreeSelection *selection, gpointer user_data)
 
79
{
 
80
        GtkBuilder *builder = GTK_BUILDER (user_data);
 
81
        GtkTreeModel *model;
 
82
        GtkTreeIter iter;
 
83
        gchar *active_id;
 
84
        gchar *locale;
 
85
        GDateTime *dt;
 
86
        gchar *s;
 
87
        struct lconv *num_info;
 
88
        const char *fmt;
 
89
 
 
90
        if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
 
91
                return;
 
92
        }
 
93
        gtk_tree_model_get (model, &iter, 0, &active_id, -1);
 
94
 
 
95
        locale = g_strdup (setlocale (LC_TIME, NULL));
 
96
        setlocale (LC_TIME, active_id);
 
97
 
 
98
        dt = g_date_time_new_now_local ();
 
99
 
 
100
        /* Display dates */
 
101
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "full_date_format")), dt, "%A %e %B %Y");
 
102
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "full_day_format")), dt, "%e %B %Y");
 
103
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "short_day_format")), dt, "%e %b %Y");
 
104
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "shortest_day_format")), dt, "%x");
 
105
 
 
106
        /* Display times */
 
107
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "full_time_format")), dt, "%r %Z");
 
108
        display_date (GTK_LABEL (gtk_builder_get_object (builder, "short_time_format")), dt, "%X");
 
109
 
 
110
        setlocale (LC_TIME, locale);
 
111
        g_free (locale);
 
112
 
 
113
        /* Display numbers */
 
114
        locale = g_strdup (setlocale (LC_NUMERIC, NULL));
 
115
        setlocale (LC_NUMERIC, active_id);
 
116
 
 
117
        s = g_strdup_printf ("%'.2f", 123456789.00);
 
118
        gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "numbers_format")), s);
 
119
        g_free (s);
 
120
 
 
121
        setlocale (LC_NUMERIC, locale);
 
122
        g_free (locale);
 
123
 
 
124
        /* Display currency */
 
125
        locale = g_strdup (setlocale (LC_MONETARY, NULL));
 
126
        setlocale (LC_MONETARY, active_id);
 
127
 
 
128
        num_info = localeconv ();
 
129
        if (num_info != NULL) {
 
130
                gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "currency_format")), num_info->currency_symbol);
 
131
        }
 
132
 
 
133
        setlocale (LC_MONETARY, locale);
 
134
        g_free (locale);
 
135
 
 
136
        /* Display measurement */
 
137
#ifdef LC_MEASUREMENT
 
138
        locale = g_strdup (setlocale (LC_MEASUREMENT, NULL));
 
139
        setlocale (LC_MEASUREMENT, active_id);
 
140
 
 
141
        fmt = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT);
 
142
        if (fmt && *fmt == 2)
 
143
                gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "measurement_format")), _("Imperial"));
 
144
        else
 
145
                gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "measurement_format")), _("Metric"));
 
146
 
 
147
        setlocale (LC_MEASUREMENT, locale);
 
148
        g_free (locale);
 
149
#endif
 
150
        g_free (active_id);
 
151
}
 
152
 
 
153
static void
 
154
set_formats_locale (const gchar *formats_locale)
 
155
{
 
156
        GDBusProxy  *proxy;
 
157
        GError      *error = NULL;
 
158
        gchar       *user_path;
 
159
        GVariant    *ret;
 
160
 
 
161
        user_path = g_strdup_printf ("/org/freedesktop/Accounts/User%i", getuid ());
 
162
        proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
 
163
                                               G_DBUS_PROXY_FLAGS_NONE,
 
164
                                               NULL,
 
165
                                               "org.freedesktop.Accounts",
 
166
                                               user_path,
 
167
                                               "org.freedesktop.Accounts.User",
 
168
                                               NULL,
 
169
                                               &error);
 
170
        if (!proxy) {
 
171
                g_warning ("Couldn't get accountsservice proxy for %s: %s", user_path, error->message);
 
172
                g_error_free (error);
 
173
                g_free (user_path);
 
174
                return;
 
175
        }
 
176
 
 
177
        ret = g_dbus_proxy_call_sync (proxy,
 
178
                                      "SetFormatsLocale",
 
179
                                      g_variant_new ("(s)", formats_locale),
 
180
                                      G_DBUS_CALL_FLAGS_NONE,
 
181
                                      -1,
 
182
                                      NULL,
 
183
                                      &error);
 
184
        if (!ret) {
 
185
                g_warning ("Couldn't set FormatsLocale: %s", error->message);
 
186
                g_error_free (error);
 
187
        } else
 
188
                g_variant_unref (ret);
 
189
 
 
190
        g_object_unref (proxy);
 
191
        g_free (user_path);
 
192
}
 
193
 
 
194
static void
 
195
update_settings_cb (GtkTreeSelection *selection, gpointer user_data)
 
196
{
 
197
        GtkBuilder *builder = GTK_BUILDER (user_data);
 
198
        GtkTreeModel *model;
 
199
        GtkTreeIter iter;
 
200
        gchar *active_id;
 
201
        GtkWidget *treeview;
 
202
        GSettings *locale_settings;
 
203
 
 
204
        if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
 
205
                return;
 
206
        }
 
207
        gtk_tree_model_get (model, &iter, 0, &active_id, -1);
 
208
 
 
209
        treeview = GTK_WIDGET (gtk_builder_get_object (builder, "region_selector"));
 
210
 
 
211
        locale_settings = g_object_get_data (G_OBJECT (treeview), "settings");
 
212
 
 
213
        set_formats_locale (active_id);
 
214
        locale_settings_changed (locale_settings, NULL, builder);
 
215
 
 
216
        g_free (active_id);
 
217
}
 
218
 
 
219
static void
 
220
setting_changed_cb (GSettings *locale_settings, gchar *key, GtkTreeView *treeview)
 
221
{
 
222
        gchar *current_setting;
 
223
 
 
224
        current_setting = cc_common_language_get_property ("FormatsLocale");
 
225
        select_region (treeview, current_setting);
 
226
        g_free (current_setting);
 
227
}
 
228
 
 
229
static gint
 
230
sort_regions (GtkTreeModel *model,
 
231
              GtkTreeIter  *a,
 
232
              GtkTreeIter  *b,
 
233
              gpointer      data)
 
234
{
 
235
        gchar *la, *lb;
 
236
        gint result;
 
237
 
 
238
        gtk_tree_model_get (model, a, 1, &la, -1);
 
239
        gtk_tree_model_get (model, b, 1, &lb, -1);
 
240
 
 
241
        result = strcmp (la, lb);
 
242
 
 
243
        g_free (la);
 
244
        g_free (lb);
 
245
 
 
246
        return result;
 
247
}
 
248
 
 
249
static void
 
250
populate_regions (GtkBuilder *builder, const gchar *current_lang)
 
251
{
 
252
        gchar *current_region;
 
253
        GHashTable *ht;
 
254
        GHashTableIter htiter;
 
255
        GtkTreeModel *model;
 
256
        gchar *name, *language;
 
257
        GtkWidget *treeview;
 
258
        GtkTreeIter iter;
 
259
        GtkTreeSelection *selection;
 
260
 
 
261
        treeview = GTK_WIDGET (gtk_builder_get_object (builder, "region_selector"));
 
262
        /* don't update the setting just because the list is repopulated */
 
263
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
 
264
        g_signal_handlers_block_by_func (selection, update_settings_cb, builder);
 
265
 
 
266
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
 
267
 
 
268
        ht = cc_common_language_get_initial_regions (current_lang);
 
269
 
 
270
        current_region = cc_common_language_get_property ("FormatsLocale");
 
271
        if (!current_region || !current_region[0]) {
 
272
                current_region = g_strdup (current_lang);
 
273
        }
 
274
        else if (!g_hash_table_lookup (ht, current_region)) {
 
275
                name = gdm_get_region_from_name (current_region, NULL);
 
276
                g_hash_table_insert (ht, g_strdup (current_region), name);
 
277
        }
 
278
 
 
279
        gtk_list_store_clear (GTK_LIST_STORE (model));
 
280
 
 
281
        g_hash_table_iter_init (&htiter, ht);
 
282
        while (g_hash_table_iter_next (&htiter, (gpointer *)&name, (gpointer *)&language)) {
 
283
                gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 
284
                gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, name, 1, language, -1);
 
285
        }
 
286
        g_hash_table_unref (ht);
 
287
 
 
288
        select_region (GTK_TREE_VIEW (treeview), current_region);
 
289
 
 
290
        g_free (current_region);
 
291
 
 
292
        g_signal_handlers_unblock_by_func (selection, update_settings_cb, builder);
 
293
}
 
294
 
 
295
static void
 
296
region_response (GtkDialog *dialog,
 
297
                 gint       response_id,
 
298
                 GtkWidget *treeview)
 
299
{
 
300
        gchar *lang;
 
301
        GtkTreeModel *model;
 
302
        GtkTreeSelection *selection;
 
303
        GtkTreeIter iter;
 
304
 
 
305
        gtk_widget_hide (GTK_WIDGET (dialog));
 
306
 
 
307
        if (response_id != GTK_RESPONSE_OK) {
 
308
                return;
 
309
        }
 
310
 
 
311
        lang = cc_language_chooser_get_language (GTK_WIDGET (dialog));
 
312
 
 
313
        if (lang == NULL) {
 
314
                return;
 
315
        }
 
316
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
 
317
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
 
318
 
 
319
        if (cc_common_language_get_iter_for_region (model, lang, &iter)) {
 
320
                gtk_tree_selection_select_iter (selection, &iter);
 
321
        }
 
322
 
 
323
        gtk_widget_grab_focus (treeview);
 
324
 
 
325
        g_free (lang);
 
326
}
 
327
 
 
328
static void
 
329
add_region (GtkWidget *button, GtkWidget *treeview)
 
330
{
 
331
        GtkWidget *toplevel;
 
332
        GtkWidget *chooser;
 
333
 
 
334
        toplevel = gtk_widget_get_toplevel (button);
 
335
        chooser = g_object_get_data (G_OBJECT (button), "chooser");
 
336
        if (chooser == NULL) {
 
337
                chooser = cc_language_chooser_new (toplevel, TRUE);
 
338
 
 
339
                g_signal_connect (chooser, "response",
 
340
                                  G_CALLBACK (region_response), treeview);
 
341
                g_signal_connect (chooser, "delete-event",
 
342
                                  G_CALLBACK (gtk_widget_hide_on_delete), NULL);
 
343
 
 
344
                g_object_set_data_full (G_OBJECT (button), "chooser",
 
345
                                        chooser, (GDestroyNotify)gtk_widget_destroy);
 
346
        }
 
347
        else {
 
348
                cc_language_chooser_clear_filter (chooser);
 
349
        }
 
350
 
 
351
        gdk_window_set_cursor (gtk_widget_get_window (toplevel), NULL);
 
352
        gtk_window_present (GTK_WINDOW (chooser));
 
353
}
 
354
 
 
355
void
 
356
setup_formats (GtkBuilder *builder)
 
357
{
 
358
        GtkWidget *treeview;
 
359
        gchar *current_lang;
 
360
        GtkTreeModel *model;
 
361
        GtkCellRenderer *cell;
 
362
        GtkTreeViewColumn *column;
 
363
        GtkWidget *widget;
 
364
        GtkStyleContext *context;
 
365
        GSettings *locale_settings;
 
366
        GtkTreeSelection *selection;
 
367
 
 
368
        locale_settings = g_settings_new ("org.gnome.system.locale");
 
369
 
 
370
        /* Setup junction between toolbar and treeview */
 
371
        widget = (GtkWidget *)gtk_builder_get_object (builder, "region-swindow");
 
372
        context = gtk_widget_get_style_context (widget);
 
373
        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
 
374
        widget = (GtkWidget *)gtk_builder_get_object (builder, "region-toolbar");
 
375
        context = gtk_widget_get_style_context (widget);
 
376
        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
 
377
 
 
378
        /* Setup formats selector */
 
379
        treeview = GTK_WIDGET (gtk_builder_get_object (builder, "region_selector"));
 
380
        cell = gtk_cell_renderer_text_new ();
 
381
        g_object_set (cell,
 
382
                      "width-chars", 40,
 
383
                      "ellipsize", PANGO_ELLIPSIZE_END,
 
384
                      NULL);
 
385
        column = gtk_tree_view_column_new_with_attributes (NULL, cell, "text", 1, NULL);
 
386
        gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
 
387
 
 
388
        model = (GtkTreeModel*)gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
 
389
        gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
 
390
                                                 sort_regions, NULL, NULL);
 
391
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
 
392
                                              GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
 
393
                                              GTK_SORT_ASCENDING);
 
394
        gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model);
 
395
 
 
396
        g_object_set_data_full (G_OBJECT (treeview), "settings", locale_settings, g_object_unref);
 
397
 
 
398
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
 
399
        g_signal_connect (selection, "changed",
 
400
                          G_CALLBACK (update_settings_cb), builder);
 
401
        g_signal_connect (selection, "changed",
 
402
                          G_CALLBACK (update_examples_cb), builder);
 
403
 
 
404
        /* Connect buttons */
 
405
        widget = (GtkWidget *)gtk_builder_get_object (builder, "region_add");
 
406
        g_signal_connect (widget, "clicked",
 
407
                          G_CALLBACK (add_region), treeview);
 
408
 
 
409
        current_lang = cc_common_language_get_current_language ();
 
410
        populate_regions (builder, current_lang);
 
411
        g_free (current_lang);
 
412
 
 
413
        g_signal_connect (locale_settings, "changed::region",
 
414
                          G_CALLBACK (setting_changed_cb), treeview);
 
415
}
 
416
 
 
417
void
 
418
formats_update_language (GtkBuilder  *builder,
 
419
                         const gchar *language)
 
420
{
 
421
        populate_regions (builder, language);
 
422
}
 
423