[PATCH 2/2] Provide our own sorting functions for regions and timezones (#1025029)

Vratislav Podzimek vpodzime at redhat.com
Thu Jan 9 13:22:22 UTC 2014


We want to put the Etc region to the end of the list and sort GMT+-X zones
numerically. Also, instead of letting Gtk sort cities and regions multiple
times, we can sort them in advance only once.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/ui/gui/spokes/datetime_spoke.glade |  7 +--
 pyanaconda/ui/gui/spokes/datetime_spoke.py    | 83 ++++++++++++++++++++++-----
 2 files changed, 71 insertions(+), 19 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.glade b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
index c5eb61f..fa23d95 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.glade
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
@@ -30,16 +30,13 @@
     </columns>
   </object>
   <object class="GtkEntryCompletion" id="cityCompletion">
-    <property name="model">citiesSort</property>
+    <property name="model">citiesFilter</property>
     <property name="text_column">0</property>
     <signal name="match-selected" handler="on_completion_match_selected" object="cityCombobox" swapped="no"/>
   </object>
   <object class="GtkTreeModelFilter" id="citiesFilter">
     <property name="child_model">cities</property>
   </object>
-  <object class="GtkTreeModelSort" id="citiesSort">
-    <property name="model">citiesFilter</property>
-  </object>
   <object class="AnacondaSpokeWindow" id="datetimeWindow">
     <property name="startup_id">filler</property>
     <property name="can_focus">False</property>
@@ -148,7 +145,7 @@
                               <object class="GtkComboBox" id="cityCombobox">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="model">citiesSort</property>
+                                <property name="model">citiesFilter</property>
                                 <property name="has_entry">True</property>
                                 <property name="entry_text_column">1</property>
                                 <signal name="changed" handler="on_city_changed" object="citiesEntry" swapped="no"/>
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index 6d747d3..2ad9f95 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -35,18 +35,20 @@ from pyanaconda.ui.gui.utils import enlightbox, gtk_action_nowait, gtk_action_wa
 from pyanaconda.i18n import _, N_
 from pyanaconda import timezone
 from pyanaconda.timezone import NTP_SERVICE
+from pyanaconda.localization import get_xlated_timezone
 from pyanaconda import iutil
 from pyanaconda import network
 from pyanaconda import nm
 from pyanaconda import ntp
 from pyanaconda import flags
 from pyanaconda import constants
-from pyanaconda import localization
 from pyanaconda.threads import threadMgr, AnacondaThread
 
 import datetime
 import os
+import re
 import threading
+import locale as locale_mod
 
 __all__ = ["DatetimeSpoke"]
 
@@ -57,6 +59,59 @@ SERVER_QUERY = 2
 DEFAULT_TZ = "America/New_York"
 
 POOL_SERVERS_NOTE = N_("Note: pool servers may not be available all the time")
+SPLIT_NUMBER_SUFFIX_RE = re.compile(r'([^0-9]*)([-+])([0-9]+)')
+
+def _compare_regions(reg_xlated1, reg_xlated2):
+    """Compare two pairs of regions and their translations."""
+
+    reg1, xlated1 = reg_xlated1
+    reg2, xlated2 = reg_xlated2
+
+    # sort the Etc timezones to the end
+    if reg1 == "Etc" and reg2 == "Etc":
+        return 0
+    elif reg1 == "Etc":
+        return 1
+    elif reg2 == "Etc":
+        return -1
+    else:
+        # otherwise compare the translated names
+        return locale_mod.strcoll(xlated1, xlated2)
+
+def _compare_cities(city_xlated1, city_xlated2):
+    """Compare two paris of cities and their translations."""
+
+    # if there are "cities" ending with numbers (like GMT+-X), we need to sort
+    # them based on their numbers
+    val1 = city_xlated1[1]
+    val2 = city_xlated2[1]
+
+    match1 = SPLIT_NUMBER_SUFFIX_RE.match(val1)
+    match2 = SPLIT_NUMBER_SUFFIX_RE.match(val2)
+
+    if match1 is None and match2 is None:
+        # no +-X suffix, just compare the strings
+        return locale_mod.strcoll(val1, val2)
+
+    if match1 is None or match2 is None:
+        # one with the +-X suffix, compare the prefixes
+        if match1:
+            prefix, _sign, _suffix = match1.groups()
+            return locale_mod.strcoll(prefix, val2)
+        else:
+            prefix, _sign, _suffix = match2.groups()
+            return locale_mod.strcoll(val1, prefix)
+
+    # both have the +-X suffix
+    prefix1, sign1, suffix1 = match1.groups()
+    prefix2, sign2, suffix2 = match2.groups()
+
+    if prefix1 == prefix2:
+        # same prefixes, let signs determine
+        return cmp(int(sign1 + suffix1), int(sign2 + suffix2))
+    else:
+        # compare prefixes
+        return locale_mod.strcoll(prefix1, prefix2)
 
 class NTPconfigDialog(GUIObject):
     builderObjects = ["ntpConfigDialog", "addImage", "serversStore"]
@@ -287,8 +342,7 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
                       "days", "months", "years", "regions", "cities",
                       "upImage", "upImage1", "upImage2", "downImage",
                       "downImage1", "downImage2", "downImage3", "configImage",
-                      "citiesFilter", "daysFilter", "citiesSort", "regionsSort",
-                      "cityCompletion", "regionCompletion",
+                      "citiesFilter", "daysFilter", "regionCompletion",
                       ]
 
     mainWidgetName = "datetimeWindow"
