languages.c

Go to the documentation of this file.
00001 /*
00002  * File Name: languages.c
00003  */
00004 
00005 /*
00006  * This file is part of settings.
00007  *
00008  * settings is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * settings is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 // system include files, between < >
00032 #include <locale.h>
00033 
00034 #include <gtk/gtk.h>
00035 #include <gdk/gdk.h>
00036 #include <glib.h>
00037 
00038 // ereader include files, between < >
00039 #include <libergtk/ergtk.h>
00040 
00041 // local include files, between " "
00042 #include "i18n.h"
00043 #include "log.h"
00044 #include "ipc.h"
00045 #include "settings.h"
00046 #include "settings_utils.h"
00047 #include "settings_style.h"
00048 #include "languages.h"
00049 
00050 
00051 //----------------------------------------------------------------------------
00052 // Type Declarations
00053 //----------------------------------------------------------------------------
00054 
00055 //----------------------------------------------------------------------------
00056 // Global Constants
00057 //----------------------------------------------------------------------------
00058 
00059 #define MAX_LANGUAGES                 12
00060 
00061 //----------------------------------------------------------------------------
00062 // Static Variables
00063 //----------------------------------------------------------------------------
00064 
00065 static gint g_orig_language = 0;
00066 static gint g_cur_language = 0;
00067 
00068 static GtkWidget* g_language_radios[MAX_LANGUAGES] = { 
00069                                                         NULL, 
00070                                                         NULL, 
00071                                                         NULL, 
00072                                                         NULL, 
00073                                                         NULL, 
00074                                                         NULL, 
00075                                                         NULL, 
00076                                                         NULL, 
00077                                                         NULL, 
00078                                                         NULL, 
00079                                                         NULL, 
00080                                                         NULL, 
00081                                                     };
00082 
00083 static gboolean   g_is_firstboot        = FALSE;
00084 static GtkWidget* g_main_window         = NULL ;
00085 static GtkWidget* g_title               = NULL;
00086 static GtkWidget* g_subtitle            = NULL;
00087 static GtkWidget* g_language_label      = NULL;
00088 static GtkWidget* g_language_label_desc = NULL;
00089 static GtkWidget* g_continue_button     = NULL;
00090 static GtkWidget* g_continue_label      = NULL;
00091 static GtkWidget* g_continue_label_desc = NULL;
00092 
00093 static const GdkColor grey = {0, 0x5500, 0x5500, 0x5500};
00094 
00095 //============================================================================
00096 // Local Function Definitions
00097 //============================================================================
00098 
00099 static GtkWidget* create_language_widgets       (GtkBox* parent);
00100 static void create_descriptive_text_widgets     (GtkBox* parent);
00101 static GtkWidget* create_continue_widgets       (GtkBox* parent);
00102 
00103 static GSList*    get_available_locales         ();
00104 static GSList*    get_available_languages       ();
00105 static void       free_string_list              (GSList* lang_list);
00106 
00107 static void       on_language_selection_changed (GtkWidget *widget, gpointer data);
00108 static void       update_labels_and_buttons (void);
00109 static gboolean   on_continue_button_clicked(GtkWidget* widget, gpointer data);
00110 
00111 static void init_widgets_with_settings          (void);
00112 //============================================================================
00113 // Functions Implementation
00114 //============================================================================
00115 
00116 GtkWidget* create_language_window(GtkWidget* parent, gboolean is_firstboot)
00117 {
00118     g_is_firstboot = is_firstboot;
00119 
00120     // create top window
00121     GtkWidget* top_window = parent;
00122     if (is_firstboot) 
00123     {
00124         gtk_window_fullscreen(GTK_WINDOW(top_window));
00125     } else 
00126     {
00127         gtk_window_maximize(GTK_WINDOW(top_window));
00128     }
00129     gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
00130     gtk_container_set_border_width(GTK_CONTAINER(top_window),WINDOW_BORDER_PADDING);
00131     gtk_window_set_modal(GTK_WINDOW(top_window), TRUE);
00132 
00133     // top level vbox (vboxtop)
00134     GtkWidget* vboxtop = gtk_vbox_new(FALSE, 3);
00135     gtk_container_add(GTK_CONTAINER(top_window), vboxtop);
00136 
00137     // add header container the title and subtitle of this settings page
00138     create_title_keep_labels(GTK_VBOX(vboxtop), NULL, NULL, &g_title, &g_subtitle);
00139 
00140     GtkWidget* view = NULL ; 
00141     if (! is_firstboot) {
00142         // add the back/exit bar below the title 
00143         view = create_settingsview_for_type( SETTING_LANGUAGE );
00144         gtk_box_pack_start(GTK_BOX(vboxtop), view, FALSE, FALSE,0 ); 
00145     }
00146 
00147     // The margin settings section.
00148     create_language_widgets(GTK_BOX(vboxtop));
00149 
00150 
00151     if ( ! is_firstboot )
00152     {
00153         gtk_widget_grab_focus(view);
00154     }
00155     else {
00156         // create save frame
00157         create_continue_widgets(GTK_BOX(vboxtop));
00158     }
00159     
00160     // Update widget with current settings.
00161     init_widgets_with_settings();
00162 
00163     g_main_window = top_window;
00164 
00165     gtk_widget_show_all(top_window);
00166 
00167     return top_window;
00168 }
00169 
00170 //============================================================================
00171 // Local Functions Implementation
00172 //============================================================================
00173 
00174 static GtkWidget* create_radio_button_item(GtkWidget* group, gchar* title)
00175 {
00176     GtkWidget* radio_button = NULL ;
00177     if ( group == NULL ) 
00178     {
00179         radio_button = gtk_radio_button_new(NULL); 
00180     }
00181     else {
00182         radio_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(group)); 
00183 
00184     }
00185     gtk_widget_set_name(radio_button, "irex-settings-checkbutton");
00186 
00187     // alignment in radio button for some padding
00188     GtkWidget* align = gtk_alignment_new(0, 0.0, 1.0, 1.0);
00189     gtk_container_add(GTK_CONTAINER(radio_button), align);
00190     gtk_alignment_set_padding(GTK_ALIGNMENT(align)
00191                                 , 6 // top
00192                                 , 6 // bottom
00193                                 , 6 // left
00194                                 , 6 // right
00195             );
00196  
00197     // top level label for radio button ( no margins )
00198     GtkWidget* label = gtk_label_new( title );
00199     gtk_widget_set_name(label, "irex-radio-title");
00200     gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.0);
00201     gtk_container_add(GTK_CONTAINER(align), label);
00202 
00203     return radio_button;
00204 }
00205 
00206 static void create_descriptive_text_widgets(GtkBox* parent)
00207 {
00208     GtkVBox* vbox = GTK_VBOX(parent);
00209 
00210     // the label Default Language
00211     g_language_label = subject_create();
00212     gtk_box_pack_start(GTK_BOX(vbox), g_language_label, FALSE, FALSE, 0);
00213 
00214     // the label language description
00215     g_language_label_desc = description_create();
00216     gtk_box_pack_start(GTK_BOX(vbox), g_language_label_desc, FALSE, FALSE, 0);
00217 
00218     // add separator
00219     GtkWidget* separator = create_separator_widgets();
00220     gtk_widget_set_name(separator, "irex-separator-invisible");
00221     gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
00222 }
00223 
00224 static GtkWidget* create_language_widgets(GtkBox* parent)
00225 {
00226     GtkVBox* frame = create_frame(GTK_VBOX(parent));
00227     
00228     // the descriptive text
00229     create_descriptive_text_widgets(GTK_BOX(frame));
00230 
00231     GSList* lang_list = get_available_languages();
00232     int n_languages = g_slist_length(lang_list);
00233 
00234     // limit the number of supported languages to MAX_LANGUAGES.
00235     // more does not fit on the screen
00236     if ( n_languages > MAX_LANGUAGES ) 
00237     {
00238         n_languages = MAX_LANGUAGES;
00239     }
00240 
00241     GList* p = (GList *) lang_list;
00242 
00243     int i = 0 ;
00244     for (i=0; i<n_languages; i++, p=p->next)
00245     {
00246         if ( i == 0 )
00247         {
00248                 // the first radio button
00249                 g_language_radios[i] =  create_radio_button_item(NULL, p->data); 
00250         }
00251         else {
00252                 // The other radio buttons
00253                 g_language_radios[i] = create_radio_button_item(g_language_radios[0], p->data);
00254         }
00255 
00256         // Add signal handler.
00257         g_signal_connect_after(G_OBJECT(g_language_radios[i]),
00258             "toggled",
00259             G_CALLBACK(on_language_selection_changed),
00260             (gpointer)i);
00261 
00262         gtk_box_pack_start(GTK_BOX(frame), g_language_radios[i], FALSE, FALSE, 0);
00263     }
00264 
00265     return GTK_WIDGET(frame);
00266 }
00267 
00268 static GtkWidget* create_continue_widgets(GtkBox* parent)
00269 {
00270     GtkVBox* frame = create_frame(GTK_VBOX(parent));
00271 
00272     // the label Default Language
00273     g_continue_label = subject_create();
00274     gtk_box_pack_start(GTK_BOX(frame), g_continue_label, FALSE, FALSE, 0);
00275 
00276     // the label language description
00277     g_continue_label_desc = description_create();
00278     gtk_box_pack_start(GTK_BOX(frame), g_continue_label_desc, FALSE, FALSE, 0);
00279 
00280     // add separator
00281     GtkWidget* separator = create_separator_widgets();
00282     gtk_widget_set_name(separator, "irex-separator-invisible");
00283     gtk_box_pack_start(GTK_BOX(frame), separator, FALSE, FALSE, 0);
00284 
00285      // create button box
00286     GtkWidget* button_box = gtk_hbutton_box_new();
00287     gtk_box_pack_start(GTK_BOX(frame), button_box, FALSE, FALSE, 9);
00288     gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_START);
00289     
00290     g_continue_button = gtk_button_new();
00291     gtk_box_pack_start(GTK_BOX(button_box), g_continue_button, FALSE, FALSE, 0);
00292     // Add signal handler.
00293     g_signal_connect(G_OBJECT(g_continue_button),
00294             "clicked",
00295             G_CALLBACK(on_continue_button_clicked ),
00296             (gpointer) NULL );
00297 
00298     return GTK_WIDGET(frame);
00299 }
00300 
00301 static void update_labels_and_buttons()
00302 {
00303     if (g_is_firstboot)
00304     {
00305         // title
00306         gtk_label_set_label(GTK_LABEL(g_title), _("Setup"));
00307         // subtitle
00308         gtk_label_set_label(GTK_LABEL(g_subtitle), _("Language Selection"));
00309         // text for label g_language_label
00310         gtk_label_set_label(GTK_LABEL(g_language_label), _("Language"));
00311         // text for label g_language_label_desc
00312         gtk_label_set_label(GTK_LABEL(g_language_label_desc), _("Choose the language to be used on this Digital Reader "
00313                                                                 "and click continue to start using the device"));
00314         // Continue section
00315         gtk_label_set_label(GTK_LABEL(g_continue_label), _("Save & Continue"));
00316         gtk_label_set_label(GTK_LABEL(g_continue_label_desc),
00317                 _("Tap continue to save the changes and start using the device."));
00318         gtk_button_set_label(GTK_BUTTON(g_continue_button),  _("Save") );
00319     }
00320     else
00321     {
00322         // title
00323         gtk_label_set_label(GTK_LABEL(g_title), _("Settings"));
00324         // subtitle
00325         gtk_label_set_label(GTK_LABEL(g_subtitle), _("Language Selection"));
00326         // update exit bar
00327         update_settings_exit_text( _("to Settings"), _("Return to the Settings overview page"));
00328         // text for label g_language_label
00329         gtk_label_set_label(GTK_LABEL(g_language_label), _("Default Language"));
00330         // text for label g_language_label_desc
00331         gtk_label_set_label(GTK_LABEL(g_language_label_desc), _("Choose the language to be used on this Digital Reader"));
00332     }
00333 }
00334 
00335 static void on_language_selection_changed(GtkWidget *widget, gpointer data)
00336 {
00337     GSList* available_locales = NULL;
00338     const char* cur_locale    = NULL;
00339     int index                 = (int)data;
00340 
00341     gboolean is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
00342     if (is_active == FALSE || index == g_cur_language)
00343     {
00344         return;
00345     }
00346 
00347     g_cur_language = index;
00348 
00349     // Step 1: Call setlocale.
00350     available_locales = get_available_locales();
00351     cur_locale = g_slist_nth_data(available_locales, g_cur_language);
00352 
00353     g_setenv("LANG", cur_locale, TRUE);
00354     setlocale(LC_ALL, cur_locale);
00355     free_string_list(available_locales);
00356 
00357     // Step 2: Update labels and buttons with new locale.
00358     update_labels_and_buttons();
00359     
00360     // Step 3: Save the new setting
00361     save_language_settings();
00362 }
00363 
00364 static gboolean on_continue_button_clicked(GtkWidget* widget, gpointer data)
00365 {
00366 
00367     //save_language_settings();
00368     main_quit();
00369     return FALSE;
00370 }
00371 
00372 static GSList* get_available_locales()
00373 {
00374     return get_value_string_list(GCONF_LOCALE_LIST);
00375 }
00376 
00377 static GSList* get_available_languages()
00378 {
00379     return get_value_string_list(GCONF_LANGUAGE_LIST);
00380 }
00381 
00382 static void free_string_list(GSList* lang_list)
00383 {
00384     GSList* p = lang_list;
00385 
00386     while (p)
00387     {
00388         g_free(p->data);
00389         p = p->next;
00390     }
00391 
00392     g_slist_free(lang_list);
00393     lang_list = NULL;
00394 }
00395 
00396 static void init_widgets_with_settings()
00397 {
00398     // Update labels with current locale.
00399     update_labels_and_buttons();
00400 
00401     // Set current chosen language option.
00402     g_assert( g_cur_language < MAX_LANGUAGES );
00403     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_language_radios[g_cur_language]), TRUE);
00404 }
00405 
00406 //============================================================================
00407 // Functions Implementation
00408 //============================================================================
00409 
00410 void load_language_settings()
00411 {
00412     GSList* available_locales = get_available_locales();
00413     const char* cur_locale = get_value_string(GCONF_CURRENT_LOCALE);
00414     if (cur_locale == NULL)
00415     {
00416         cur_locale = "en_US";
00417     }
00418 
00419     GSList* found = g_slist_find_custom(available_locales, cur_locale, (GCompareFunc)strcmp);
00420     if (!found)
00421     {
00422         LOGPRINTF("Locale [%s] not found - try en_US", cur_locale);
00423         found = g_slist_find_custom(available_locales, "en_US", (GCompareFunc)strcmp);
00424     }
00425     if (!found)
00426     {
00427         LOGPRINTF("Locale en_US not found - try en_GB");
00428         found = g_slist_find_custom(available_locales, "en_GB", (GCompareFunc)strcmp);
00429     }
00430 
00431     g_orig_language = g_slist_position(available_locales, found);
00432     g_cur_language = g_orig_language;
00433 }
00434 
00435 void save_language_settings()
00436 {
00437     GSList*  available_locales = NULL;
00438     gpointer cur_locale        = NULL;
00439 
00440     // Save language settings if necessary.
00441     if (g_cur_language != g_orig_language)
00442     {
00443         // Set current locale.
00444         available_locales = get_available_locales();
00445         cur_locale = g_slist_nth_data(available_locales, g_cur_language);
00446         set_value_string(GCONF_CURRENT_LOCALE, cur_locale);
00447         free_string_list(available_locales);
00448     }
00449 
00450     LOGPRINTF("Saving language settings, done.");
00451 }
00452 
00453 //============================================================================
00454 // Functions Implementation
00455 //============================================================================
00456 
00457 void rollback_language_settings()
00458 {
00459     GSList* available_locales = NULL;
00460     const char* cur_locale    = NULL;
00461 
00462     if (g_cur_language == g_orig_language)
00463     {
00464         return;
00465     }
00466 
00467     g_cur_language = g_orig_language;
00468 
00469     // Set locale back to original.
00470     available_locales = get_available_locales();
00471     cur_locale = g_slist_nth_data(available_locales, g_orig_language);
00472     setlocale(LC_ALL, cur_locale);
00473     free_string_list(available_locales);
00474 }
00475 
00476 void language_set_main_focus(void)
00477 {
00478     gtk_widget_grab_focus(g_language_radios[0]);
00479 }
Generated by  doxygen 1.6.2-20100208