[PATCH 6/7] Rework the Langsupport spoke to work with all locales
Vratislav Podzimek
vpodzime at redhat.com
Tue Sep 3 14:27:08 UTC 2013
On Tue, 2013-09-03 at 14:43 +0200, Radek Vykydal wrote:
> On 08/30/2013 11:15 AM, Vratislav Podzimek wrote:
> > diff --git a/pyanaconda/ui/gui/spokes/langsupport.py b/pyanaconda/ui/gui/spokes/langsupport.py
> > index 5f44599..6f75ebc 100644
> > --- a/pyanaconda/ui/gui/spokes/langsupport.py
> > +++ b/pyanaconda/ui/gui/spokes/langsupport.py
> > @@ -17,6 +17,7 @@
> > # Red Hat, Inc.
> > #
> > # Red Hat Author(s): Radek Vykydal <rvykydal at redhat.com>
> > +# Vratislav Podzimek <vpodzime at redhat.com>
> > #
> >
> > from gi.repository import Gtk, Pango
> > @@ -25,6 +26,7 @@ from pyanaconda.i18n import N_
> > from pyanaconda.iutil import strip_accents
> > from pyanaconda.ui.gui.spokes import NormalSpoke
> > from pyanaconda.ui.gui.categories.localization import LocalizationCategory
> > +from pyanaconda.ui.gui.utils import set_treeview_selection
> > from pyanaconda import localization
> >
> > import re
> > @@ -34,14 +36,8 @@ log = logging.getLogger("anaconda")
> >
> > __all__ = ["LangsupportSpoke"]
> >
> > -COL_NATIVE_NAME = 0
> > -COL_ENGLISH_NAME = 1
> > -COL_LANG_SETTING = 2
> > -COL_SELECTED = 3
> > -COL_IS_ADDITIONAL = 4
> > -
> > class LangsupportSpoke(NormalSpoke):
> > - builderObjects = ["langsupportStore", "langsupportStoreFilter", "langsupportWindow"]
> > + builderObjects = ["languageStore", "languageStoreFilter", "localeStore", "langsupportWindow"]
> > mainWidgetName = "langsupportWindow"
> > uiFile = "spokes/langsupport.glade"
> >
> > @@ -52,60 +48,57 @@ class LangsupportSpoke(NormalSpoke):
> >
> > def __init__(self, *args, **kwargs):
> > NormalSpoke.__init__(self, *args, **kwargs)
> > + self._selected_locales = set()
> >
> > def initialize(self):
> > - self._langsupportStore = self.builder.get_object("langsupportStore")
> > - self._langsupportEntry = self.builder.get_object("langsupportEntry")
> > - self._langsupportStoreFilter = self.builder.get_object("langsupportStoreFilter")
> > - self._langsupportStoreFilter.set_visible_func(self._matches_entry, None)
> > -
> > - # mark selected items in language list bold
> > - for col, rend, idx in (("englishNameCol", "englishNameRenderer", COL_ENGLISH_NAME),
> > - ("nativeNameCol", "nativeNameRenderer", COL_NATIVE_NAME)):
> > + self._languageStore = self.builder.get_object("languageStore")
> > + self._languageEntry = self.builder.get_object("languageEntry")
> > + self._languageStoreFilter = self.builder.get_object("languageStoreFilter")
> > + self._languageStoreFilter.set_visible_func(self._matches_entry, None)
> > + self._langView = self.builder.get_object("languageView")
> > + self._langSelectedRenderer = self.builder.get_object("langSelectedRenderer")
> > + self._langSelectedColumn = self.builder.get_object("langSelectedColumn")
> > + self._langSelection = self.builder.get_object("languageViewSelection")
> > + self._localeStore = self.builder.get_object("localeStore")
> > + self._localeView = self.builder.get_object("localeView")
> > +
> > + # fill the list with available translations
> > + for lang in localization.get_available_translations():
> > + self._add_language(self._languageStore,
> > + localization.get_native_name(lang),
> > + localization.get_english_name(lang), lang)
> > +
> > + # render a right arrow for the chosen language
> > + self._right_arrow = Gtk.Image.new_from_file("/usr/share/anaconda/pixmaps/right-arrow-icon.png")
> > + self._langSelectedColumn.set_cell_data_func(self._langSelectedRenderer,
> > + self._render_lang_selected)
> > +
> > + # mark selected locales and languages with selected locales bold
> > + localeNativeColumn = self.builder.get_object("localeNativeName")
> > + localeNativeNameRenderer = self.builder.get_object("localeNativeNameRenderer")
> > + localeNativeColumn.set_cell_data_func(localeNativeNameRenderer,
> > + self._mark_selected_locale_bold)
> > +
> > + for col, rend in [("nativeName", "nativeNameRenderer"),
> > + ("englishName", "englishNameRenderer")]:
> > column = self.builder.get_object(col)
> > renderer = self.builder.get_object(rend)
> > - column.set_cell_data_func(renderer, self._mark_selected_bold, idx)
> > -
> > - # source of lang code <-> UI name mapping
> > - # (localization.get_available_translations() returns a generator)
> > - self.locale_infos_for_data = list(localization.get_available_translations())
> > - self.locale_infos_for_ui = self.locale_infos_for_data[:]
> > -
> > - for locale in sorted(self.locale_infos_for_ui):
> > - self._add_language(self._langsupportStore,
> > - localization.get_native_name(locale),
> > - localization.get_english_name(locale),
> > - locale,
> > - False, True)
> > -
> > - self._select_language(self._langsupportStore, self.data.lang.lang)
> > + column.set_cell_data_func(renderer, self._mark_selected_language_bold)
> >
> > def apply(self):
> > - self.data.lang.addsupport = [row[COL_LANG_SETTING]
> > - for row in self._langsupportStore
> > - if row[COL_SELECTED] and row[COL_IS_ADDITIONAL]]
> > + # store only additional langsupport locales
> > + self.data.lang.addsupport = list(sorted(self._selected_locales - set([self.data.lang.lang])))
> >
>
> The list constructor is not needed here.
Yeah, I've found out sorted() returns a list instead of generator while
I was writing those patches. Thanks!
>
>
> > def refresh(self):
> > - self._langsupportEntry.set_text("")
> > - lang_infos = self._find_localeinfos_for_code(self.data.lang.lang, self.locale_infos_for_ui)
> > - if len(lang_infos) > 1:
> > - log.warning("Found multiple locales for lang %s: %s, picking first",
> > - self.data.lang.lang, lang_infos)
> > - # Just take the first found
> > - # TODO - for corner cases choose the one that is common prefix
> > - lang_infos = lang_infos[:1]
> > -
> > - addsupp_infos = []
> > - for code in self.data.lang.addsupport:
> > - code_infos = self._find_localeinfos_for_code(code, self.locale_infos_for_ui)
> > - addsupp_infos.extend(code_infos)
> > -
> > - for row in self._langsupportStore:
> > - if row[COL_LANG_SETTING] in addsupp_infos:
> > - row[COL_SELECTED] = True
> > - if row[COL_LANG_SETTING] in lang_infos:
> > - row[COL_SELECTED] = True
> > - row[COL_IS_ADDITIONAL] = False
> > + self._languageEntry.set_text("")
> > + self._selected_locales = set(self._installed_langsupports)
> > +
> > + # select the first locale from the "to be installed" langsupports
> > + self._select_locale(self._installed_langsupports[0])
> > +
> > + @property
> > + def _installed_langsupports(self):
> > + return sorted(self.data.lang.addsupport + [self.data.lang.lang])
> >
> > @property
> > def showable(self):
> > @@ -113,13 +106,8 @@ class LangsupportSpoke(NormalSpoke):
> >
> > @property
> > def status(self):
> > - # TODO: translate
> > - infos = self._find_localeinfos_for_code(self.data.lang.lang, self.locale_infos_for_data)[:1]
> > - for code in self.data.lang.addsupport:
> > - for info in self._find_localeinfos_for_code(code, self.locale_infos_for_data):
> > - if info not in infos:
> > - infos.append(info)
> > - return ", ".join(localization.get_english_name(info) for info in infos)
> > + return ", ".join(localization.get_native_name(locale)
> > + for locale in self._installed_langsupports)
>
> IIRC, on proposal in a review I added a patch to keep data.lang.lang first,
> we might want to keep it.
okay, will change that.
>
> >
> > @property
> > def mandatory(self):
> > @@ -129,42 +117,64 @@ class LangsupportSpoke(NormalSpoke):
> > def completed(self):
> > return True
> >
> > - def _find_localeinfos_for_code(self, code, infos):
> > - if code in infos:
> > - return [code]
> > - else:
> > - retval = [info for info in infos
> > - if code in localization.expand_langs(info)]
> > - log.debug("locale infos found for %s: %s", code, retval)
> > - return retval
> > -
> > - def _add_language(self, store, native, english, setting, selected, additional):
> > - store.append(['<span lang="%s">%s</span>' % (re.sub(r'\..*', '', setting), native),
> > - english, setting, selected, additional])
> > -
> > - def _select_language(self, store, language):
> > - itr = store.get_iter_first()
> > - while itr and language not in localization.expand_langs(store[itr][COL_LANG_SETTING]):
> > - itr = store.iter_next(itr)
> > -
> > - # If we were provided with an unsupported language, just use the default.
> > - if not itr:
> > - return
> > -
> > - treeview = self.builder.get_object("langsupportView")
> > - selection = treeview.get_selection()
> > - selection.select_iter(itr)
> > - path = store.get_path(itr)
> > - treeview.scroll_to_cell(path)
> > + def _add_language(self, store, native, english, lang):
> > + native_span = '<span lang="%s">%s</span>' % (lang, native)
> > + store.append([native_span, english, lang])
> > +
> > + def _addLocale(self, store, native, locale):
> > + native_span = '<span lang="%s">%s</span>' % (re.sub(r'\..*', '', locale), native)
> > +
> > + # native, locale, selected, additional
> > + store.append([native_span, locale, locale in self._selected_locales,
> > + locale != self.data.lang.lang])
> > +
> > + def _refresh_locale_store(self, lang):
> > + """Refresh the localeStore with locales for the given language."""
> > +
> > + self._localeStore.clear()
> > + locales = localization.get_language_locales(lang)
> > + for locale in locales:
> > + self._addLocale(self._localeStore,
> > + localization.get_native_name(locale),
> > + locale)
> > +
> > + # select the first locale (with the highest rank)
> > + set_treeview_selection(self._localeView, locales[0], col=1)
> > +
> > + def _select_locale(self, locale):
> > + """
> > + Try to select the given locale in the language and locale
> > + treeviews. This method tries to find the best match for the given
> > + locale.
> > +
> > + :return: a pair of selected iterators (language and locale)
> > + :rtype: a pair of GtkTreeIter or None objects
> > +
> > + """
> > +
> > + # get lang and select it
> > + parts = localization.parse_langcode(locale)
> > + if "language" not in parts:
> > + # invalid locale, cannot select
> > + return (None, None)
> > +
> > + lang_itr = set_treeview_selection(self._langView, parts["language"], col=2)
> > + self._refresh_locale_store(parts["language"]) #XXX: needed?
> > +
> > + # find matches and use the one with the highest rank
> > + locales = localization.get_language_locales(locale)
> > + locale_itr = set_treeview_selection(self._localeView, locales[0], col=1)
> > +
> > + return (lang_itr, locale_itr)
> >
> > def _matches_entry(self, model, itr, *args):
> > # Need to strip out the pango markup before attempting to match.
> > # Otherwise, starting to type "span" for "spanish" will match everything
> > # due to the enclosing span tag.
> > # (success, attrs, native, accel)
> > - native = Pango.parse_markup(model[itr][COL_NATIVE_NAME], -1, "_")[2]
> > - english = model[itr][COL_ENGLISH_NAME]
> > - entry = self._langsupportEntry.get_text().strip()
> > + native = Pango.parse_markup(model[itr][0], -1, "_")[2]
> > + english = model[itr][1]
> > + entry = self._languageEntry.get_text().strip()
> >
> > # Nothing in the text entry? Display everything.
> > if not entry:
> > @@ -179,21 +189,53 @@ class LangsupportSpoke(NormalSpoke):
> > else:
> > return False
> >
> > - def _mark_selected_bold(self, column, renderer, model, itr, idx):
> > - value = model[itr][idx]
> > - if model[itr][COL_SELECTED]:
> > - value = "<b>%s</b>" % value
> > - renderer.set_property("markup", value)
> > + def _render_lang_selected(self, column, renderer, model, itr, user_data=None):
> > + (lang_store, sel_itr) = self._langSelection.get_selected()
> > +
> > + lang_locales = set(localization.get_language_locales(model[itr][2]))
> > + if sel_itr and lang_store[sel_itr][2] == model[itr][2]:
> > + renderer.set_property("pixbuf", self._right_arrow.get_pixbuf())
> > + else:
> > + renderer.set_property("pixbuf", None)
> > +
> > + def _mark_selected_locale_bold(self, column, renderer, model, itr, user_data=None):
> > + value = model[itr][0]
>
> value is unused
Good catch, thanks!
--
Vratislav Podzimek
Anaconda Rider | Red Hat, Inc. | Brno - Czech Republic
More information about the anaconda-patches
mailing list