[master/rhel7 1/2] Add a wrapper function for GtkTreeViewColumn.set_cell_data_func

David Shea dshea at redhat.com
Wed Jul 30 17:46:12 UTC 2014


This method makes it easier to override more than one property on a
particular column, or to add properties to a column that has already
been modified by a different method.

Related: rhbz#1072355
---
 pyanaconda/ui/gui/spokes/datetime_spoke.py         | 12 ++++----
 pyanaconda/ui/gui/spokes/keyboard.py               | 15 +++++-----
 pyanaconda/ui/gui/spokes/langsupport.py            | 16 +++++-----
 .../ui/gui/spokes/lib/lang_locale_handler.py       | 10 +++----
 pyanaconda/ui/gui/utils.py                         | 34 ++++++++++++++++++++++
 5 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index 103338c..a74175f 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -30,7 +30,8 @@ from pyanaconda.ui.common import FirstbootSpokeMixIn
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.categories.localization import LocalizationCategory
-from pyanaconda.ui.gui.utils import enlightbox, gtk_action_nowait, gtk_action_wait, gtk_call_once
+from pyanaconda.ui.gui.utils import enlightbox, gtk_action_nowait, gtk_action_wait, gtk_call_once,\
+        override_cell_property
 
 from pyanaconda.i18n import _, N_
 from pyanaconda import timezone
@@ -153,18 +154,19 @@ class NTPconfigDialog(GUIObject):
         value = model[itr][1]
 
         if value == SERVER_QUERY:
-            renderer.set_property("stock-id", "gtk-dialog-question")
+            return "gtk-dialog-question"
         elif value == SERVER_OK:
-            renderer.set_property("stock-id", "gtk-yes")
+            return "gtk-yes"
         else:
-            renderer.set_property("stock-id", "gtk-no")
+            return "gtk-no"
 
     def initialize(self):
         self.window.set_size_request(500, 400)
 
         workingColumn = self.builder.get_object("workingColumn")
         workingRenderer = self.builder.get_object("workingRenderer")
-        workingColumn.set_cell_data_func(workingRenderer, self._render_working)
+        override_cell_property(workingColumn, workingRenderer, "icon-name",
+                self._render_working)
 
         self._serverEntry = self.builder.get_object("serverEntry")
         self._serversStore = self.builder.get_object("serversStore")
diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index 690a7b0..2c81f01 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -26,7 +26,7 @@ from gi.repository import GLib, Gkbd, Gtk, Gdk
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.categories.localization import LocalizationCategory
-from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once
+from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, override_cell_property
 from pyanaconda import keyboard
 from pyanaconda import flags
 from pyanaconda.i18n import _, N_
@@ -40,14 +40,13 @@ __all__ = ["KeyboardSpoke"]
 LAYOUT_SWITCHING_INFO = N_("%s to switch layouts.")
 
 def _show_layout(column, renderer, model, itr, wrapper):
-    value = wrapper.get_layout_variant_description(model[itr][0])
-    renderer.set_property("text", value)
+    return wrapper.get_layout_variant_description(model[itr][0])
 
 def _show_description(column, renderer, model, itr, wrapper):
     value = wrapper.get_switch_opt_description(model[itr][0])
     if model[itr][1]:
         value = "<b>%s</b>" % value
