[Sugar-devel] [PATCH sugar] CP Language section: improve the list of language/country - SL #51

Manuel Quiñones manuq at laptop.org
Wed Mar 27 10:57:21 EDT 2013


Important note: this adds a new dependency: PyICU (yum install pyicu
in Fedora).

Improvements:

- The list is now displayed in the actual language of the locale.  For
  example "Deutsch (Deutschland)" for 'de_DE' or "italiano (Italia)"
  for 'it_IT'.  The translated text is also accompanied by the text in
  the current locale, with a foreground color that makes it less
  relevant.

- Translation issues that were in the previous implementation are gone
  SL #4449 and #4327 .

- Less load time.
  http://bugs.sugarlabs.org/ticket/4449#comment:12

- Layout: the combo box now has a fixed width (1/3 of the screen) and
  the text inside does ellipsize.

Implementation: switch to PyICU, which is faster and has better
results than the current implementation, based on gettext and parsing
strings from the output of 'locale -av' command.

Signed-off-by: Manuel Quiñones <manuq at laptop.org>
---
 extensions/cpsection/language/model.py | 81 ++++++++++++++++++++++------------
 extensions/cpsection/language/view.py  | 17 ++++---
 2 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/extensions/cpsection/language/model.py b/extensions/cpsection/language/model.py
index 17de6bb..9386cc7 100644
--- a/extensions/cpsection/language/model.py
+++ b/extensions/cpsection/language/model.py
@@ -25,34 +25,60 @@ import locale
 from gettext import gettext as _
 import subprocess
 
+from PyICU import Locale
 
 _default_lang = '%s.%s' % locale.getdefaultlocale()
 _standard_msg = _('Could not access ~/.i18n. Create standard settings.')
 
 
-def read_all_languages():
-    fdp = subprocess.Popen(['locale', '-av'], stdout=subprocess.PIPE)
+def _read_all_locale_codes():
+    """
+    Return the list of the available locales in the system.
+
+    """
+    fdp = subprocess.Popen(['locale', '-a'], stdout=subprocess.PIPE)
     lines = fdp.stdout.read().split('\n')
-    locales = []
+    codes = []
 
     for line in lines:
-        if line.find('locale:') != -1:
-            locale = line.split()[1]
-        elif line.find('language |') != -1:
-            lang = line.lstrip('language |')
-        elif line.find('territory |') != -1:
-            territory = line.lstrip('territory |')
-            if locale.endswith('utf8') and len(lang):
-                locales.append((lang, territory, locale))
+        if line.endswith('utf8'):
+            codes.append(line)
 
     #FIXME: This is a temporary workaround for locales that are essential to
     # OLPC, but are not in Glibc yet.
-    locales.append(('Kreyol', 'Haiti', 'ht_HT.utf8'))
-    locales.append(('Dari', 'Afghanistan', 'fa_AF.utf8'))
-    locales.append(('Pashto', 'Afghanistan', 'ps_AF.utf8'))
+    for code in ['ht_HT.utf8', 'fa_AF.utf8', 'ps_AF.utf8']:
+        codes.append(code)
+
+    return codes
+
+def _get_locale_data(locale_code):
+    """
+    Return information about the locale.
+
+    - 'language' and 'country' are in English.
 
-    locales.sort()
-    return locales
+    - 'description' is the text to be displayed to the user.  It is in
+      Pango markup with: 1. the locale display name in the locale
+      itself (for example "Deutsch (Deutschland)" for 'de_DE.utf8' or
+      "italiano (Italia)" for 'it_IT.utf8') and 2. the locale display
+      name in the current locale..
+
+    """
+    locale = Locale(locale_code)
+    english = Locale.getEnglish()
+    description = "%s <span foreground=\"#808080\">%s</span>" % \
+        (locale.getDisplayName(locale), locale.getDisplayName())
+    return {'code': locale_code,
+            'language': locale.getDisplayLanguage(english),
+            'country': locale.getDisplayCountry(english),
+            'description': description}
+
+def read_all_languages():
+    """
+    Return information about each available locale.
+
+    """
+    return [_get_locale_data(code) for code in _read_all_locale_codes()]
 
 
 def _initialize():
