[master][PATCH] Share code between the Welcome and Langsupport spokes

Vratislav Podzimek vpodzime at redhat.com
Thu Sep 5 09:17:44 UTC 2013


These two spokes do the same in a lot of places so they can share the code. It
doesn't in a lot of removed lines, but a lot of things will be fixed only at one
place instead of two in the future.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/ui/gui/spokes/langsupport.py            | 105 +-------------
 .../ui/gui/spokes/lib/lang_locale_handler.py       | 161 +++++++++++++++++++++
 pyanaconda/ui/gui/spokes/welcome.py                | 105 +-------------
 3 files changed, 173 insertions(+), 198 deletions(-)
 create mode 100644 pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py

diff --git a/pyanaconda/ui/gui/spokes/langsupport.py b/pyanaconda/ui/gui/spokes/langsupport.py
index 7f642d1..125e3b5 100644
--- a/pyanaconda/ui/gui/spokes/langsupport.py
+++ b/pyanaconda/ui/gui/spokes/langsupport.py
@@ -26,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.spokes.lib.lang_locale_handler import LangLocaleHandler
 from pyanaconda.ui.gui.utils import set_treeview_selection
 from pyanaconda import localization
 
@@ -36,7 +37,7 @@ log = logging.getLogger("anaconda")
 
 __all__ = ["LangsupportSpoke"]
 
-class LangsupportSpoke(NormalSpoke):
+class LangsupportSpoke(LangLocaleHandler, NormalSpoke):
     builderObjects = ["languageStore", "languageStoreFilter", "localeStore", "langsupportWindow"]
     mainWidgetName = "langsupportWindow"
     uiFile = "spokes/langsupport.glade"
@@ -61,16 +62,7 @@ class LangsupportSpoke(NormalSpoke):
         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)
+        LangLocaleHandler.initialize(self)
 
         # mark selected locales and languages with selected locales bold
         localeNativeColumn = self.builder.get_object("localeNativeName")
@@ -84,9 +76,6 @@ class LangsupportSpoke(NormalSpoke):
             renderer = self.builder.get_object(rend)
             column.set_cell_data_func(renderer, self._mark_selected_language_bold)
 
-        # make filtering work
-        self._languageStoreFilter.set_visible_func(self._matches_entry, None)
-
     def apply(self):
         # store only additional langsupport locales
         self.data.lang.addsupport = sorted(self._selected_locales - set([self.data.lang.lang]))
@@ -123,83 +112,13 @@ class LangsupportSpoke(NormalSpoke):
         native_span = '<span lang="%s">%s</span>' % (lang, native)
         store.append([native_span, english, lang])
 
-    def _addLocale(self, store, native, locale):
+    def _add_locale(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][0], -1, "_")[2]
-        english = model[itr][1]
-        entry = self._languageEntry.get_text().strip()
-
-        # Nothing in the text entry?  Display everything.
-        if not entry:
-            return True
-
-        # Otherwise, filter the list showing only what is matched by the
-        # text entry.  Either the English or native names can match.
-        lowered = entry.lower()
-        translit = strip_accents(unicode(native, "utf-8")).lower()
-        if lowered in native.lower() or lowered in english.lower() or lowered in translit:
-            return True
-        else:
-            return False
-
-    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):
         if model[itr][2]:
             renderer.set_property("weight", Pango.Weight.BOLD.real)
@@ -214,15 +133,6 @@ class LangsupportSpoke(NormalSpoke):
             renderer.set_property("weight", Pango.Weight.NORMAL.real)
 
     # Signal handlers.
-    def on_lang_selection_changed(self, selection):
-        (store, selected) = selection.get_selected_rows()
-
-        if selected:
-            lang = store[selected[0]][2]
-            self._refresh_locale_store(lang)
-        else:
-            self._localeStore.clear()
-
     def on_locale_toggled(self, renderer, path):
         itr = self._localeStore.get_iter(path)
         row = self._localeStore[itr]
@@ -233,10 +143,3 @@ class LangsupportSpoke(NormalSpoke):
             self._selected_locales.add(row[1])
         else:
             self._selected_locales.remove(row[1])