@@ -330,9 +384,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
         self._citiesFilter = self.builder.get_object("citiesFilter")
         self._citiesFilter.set_visible_func(self.city_in_region, None)
 
-        self._citiesSort = self.builder.get_object("citiesSort")
-        self._citiesSort.set_sort_column_id(1, Gtk.SortType.ASCENDING)
-
         self._hoursLabel = self.builder.get_object("hoursLabel")
         self._minutesLabel = self.builder.get_object("minutesLabel")
         self._amPmUp = self.builder.get_object("amPmUpButton")
@@ -362,10 +413,16 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
         for year in xrange(1990, 2051):
             self.add_to_store(self._yearsStore, year)
 
-        for region in self._regions_zones.keys():
-            self.add_to_store_xlated(self._regionsStore, region)
+        cities = set()
+        xlated_regions = ((region, get_xlated_timezone(region))
+                          for region in self._regions_zones.iterkeys())
+        for region, xlated in sorted(xlated_regions, cmp=_compare_regions):
+            self.add_to_store_xlated(self._regionsStore, region, xlated)
             for city in self._regions_zones[region]:
-                self.add_to_store_xlated(self._citiesStore, city)
+                cities.add((city, get_xlated_timezone(city)))
+
+        for city, xlated in sorted(cities, cmp=_compare_cities):
+            self.add_to_store_xlated(self._citiesStore, city, xlated)
 
         if self._radioButton24h.get_active():
             self._set_amPm_part_sensitive(False)
@@ -397,11 +454,11 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
     def status(self):
         if self.data.timezone.timezone:
             if timezone.is_valid_timezone(self.data.timezone.timezone):
-                return _("%s timezone") % localization.get_xlated_timezone(self.data.timezone.timezone)
+                return _("%s timezone") % get_xlated_timezone(self.data.timezone.timezone)
             else:
                 return _("Invalid timezone")
         elif self._tzmap.get_timezone():
-            return _("%s timezone") % localization.get_xlated_timezone(self._tzmap.get_timezone())
+            return _("%s timezone") % get_xlated_timezone(self._tzmap.get_timezone())
         else:
             return _("Nothing selected")
 
@@ -497,8 +554,7 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
         return True
 
     @gtk_action_nowait
-    def add_to_store_xlated(self, store, item):
-        xlated = localization.get_xlated_timezone(item)
+    def add_to_store_xlated(self, store, item, xlated):
         store.append([item, xlated])
 
     @gtk_action_nowait
@@ -862,7 +918,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
     def on_city_region_text_entry_activated(self, entry):
         combo = entry.get_parent()
         model = combo.get_model()
-        itr = model.get_iter_first()
         entry_text = entry.get_text().lower()
 
         for row in model:
-- 
1.8.4.2



More information about the anaconda-patches mailing list