-    renderer.set_property("markup", value)
+    return value
 
 class AddLayoutDialog(GUIObject):
     builderObjects = ["addLayoutDialog", "newLayoutStore",
@@ -106,8 +105,8 @@ class AddLayoutDialog(GUIObject):
         self._entry = self.builder.get_object("addLayoutEntry")
         layoutColumn = self.builder.get_object("newLayoutColumn")
         layoutRenderer = self.builder.get_object("newLayoutRenderer")
-        layoutColumn.set_cell_data_func(layoutRenderer, _show_layout,
-                                            self._xkl_wrapper)
+        override_cell_property(layoutColumn, layoutRenderer, "text", _show_layout,
+                               self._xkl_wrapper)
         self._treeModelFilter = self.builder.get_object("newLayoutStoreFilter")
         self._treeModelFilter.set_visible_func(self.matches_entry, None)
         self._treeModelSort = self.builder.get_object("newLayoutStoreSort")
@@ -184,7 +183,7 @@ class ConfigureSwitchingDialog(GUIObject):
         # we want to display "Alt + Shift" rather than "grp:alt_shift_toggle"
         descColumn = self.builder.get_object("descColumn")
         descRenderer = self.builder.get_object("descRenderer")
-        descColumn.set_cell_data_func(descRenderer, _show_description,
+        override_cell_property(descColumn, descRenderer, "markup", _show_description,
                                             self._xkl_wrapper)
 
         self._switchingOptsSort = self.builder.get_object("switchingOptsSort")
@@ -300,7 +299,7 @@ class KeyboardSpoke(NormalSpoke):
         # 'language (description)'.
         layoutColumn = self.builder.get_object("layoutColumn")
         layoutRenderer = self.builder.get_object("layoutRenderer")
-        layoutColumn.set_cell_data_func(layoutRenderer, _show_layout,
+        override_cell_property(layoutColumn, layoutRenderer, "text", _show_layout,
                                             self._xkl_wrapper)
 
         self._store = self.builder.get_object("addedLayoutStore")
diff --git a/pyanaconda/ui/gui/spokes/langsupport.py b/pyanaconda/ui/gui/spokes/langsupport.py
index 85b84f7..4625168 100644
--- a/pyanaconda/ui/gui/spokes/langsupport.py
+++ b/pyanaconda/ui/gui/spokes/langsupport.py
@@ -28,7 +28,7 @@ from pyanaconda.iutil import strip_accents
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.spokes.lib.lang_locale_handler import LangLocaleHandler
 from pyanaconda.ui.gui.categories.localization import LocalizationCategory
-from pyanaconda.ui.gui.utils import set_treeview_selection
+from pyanaconda.ui.gui.utils import set_treeview_selection, override_cell_property
 from pyanaconda import localization
 
 import re
@@ -69,14 +69,14 @@ class LangsupportSpoke(LangLocaleHandler, NormalSpoke):
         # 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)
+        override_cell_property(localeNativeColumn, localeNativeNameRenderer,
+                "weight", 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_language_bold)
+            override_cell_property(column, renderer, "weight", self._mark_selected_language_bold)
 
     def apply(self):
         # store only additional langsupport locales
@@ -123,16 +123,16 @@ class LangsupportSpoke(LangLocaleHandler, NormalSpoke):
 
     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)
+            return Pango.Weight.BOLD.real
         else:
-            renderer.set_property("weight", Pango.Weight.NORMAL.real)
+            return Pango.Weight.NORMAL.real
 
     def _mark_selected_language_bold(self, column, renderer, model, itr, user_data=None):
         lang_locales = set(localization.get_language_locales(model[itr][2]))
         if not lang_locales.isdisjoint(self._selected_locales):
-            renderer.set_property("weight", Pango.Weight.BOLD.real)
+            return Pango.Weight.BOLD.real
         else:
-            renderer.set_property("weight", Pango.Weight.NORMAL.real)
+            return Pango.Weight.NORMAL.real
 
     # Signal handlers.
     def on_locale_toggled(self, renderer, path):
diff --git a/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py b/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py
index dea6bef..36b5828 100644
--- a/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py
+++ b/pyanaconda/ui/gui/spokes/lib/lang_locale_handler.py
@@ -27,7 +27,7 @@ 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
+from pyanaconda.ui.gui.utils import set_treeview_selection, override_cell_property
 
 class LangLocaleHandler(object):
     """
@@ -53,8 +53,8 @@ class LangLocaleHandler(object):
     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)
+        override_cell_property(self._langSelectedColumn, self._langSelectedRenderer,
+                               "pixbuf", self._render_lang_selected)
 
         # fill the list with available translations
         for lang in localization.get_available_translations():
@@ -91,9 +91,9 @@ class LangLocaleHandler(object):
         (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())
+            return self._right_arrow.get_pixbuf()
         else:
-            renderer.set_property("pixbuf", None)
+            return None
 
     def _add_language(self, store, native, english, lang):
         """Override this method with a valid implementation"""
diff --git a/pyanaconda/ui/gui/utils.py b/pyanaconda/ui/gui/utils.py
index 4456ab1..d62f0ec 100644
--- a/pyanaconda/ui/gui/utils.py
+++ b/pyanaconda/ui/gui/utils.py
@@ -193,3 +193,37 @@ def set_treeview_selection(treeview, item, col=0):
     treeview.scroll_to_cell(path, use_align=True, row_align=0.5)
 
     return itr
+
+# This will be populated by override_cell_property. Keys are tuples of (column, renderer).
+# Values are a dict of the form {property-name: (property-func, property-data)}.
+_override_cell_property_map = {}
+def override_cell_property(tree_column, cell_renderer, propname, property_func, data=None):
+    """
+    Override a single property of a cell renderer.
+
+    property_func takes the same arguments as GtkTreeCellDataFunc:
+    (TreeViewColumn, CellRenderer, TreeModel, TreeIter, data). Instead of being
+    expected to manipulate the CellRenderer itself, this method should instead
+    return the value to which the property should be set.
+
+    This method calls set_cell_data_func on the column and renderer.
+
+    :param GtkTreeViewColumn column: the column to override
+    :param GtkCellRenderer cell_renderer: the cell renderer to override
+    :param str propname: the property to set on the renderer
+    :param function property_func: a function that returns the value of the property to set
+    :param data: Optional data to pass to property_func
+    """
+
+    def _cell_data_func(tree_column, cell_renderer, tree_model, tree_iter, _data=None):
+        overrides = _override_cell_property_map[(tree_column, cell_renderer)]
+        for property_name in overrides:
+            property_func, property_func_data = overrides[property_name]
+            cell_renderer.set_property(property_name,
+                    property_func(tree_column, cell_renderer, tree_model, tree_iter, property_func_data))
+
+    if (tree_column, cell_renderer) not in _override_cell_property_map:
+        _override_cell_property_map[(tree_column, cell_renderer)] = {}
+        tree_column.set_cell_data_func(cell_renderer, _cell_data_func)
+
+    _override_cell_property_map[(tree_column, cell_renderer)][propname] = (property_func, data)
-- 
2.0.0



More information about the anaconda-patches mailing list