Get the available translations for anaconda and populate the welcome spoke with them. --- anaconda.spec.in | 1 + pyanaconda/localization.py | 172 +++++++++++++++++++++++++++++++++++ pyanaconda/ui/gui/spokes/welcome.py | 27 +++--- pyanaconda/ui/gui/spokes/welcome.ui | 4 +- 4 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 pyanaconda/localization.py diff --git a/anaconda.spec.in b/anaconda.spec.in index 31df6d5..682dd89 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -112,6 +112,7 @@ Requires: dosfstools Requires: e2fsprogs >= %{e2fsver} Requires: gzip Requires: libarchive +Requires: python-babel %ifarch %{ix86} x86_64 ia64 Requires: dmidecode %endif diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py new file mode 100644 index 0000000..dafc9bf --- /dev/null +++ b/pyanaconda/localization.py @@ -0,0 +1,172 @@ +# Localization classes and functions +# +# Copyright (C) 2012 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Martin Gracik <mgracik@xxxxxxxxxx> +# + +import gettext +import locale +import os +import re + +import babel + + +class LocaleInfo(object): + + def __init__(self, localedata): + self._localedata = localedata + + @property + def language(self): + return self._localedata.language + + @property + def territory(self): + return self._localedata.territory + + @property + def script(self): + return self._localedata.script + + @property + def variant(self): + return self._localedata.variant + + @property + def english_name(self): + return self._localedata.english_name or u'' + + @property + def display_name(self): + # some languages don't have a display_name + display_name = self._localedata.display_name or self.english_name + # some start with lowercase + display_name = display_name.title() + return display_name + + @property + def short_name(self): + return self.__repr__() + + def __repr__(self): + formatstr = '{0.language}' + if self.territory is not None: + formatstr += '_{0.territory}' + if self.script is not None: + formatstr += '@{0.script}' + if self.variant is not None: + formatstr += '#{0.variant}' + + return formatstr.format(self) + + def __str__(self): + return self.english_name.encode('ascii', 'replace') + + def __unicode__(self): + return self.english_name + + def __eq__(self, other): + return repr(self) == repr(other) + + +def get_all_locales(): + localeset = set() + for localename in sorted(babel.localedata.list()): + try: + localedata = babel.Locale.parse(localename) + except babel.core.UnknownLocaleError: + continue + + locale = LocaleInfo(localedata) + if repr(locale) not in localeset: + localeset.add(repr(locale)) + yield locale + + +def get_available_translations(domain=None, localedir=None): + domain = domain or gettext._current_domain + localedir = localedir or gettext._default_localedir + + langdict = babel.Locale('en', 'US').languages + messagefiles = gettext.find(domain, localedir, langdict.keys(), all=True) + languages = [path.split(os.path.sep)[-3] for path in messagefiles] + + # usually there are no message files for en_US + if 'en_US' not in languages: + languages.append('en_US') + + for langcode in languages: + try: + localedata = babel.Locale.parse(langcode) + except babel.core.UnknownLocaleError: + continue + + yield LocaleInfo(localedata) + + +class Language(object): + + def __init__(self): + self.locales = {repr(locale):locale for locale in get_all_locales()} + self.translations = {repr(locale):locale for locale in get_available_translations()} + + self.install_lang = None + self.system_lang = None + + self.set_install_lang('en_US') + self.set_system_lang('en_US') + + @staticmethod + def parse_langcode(langcode): + pattern = re.compile(r'(?P<language>[A-Za-z]+)(_(?P<territory>[A-Za-z]+))?(\.(?P<codeset>[-\w]+))?(@(?P<modifier>[-\w]+))?') + m = pattern.match(langcode) + return m.groupdict() + + @property + def install_lang_as_dict(self): + self.parse_langcode(self.install_lang) + + @property + def system_lang_as_dict(self): + self.parse_langcode(self.system_lang) + + def set_install_lang(self, langcode): + self.install_lang = langcode + + os.environ['LANG'] = langcode + os.environ['LC_NUMERIC'] = 'C' + + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error: + pass + + # XXX this is the sort of thing which you should never do, + # but we switch languages at runtime and thus need to invalidate + # the set of languages/mofiles which gettext knows about + gettext._translations = {} + + # XXX DEBUG + print 'set install lang to "%s"' % self.install_lang + + def set_system_lang(self, langcode): + self.system_lang = langcode + + # XXX DEBUG + print 'set system lang to "%s"' % self.system_lang diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py index c5d0e1d..47e037b 100644 --- a/pyanaconda/ui/gui/spokes/welcome.py +++ b/pyanaconda/ui/gui/spokes/welcome.py @@ -23,6 +23,8 @@ from gi.repository import AnacondaWidgets, Gtk from pyanaconda.ui.gui.hubs.summary import SummaryHub from pyanaconda.ui.gui.spokes import StandaloneSpoke +from pyanaconda.localization import Language + __all__ = ["WelcomeLanguageSpoke"] class WelcomeLanguageSpoke(StandaloneSpoke): @@ -47,18 +49,13 @@ class WelcomeLanguageSpoke(StandaloneSpoke): completion.set_text_column(1) store = self.builder.get_object("languageStore") - self._addLanguage(store, "English", "English", "en_US") - self._addLanguage(store, "Language A", "Language A", "C") - self._addLanguage(store, "Language B", "Language B", "C") - self._addLanguage(store, "Language C", "Language C", "C") - self._addLanguage(store, "Language D", "Language D", "C") - self._addLanguage(store, "Language E", "Language E", "C") - self._addLanguage(store, "Language F", "Language F", "C") - self._addLanguage(store, "Language G", "Language G", "C") - self._addLanguage(store, "Language H", "Language H", "C") - self._addLanguage(store, "Language I", "Language I", "C") - self._addLanguage(store, "Language J", "Language J", "C") - self._addLanguage(store, "Language K", "Language K", "C") + + # FIXME I think the following line should go somewhere else + self.language = Language() + + for code, trans in sorted(self.language.translations.items()): + self._addLanguage(store, trans.display_name, + trans.english_name, trans.short_name) def setup(self): StandaloneSpoke.setup(self) @@ -76,6 +73,12 @@ class WelcomeLanguageSpoke(StandaloneSpoke): (store, selected) = selection.get_selected_rows() self.window.set_may_continue(len(selected) > 0) + if selected: + lang = store[selected[0]][2] + self.language.set_install_lang(lang) + self.language.set_system_lang(lang) + # TODO reload the whole window so it gets translated + # Override the default in StandaloneSpoke so we can display the beta # warning dialog first. def _on_continue_clicked(self, cb): diff --git a/pyanaconda/ui/gui/spokes/welcome.ui b/pyanaconda/ui/gui/spokes/welcome.ui index b1894d5..d6cacd7 100644 --- a/pyanaconda/ui/gui/spokes/welcome.ui +++ b/pyanaconda/ui/gui/spokes/welcome.ui @@ -242,7 +242,9 @@ OS you can rely on. It's for testing purposes only.</property> <property name="headers_visible">False</property> <property name="search_column">0</property> <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection"/> + <object class="GtkTreeSelection" id="treeview-selection"> + <signal name="changed" handler="on_selection_changed" swapped="no"/> + </object> </child> <child> <object class="GtkTreeViewColumn" id="nativeName"> -- 1.7.5.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list