@@ -60,11 +86,11 @@ def _initialize():
         # when running under 'python -OO', all __doc__ fields are None,
         # so += would fail -- and this function would be unnecessary anyway.
         return
-    languages = read_all_languages()
     set_languages.__doc__ += '\n'
-    for lang in languages:
-        set_languages.__doc__ += '%s \n' % (lang[0].replace(' ', '_') + '/' +
-                                           lang[1].replace(' ', '_'))
+    for lang in read_all_languages():
+        set_languages.__doc__ += '%s \n' % \
+            (lang['language'].replace(' ', '_') +
+             '/' + lang['country'].replace(' ', '_'))
 
 
 def _write_i18n(lang_env, language_env):
@@ -120,9 +146,9 @@ def print_languages():
     for code in codes:
         found_lang = False
         for lang in languages:
-            if lang[2].split('.')[0] == code.split('.')[0]:
-                print lang[0].replace(' ', '_') + '/' + \
-                    lang[1].replace(' ', '_')
+            if lang['code'].split('.')[0] == code.split('.')[0]:
+                print lang['language'].replace(' ', '_') + '/' + \
+                    lang['country'].replace(' ', '_')
                 found_lang = True
                 break
         if not found_lang:
@@ -142,12 +168,11 @@ def set_languages(languages):
         set_languages_list([languages])
         return 1
     else:
-        langs = read_all_languages()
-        for lang, territory, locale in langs:
-            code = lang.replace(' ', '_') + '/' \
-                + territory.replace(' ', '_')
+        for lang in read_all_languages():
+            code = lang['language'].replace(' ', '_') + '/' \
+                + lang['country'].replace(' ', '_')
             if code == languages:
-                set_languages_list([locale])
+                set_languages_list([lang['code']])
                 return 1
         print (_("Sorry I do not speak \'%s\'.") % languages)
 
diff --git a/extensions/cpsection/language/view.py b/extensions/cpsection/language/view.py
index 99275d4..77be2a6 100644
--- a/extensions/cpsection/language/view.py
+++ b/extensions/cpsection/language/view.py
@@ -16,7 +16,9 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
 from gi.repository import Gtk
+from gi.repository import Gdk
 from gi.repository import GObject
+from gi.repository import Pango
 import gettext
 
 from sugar3.graphics import style
@@ -25,9 +27,6 @@ from sugar3.graphics.icon import Icon
 from jarabe.controlpanel.sectionview import SectionView
 from jarabe.controlpanel.inlinealert import InlineAlert
 
-_translate_language = lambda msg: gettext.dgettext('iso_639', msg)
-_translate_country = lambda msg: gettext.dgettext('iso_3166', msg)
-
 CLASS = 'Language'
 ICON = 'module-language'
 TITLE = gettext.gettext('Language')
@@ -99,16 +98,16 @@ class Language(SectionView):
         self._attach_to_table(label, 0, 1, padding=1)
         label.show()
 
-        store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
-        for language, country, code in self._available_locales:
-            description = '%s (%s)' % (_translate_language(language), \
-                _translate_country(country))
-            store.append([code, description])
+        store = Gtk.ListStore(str, str)
+        for locale in self._available_locales:
+            store.append([locale['code'], locale['description']])
 
         combobox = Gtk.ComboBox(model=store)
         cell = Gtk.CellRendererText()
+        cell.props.width = Gdk.Screen.width() / 3
+        cell.props.ellipsize = Pango.EllipsizeMode.MIDDLE
         combobox.pack_start(cell, True)
-        combobox.add_attribute(cell, 'text', 1)
+        combobox.add_attribute(cell, 'markup', 1)
 
         if locale_code:
             for row in store:
-- 
1.8.1.4



More information about the Sugar-devel mailing list