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

Daniel Narvaez dwnarvaez at gmail.com
Wed Mar 27 12:02:26 EDT 2013


I'm a bit concerned about using icu, but really just as a gut
reaction, I haven't read the code or researched it much.

It looks like a huge set of libraries, which might be overkill for the
use case of listing languages (did we check if/how much it increases
memory usage?). It seems to partially overlap glib. It doesn't seem to
be used by GNOME for the same functionality which is a bit suspect and
might mean it's not very tested (maybe it's used by qt though?).

Did you consider using the same code as the GNOME control panel?

https://git.gnome.org/browse/gnome-desktop/tree/libgnome-desktop/gnome-languages.c

It seems to be pretty self-contained so it could be cut and pasted. Or
we could use the library directly.

Just an idea.

On 27 March 2013 15:57, Manuel Quiñones <manuq at laptop.org> wrote:
> 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
>
> _______________________________________________
> Sugar-devel mailing list
> Sugar-devel at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/sugar-devel



-- 
Daniel Narvaez


More information about the Sugar-devel mailing list