Consolidated the find callbacks
[gonvert] / src / gonvert_glade.py
index 2d13136..a35e519 100755 (executable)
@@ -4,7 +4,6 @@
 import os
 import pickle
 import string
-import sys
 import gettext
 import logging
 
@@ -122,6 +121,13 @@ class Gonvert(object):
                self._unitSymbolColumn.connect("clicked", self._on_click_unit_column)
                self._unitsView.append_column(self._unitSymbolColumn)
 
+               self._unitModel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+               self._sortedUnitModel = gtk.TreeModelSort(self._unitModel)
+               columns = self._get_column_sort_stuff()
+               for columnIndex, (column, sortDirection, col_cmp) in enumerate(columns):
+                       self._sortedUnitModel.set_sort_func(columnIndex, col_cmp)
+               self._unitsView.set_model(self._sortedUnitModel)
+
                #Insert a column into the category list even though the heading will not be seen
                renderer = gtk.CellRendererText()
                self._categoryColumn = gtk.TreeViewColumn('Title', renderer)
@@ -144,7 +150,6 @@ class Gonvert(object):
                        "on_exit_menu_activate": self._on_user_exit,
                        "on_main_window_destroy": self._on_user_exit,
                        "on_categoryView_select_row": self._on_click_category,
-                       "on_unitsView__on_click_unit_column": self._on_click_unit_column,
                        "on_unitValue_changed": self._on_unit_value_changed,
                        "on_previousUnitValue_changed": self._on_previous_unit_value_changed,
                        "on_writeUnitsMenuItem_activate": self._on_user_write_units,
@@ -155,7 +160,6 @@ class Gonvert(object):
                        "on_messagebox_ok_clicked": self.messagebox_ok_clicked,
                        "on_clearSelectionMenuItem_activate": self._on_user_clear_selections,
                        "on_unitsView_cursor_changed": self._on_click_unit,
-                       "on_unitsView_button_released": self._on_button_released,
                        "on_shortlistcheck_toggled": self._on_shortlist_changed,
                        "on_toggleShortList_activate": self._on_edit_shortlist,
                }
@@ -300,15 +304,6 @@ class Gonvert(object):
                        self._find_result[self._find_count][3], self._unitNameColumn, True
                )
 
-       def _on_findEntry_changed(self, *args):
-               """
-               Clear out find results since the user wants to look for something new
-               """
-               try:
-                       self._clear_find()
-               except Exception:
-                       _moduleLogger.exception()
-
        def _on_shortlist_changed(self, *args):
                try:
                        raise NotImplementedError("%s" % self._shortlistcheck.get_active())
@@ -329,6 +324,15 @@ class Gonvert(object):
                except Exception:
                        _moduleLogger.exception()
 