-
-    def on_clear_icon_clicked(self, entry, icon_pos, event):
-        if icon_pos == Gtk.EntryIconPosition.SECONDARY:
-            entry.set_text("")
-
-    def on_entry_changed(self, *args):
-        self._languageStoreFilter.refilter()
diff --git a/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py b/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py
new file mode 100644
index 0000000..dea6bef
--- /dev/null
+++ b/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py
@@ -0,0 +1,161 @@
+#
+# Copyright (C) 2011-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): Vratislav Podzimek <vpodzime at redhat.com>
+#
+
+"""
+Module providing the LangLocaleHandler class that could be used as a mixin for
+screens handling languages or locales configuration.
+
+"""
+
+from gi.repository import Gtk, Pango
+from pyanaconda import localization
+from pyanaconda.iutil import strip_accents
+from pyanaconda.ui.gui.utils import set_treeview_selection
+
+class LangLocaleHandler(object):
+    """
+    Class that could be used as a mixin for screens handling languages or
+    locales configuration.
+
+    """
+
+    def __init__(self):
+        # the class inheriting from this class is responsible for populating
+        # these items with actual objects
+        self._languageStore = None
+        self._languageStoreFilter = None
+        self._languageEntry = None
+        self._langSelection = None
+        self._langSelectedRenderer = None
+        self._langSelectedColumn = None
+        self._langView = None
+        self._localeView = None
+        self._localeStore = None
+        self._localeSelection = None
+
+    def initialize(self):
+        # 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)
+
+        # 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)
+
+        # make filtering work
+        self._languageStoreFilter.set_visible_func(self._matches_entry, None)
+
+    def _matches_entry(self, model, itr, *args):
+        # Nothing in the text entry?  Display everything.
+        entry = self._languageEntry.get_text().strip()
+        if not entry:
+            return True
+
+        # 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][0], -1, "_")[2]
+        english = model[itr][1]
+
+        # Otherwise, filter the list showing only what is matched by the
+        # text entry.  Either the English or native names can match.
+        lowered = entry.lower()
+        translit = strip_accents(unicode(native, "utf-8")).lower()
+        if lowered in native.lower() or lowered in english.lower() or lowered in translit:
+            return True
+        else:
+            return False
+
+    def _render_lang_selected(self, column, renderer, model, itr, user_data=None):
+        (lang_store, sel_itr) = self._langSelection.get_selected()
+
+        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 _add_language(self, store, native, english, lang):
+        """Override this method with a valid implementation"""
+
+        raise NotImplementedError()
+
+    def _add_locale(self, store, native, locale):
+        """Override this method with a valid implementation"""
+
+        raise NotImplementedError()
+
+    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)
+
+        # 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 _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._add_locale(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 on_lang_selection_changed(self, selection):
+        (store, selected) = selection.get_selected_rows()
+
+        if selected:
+            lang = store[selected[0]][2]
+            self._refresh_locale_store(lang)
+        else:
+            self._localeStore.clear()
+
+    def on_clear_icon_clicked(self, entry, icon_pos, event):
+        if icon_pos == Gtk.EntryIconPosition.SECONDARY:
+            entry.set_text("")
+
+    def on_entry_changed(self, *args):
+        self._languageStoreFilter.refilter()
+
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 5bd8c8a..80af8d8 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -28,6 +28,7 @@ from gi.repository import Gtk, Pango
 from pyanaconda.ui.gui.hubs.summary import SummaryHub
 from pyanaconda.ui.gui.spokes import StandaloneSpoke
 from pyanaconda.ui.gui.utils import enlightbox, set_treeview_selection
+from pyanaconda.ui.gui.spokes.lib.lang_locale_handler import LangLocaleHandler
 
 from pyanaconda import localization
 from pyanaconda.product import distributionText, isFinal, productName, productVersion
@@ -43,7 +44,7 @@ log = logging.getLogger("anaconda")
 
 __all__ = ["WelcomeLanguageSpoke"]
 
-class WelcomeLanguageSpoke(StandaloneSpoke):
+class WelcomeLanguageSpoke(LangLocaleHandler, StandaloneSpoke):
     mainWidgetName = "welcomeWindow"
     uiFile = "spokes/welcome.glade"
     builderObjects = ["languageStore", "languageStoreFilter", "localeStore",
@@ -143,14 +144,6 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
     def _row_is_separator(self, model, itr, *args):
         return model[itr][3]
 
-    def _render_lang_selected(self, column, renderer, model, itr, user_data=None):
-        (lang_store, sel_itr) = self._langSelection.get_selected()
-
-        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 initialize(self):
         self._languageStore = self.builder.get_object("languageStore")
         self._languageStoreFilter = self.builder.get_object("languageStoreFilter")
@@ -163,14 +156,11 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
         self._localeStore = self.builder.get_object("localeStore")
         self._localeSelection = self.builder.get_object("localeViewSelection")
 
+        LangLocaleHandler.initialize(self)
+
         # We need to tell the view whether something is a separator or not.
         self._langView.set_row_separator_func(self._row_is_separator, None)
 
-        # 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)
-
         # We can use the territory from geolocation here
         # to preselect the translation, when it's available.
         territory = geoloc.get_territory_code(wait=True)
@@ -181,12 +171,6 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
             # kickstart/command line
             localization.setup_locale(locales[0], self.data.lang)
 
-        # fill the list with available translations
-        for lang in localization.get_available_translations():
-            self._addLanguage(self._languageStore,
-                              localization.get_native_name(lang),
-                              localization.get_english_name(lang), lang)
-
         # Move the default language (whatever was provided on the command line,
         # or by kickstart, or by geoip, or English if nothing else) to the top
         # of the list and select it by default.  People find it confusing to be
@@ -210,8 +194,6 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
         newItr = store.insert(1)
         store.set(newItr, 0, "", 1, "", 2, "", 3, True)
 
-        self._languageStoreFilter.set_visible_func(self._matchesEntry, None)
-
     def _retranslate_one(self, widgetName):
         widget = self.builder.get_object(widgetName)
         if not widget:
@@ -251,85 +233,21 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
         self._languageEntry.set_text("")
         self._languageStoreFilter.refilter()
 
-    def _addLanguage(self, store, native, english, lang):
+    def _add_language(self, store, native, english, lang):
         native_span = '<span lang="%s">%s</span>' % (lang, native)
         store.append([native_span, english, lang, False])
 
-    def _addLocale(self, store, native, locale):
+    def _add_locale(self, store, native, locale):
         native_span = '<span lang="%s">%s</span>' % (re.sub(r'\..*', '', locale), native)
         store.append([native_span, locale])
 
-    def _matchesEntry(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][0], -1, "_")[2]
-        english = model[itr][1]
-        entry = self._languageEntry.get_text().strip()
-
-        # Nothing in the text entry?  Display everything.
-        if not entry:
-            return True
-
-        # Otherwise, filter the list showing only what is matched by the
-        # text entry.  Either the English or native names can match.
-        lowered = entry.lower()
-        translit = strip_accents(unicode(native, "utf-8")).lower()
-        if lowered in native.lower() or lowered in english.lower() or lowered in translit:
-            return True
-        else:
-            return False
-
-    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)
-
-        # 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 _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)
-
     # Signal handlers.
     def on_lang_selection_changed(self, selection):
         (store, selected) = selection.get_selected_rows()
+        LangLocaleHandler.on_lang_selection_changed(self, selection)
 
-        if selected:
-            lang = store[selected[0]][2]
-            self._refresh_locale_store(lang)
-        else:
-            if hasattr(self.window, "set_may_continue"):
+        if not selected and hasattr(self.window, "set_may_continue"):
                 self.window.set_may_continue(False)
-            self._localeStore.clear()
 
     def on_locale_selection_changed(self, selection):
         (store, selected) = selection.get_selected_rows()
@@ -341,13 +259,6 @@ class WelcomeLanguageSpoke(StandaloneSpoke):
             localization.setup_locale(lang)
             self.retranslate(lang)
 
-    def on_clear_icon_clicked(self, entry, icon_pos, event):
-        if icon_pos == Gtk.EntryIconPosition.SECONDARY:
-            entry.set_text("")
-
-    def on_entry_changed(self, *args):
-        self._languageStoreFilter.refilter()
-
     # Override the default in StandaloneSpoke so we can display the beta
     # warning dialog first.
     def _on_continue_clicked(self, cb):
-- 
1.7.11.7



More information about the anaconda-patches mailing list