+       def _on_findEntry_changed(self, *args):
+               """
+               Clear out find results since the user wants to look for something new
+               """
+               try:
+                       self._clear_find()
+               except Exception:
+                       _moduleLogger.exception()
+
        def _on_find_activate(self, a):
                """
                check if 'new find' or 'last find' or 'next-find'
@@ -361,126 +365,66 @@ class Gonvert(object):
                except Exception:
                        _moduleLogger.exception()
 
+       def _unit_model_cmp(self, sortedModel, leftItr, rightItr):
+               leftUnitText = self._unitModel.get_value(leftItr, 0)
+               rightUnitText = self._unitModel.get_value(rightItr, 0)
+               return cmp(leftUnitText, rightUnitText)
+
+       def _symbol_model_cmp(self, sortedModel, leftItr, rightItr):
+               leftSymbolText = self._unitModel.get_value(leftItr, 2)
+               rightSymbolText = self._unitModel.get_value(rightItr, 2)
+               return cmp(leftSymbolText, rightSymbolText)
+
+       def _value_model_cmp(self, sortedModel, leftItr, rightItr):
+               #special sorting exceptions for ascii values (instead of float values)
+               if self._selected_category == "Computer Numbers":
+                       leftValue = self._unitModel.get_value(leftItr, 1)
+                       rightValue = self._unitModel.get_value(rightItr, 1)
+               else:
+                       leftValueText = self._unitModel.get_value(leftItr, 1)
+                       leftValue = float(leftValueText) if leftValueText else 0.0
+
+                       rightValueText = self._unitModel.get_value(rightItr, 1)
+                       rightValue = float(rightValueText) if rightValueText else 0.0
+               return cmp(leftValue, rightValue)
+
+       def _get_column_sort_stuff(self):
+               columns = (
+                       (self._unitNameColumn, "_unit_sort_direction", self._unit_model_cmp),
+                       (self._unitValueColumn, "_value_sort_direction", self._value_model_cmp),
+                       (self._unitSymbolColumn, "_units_sort_direction", self._symbol_model_cmp),
+               )
+               return columns
+
        def _on_click_unit_column(self, col):
                """
                Sort the contents of the col when the user clicks on the title.
                """
-               #Determine which column requires sorting
-               if col is self._unitNameColumn:
-                       selectedUnitColumn = 0
-                       self._unitNameColumn.set_sort_indicator(True)
-                       self._unitValueColumn.set_sort_indicator(False)
-                       self._unitSymbolColumn.set_sort_indicator(False)
-                       self._unitNameColumn.set_sort_order(not self._unit_sort_direction)
-               elif col is self._unitValueColumn:
-                       selectedUnitColumn = 1
-                       self._unitNameColumn.set_sort_indicator(False)
-                       self._unitValueColumn.set_sort_indicator(True)
-                       self._unitSymbolColumn.set_sort_indicator(False)
-                       self._unitValueColumn.set_sort_order(not self._value_sort_direction)
-               elif col is self._unitSymbolColumn:
-                       selectedUnitColumn = 2
-                       self._unitNameColumn.set_sort_indicator(False)
-                       self._unitValueColumn.set_sort_indicator(False)
-                       self._unitSymbolColumn.set_sort_indicator(True)
-                       self._unitSymbolColumn.set_sort_order(not self._units_sort_direction)
-               else:
-                       assert False, "Unknown column: %s" % (col.get_title(), )
-
-               #declare a spot to hold the sorted list
-               sorted_list = []
-
-               #point to the first row
-               iter = self._unitModel.get_iter_first()
-               row = 0
-
-               while iter:
-                       #grab all text from columns for sorting
-
-                       #get the text from each column
-                       unit_text = self._unitModel.get_value(iter, 0)
-                       units_text = self._unitModel.get_value(iter, 2)
-
-                       #do not bother sorting if the value column is empty
-                       if self._unitModel.get_value(iter, 1) == '' and selectedUnitColumn == 1:
-                               return
-
-                       #special sorting exceptions for ascii values (instead of float values)
-                       if self._selected_category == "Computer Numbers":
-                               value_text = self._unitModel.get_value(iter, 1)
-                       else:
-                               if self._unitModel.get_value(iter, 1) == None or self._unitModel.get_value(iter, 1) == '':
-                                       value_text = ''
-                               else:
-                                       value_text = float(self._unitModel.get_value(iter, 1))
-
-                       if selectedUnitColumn == 0:
-                               sorted_list.append((unit_text, value_text, units_text))
-                       elif selectedUnitColumn == 1:
-                               sorted_list.append((value_text, unit_text, units_text))
-                       else:
-                               sorted_list.append((units_text, value_text, unit_text))
-
-                       #point to the next row in the self._unitModel
-                       iter = self._unitModel.iter_next(iter)
-                       row = row+1
-
-               #check if no calculations have been made yet (don't bother sorting)
-               if row == 0:
-                       return
-               else:
-                       if selectedUnitColumn == 0:
-                               if not self._unit_sort_direction:
-                                       sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(x), string.lower(y)))
-                                       self._unit_sort_direction = True
-                               else:
-                                       sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(y), string.lower(x)))
-                                       self._unit_sort_direction = False
-                       elif selectedUnitColumn == 1:
-                               sorted_list.sort()
-                               if not self._value_sort_direction:
-                                       self._value_sort_direction = True
-                               else:
-                                       sorted_list.reverse()
-                                       self._value_sort_direction = False
-                       else:
-                               if not self._units_sort_direction:
-                                       sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(x), string.lower(y)))
-                                       self._units_sort_direction = True
-                               else:
-                                       sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(y), string.lower(x)))
-                                       self._units_sort_direction = False
-
-                       #Clear out the previous list of units
-                       self._unitModel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
-                       self._unitsView.set_model(self._unitModel)
-
-                       #colourize each row differently for easier reading
-                       self._unitsView.set_property('rules_hint', 1)
-
-                       #Clear out the description
-                       text_model = gtk.TextBuffer(None)
-                       self._unitDescription.set_buffer(text_model)
-
-                       if selectedUnitColumn == 0:
-                               for unit, value, units in sorted_list:
-                                       iter = self._unitModel.append()
-                                       self._unitModel.set(iter, 0, unit, 1, str(value), 2, units)
-                       elif selectedUnitColumn == 1:
-                               for value, unit, units in sorted_list:
-                                       iter = self._unitModel.append()
-                                       self._unitModel.set(iter, 0, unit, 1, str(value), 2, units)
+               try:
+                       #Determine which column requires sorting
+                       columns = self._get_column_sort_stuff()
+                       for column, directionName, col_cmp in columns:
+                               column.set_sort_indicator(False)
+                       for columnIndex, (maybeCol, directionName, col_cmp) in enumerate(columns):
+                               if col is maybeCol:
+                                       direction = getattr(self, directionName)
+                                       gtkDirection = gtk.SORT_ASCENDING if direction else gtk.SORT_DESCENDING
+
+                                       # cause a sort
+                                       self._sortedUnitModel.set_sort_column_id(columnIndex, gtkDirection)
+
+                                       # set the visual for sorting
+                                       col.set_sort_indicator(True)
+                                       col.set_sort_order(not direction)
+
+                                       setattr(self, directionName, not direction)
+                                       break
                        else:
-                               for units, value, unit in sorted_list:
-                                       iter = self._unitModel.append()
-                                       self._unitModel.set(iter, 0, unit, 1, str(value), 2, units)
-               return
+                               assert False, "Unknown column: %s" % (col.get_title(), )
+               except Exception:
+                       _moduleLogger.exception()
 
        def _on_click_category(self, row):
-               #Clear out the previous list of units
-               self._unitModel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
-               self._unitsView.set_model(self._unitModel)
-
                #Colourize each row alternately for easier reading
                self._unitsView.set_property('rules_hint', 1)
 
@@ -506,9 +450,11 @@ class Gonvert(object):
                del keys[0] # do not display .base_unit description key
 
                #Fill up the units descriptions and clear the value cells
+               self._unitModel.clear()
                for key in keys:
                        iter = self._unitModel.append()
                        self._unitModel.set(iter, 0, key, 1, '', 2, self._unitDataInCategory[key][1])
+               self._sortedUnitModel.sort_column_changed()
 
                self._unitName.set_text('')
                self._unitValue.set_text('')
@@ -549,9 +495,6 @@ class Gonvert(object):
                self._unitValue.grab_focus()
                self._unitValue.select_region(0, -1)
 
-       def _on_button_released(self, row, a):
-               self._on_click_unit(row)
-
        def _on_click_unit(self, row):
                self._calcsuppress = True #suppress calculations