28 _moduleLogger = logging.getLogger("gonvert_glade")
29 PROFILE_STARTUP = False
30 FORCE_HILDON_LIKE = False
32 if gettext is not None:
33 gettext.bindtextdomain('gonvert', '/usr/share/locale')
34 gettext.textdomain('gonvert')
37 def change_menu_label(widgets, labelname, newtext):
38 item_label = widgets.get_widget(labelname).get_children()[0]
39 item_label.set_text(newtext)
42 def split_number(number):
44 fractional, integer = math.modf(number)
46 integerDisplay = number
47 fractionalDisplay = ""
49 integerDisplay = str(integer)
50 fractionalDisplay = str(fractional)
51 if "e+" in integerDisplay:
52 integerDisplay = number
53 fractionalDisplay = ""
54 elif "e-" in fractionalDisplay and 0.0 < integer:
55 integerDisplay = number
56 fractionalDisplay = ""
57 elif "e-" in fractionalDisplay:
59 fractionalDisplay = number
61 integerDisplay = integerDisplay.split(".", 1)[0] + "."
62 fractionalDisplay = fractionalDisplay.rsplit(".", 1)[-1]
64 return integerDisplay, fractionalDisplay
67 class Gonvert(object):
70 os.path.join(os.path.dirname(__file__), "gonvert.glade"),
71 os.path.join(os.path.dirname(__file__), "../data/gonvert.glade"),
72 os.path.join(os.path.dirname(__file__), "../lib/gonvert.glade"),
73 '/usr/share/gonvert/gonvert.glade',
74 '/usr/lib/gonvert/gonvert.glade',
81 UNITS_FRACTION_IDX = 4
84 self._unitDataInCategory = None
85 self._unit_sort_direction = False
86 self._value_sort_direction = False
87 self._units_sort_direction = False
88 self._isFullScreen = False
90 self._find_result = [] # empty find result list
91 self._findIndex = 0 # default to find result number zero
93 self._selectedCategoryName = '' # preset to no selected category
94 self._defaultUnitForCategory = {} # empty dictionary for later use
96 #check to see if glade file is in current directory (user must be
97 # running from download untar directory)
98 for gladePath in self._glade_files:
99 if os.path.isfile(gladePath):
100 homepath = os.path.dirname(gladePath)
101 pixmapspath = "/".join((homepath, "pixmaps"))
102 widgets = gtk.glade.XML(gladePath)
105 _moduleLogger.error("UI Descriptor not found!")
109 self._mainWindow = widgets.get_widget('mainWindow')
110 self._app = hildonize.get_app_class()()
111 self._mainWindow = hildonize.hildonize_window(self._app, self._mainWindow)
113 change_menu_label(widgets, 'fileMenuItem', _('File'))
114 change_menu_label(widgets, 'exitMenuItem', _('Exit'))
115 change_menu_label(widgets, 'helpMenuItem', _('Help'))
116 change_menu_label(widgets, 'aboutMenuItem', _('About'))
117 change_menu_label(widgets, 'findButton', _('Find'))
119 self._categorySelectionButton = widgets.get_widget("categorySelectionButton")
120 self._categoryView = widgets.get_widget('categoryView')
122 self._unitsView = widgets.get_widget('unitsView')
123 self._unitsView.set_property('rules_hint', 1)
124 self._unitsView_selection = self._unitsView.get_selection()
126 self._unitName = widgets.get_widget('unitName')
127 self._unitValue = widgets.get_widget('unitValue')
128 self._previousUnitName = widgets.get_widget('previousUnitName')
129 self._previousUnitValue = widgets.get_widget('previousUnitValue')
131 self._unitSymbol = widgets.get_widget('unitSymbol')
132 self._previousUnitSymbol = widgets.get_widget('previousUnitSymbol')
134 self._unitDescription = widgets.get_widget('unitDescription')
136 self._searchLayout = widgets.get_widget('searchLayout')
137 self._searchLayout.hide()
138 self._findEntry = widgets.get_widget('findEntry')
139 self._findLabel = widgets.get_widget('findLabel')
140 self._findButton = widgets.get_widget('findButton')
142 self._unitsNameRenderer = gtk.CellRendererText()
143 self._unitsNameRenderer.set_property("scale", 0.75)
144 if FORCE_HILDON_LIKE:
145 self._unitsNameRenderer.set_property("ellipsize", pango.ELLIPSIZE_END)
146 self._unitsNameRenderer.set_property("width-chars", 5)
147 self._unitNameColumn = gtk.TreeViewColumn(_('Name'), self._unitsNameRenderer)
148 self._unitNameColumn.set_property('resizable', True)
149 self._unitNameColumn.add_attribute(self._unitsNameRenderer, 'text', self.UNITS_NAME_IDX)
150 self._unitNameColumn.set_clickable(True)
151 self._unitNameColumn.connect("clicked", self._on_click_unit_column)
152 self._unitsView.append_column(self._unitNameColumn)
154 renderer = gtk.CellRendererText()
155 renderer.set_property("xalign", 1.0)
156 renderer.set_property("alignment", pango.ALIGN_RIGHT)
157 hildonize.set_cell_thumb_selectable(renderer)
158 self._unitIntegerColumn = gtk.TreeViewColumn(_('Value'), renderer)
159 self._unitIntegerColumn.set_property('resizable', True)
160 self._unitIntegerColumn.add_attribute(renderer, 'text', self.UNITS_INTEGER_IDX)
161 self._unitIntegerColumn.set_clickable(True)
162 self._unitIntegerColumn.connect("clicked", self._on_click_unit_column)
163 self._unitsView.append_column(self._unitIntegerColumn)
165 renderer = gtk.CellRendererText()
166 renderer.set_property("xalign", 0.0)
167 renderer.set_property("alignment", pango.ALIGN_LEFT)
168 renderer.set_property("scale", 0.75)
169 self._unitFractionalColumn = gtk.TreeViewColumn(_(''), renderer)
170 self._unitFractionalColumn.set_property('resizable', True)
171 self._unitFractionalColumn.add_attribute(renderer, 'text', self.UNITS_FRACTION_IDX)
172 self._unitFractionalColumn.set_clickable(True)
173 self._unitFractionalColumn.connect("clicked", self._on_click_unit_column)
174 self._unitsView.append_column(self._unitFractionalColumn)
176 renderer = gtk.CellRendererText()
177 renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
178 #renderer.set_property("scale", 0.5)
179 self._unitSymbolColumn = gtk.TreeViewColumn(_('Units'), renderer)
180 self._unitSymbolColumn.set_property('resizable', True)
181 self._unitSymbolColumn.add_attribute(renderer, 'text', self.UNITS_SYMBOL_IDX)
182 self._unitSymbolColumn.set_clickable(True)
183 self._unitSymbolColumn.connect("clicked", self._on_click_unit_column)
184 self._unitsView.append_column(self._unitSymbolColumn)
186 self._unitModel = gtk.ListStore(
187 gobject.TYPE_STRING, # UNITS_NAME_IDX
188 gobject.TYPE_STRING, # UNITS_VALUE_IDX
189 gobject.TYPE_STRING, # UNITS_SYMBOL_IDX
190 gobject.TYPE_STRING, # UNITS_INTEGER_IDX
191 gobject.TYPE_STRING, # UNITS_FRACTION_IDX
193 self._sortedUnitModel = gtk.TreeModelSort(self._unitModel)
194 columns = self._get_column_sort_stuff()
195 for columnIndex, (column, sortDirection, col_cmp) in enumerate(columns):
196 self._sortedUnitModel.set_sort_func(columnIndex, col_cmp)
197 self._unitsView.set_model(self._sortedUnitModel)
199 #Insert a column into the category list even though the heading will not be seen
200 renderer = gtk.CellRendererText()
201 self._categoryColumn = gtk.TreeViewColumn('Title', renderer)
202 self._categoryColumn.set_property('resizable', 1)
203 self._categoryColumn.add_attribute(renderer, 'text', 0)
204 self._categoryView.append_column(self._categoryColumn)
206 self._categoryModel = gtk.ListStore(gobject.TYPE_STRING)
207 self._categoryView.set_model(self._categoryModel)
208 #colourize each row differently for easier reading
209 self._categoryView.set_property('rules_hint', 1)
211 #Populate the catagories list
212 for key in unit_data.UNIT_CATEGORIES:
214 self._categoryModel.append(row)
216 #--------- connections to GUI ----------------
217 self._mainWindow.connect("delete-event", self._on_user_exit)
218 self._mainWindow.connect("key-press-event", self._on_key_press)
219 self._mainWindow.connect("window-state-event", self._on_window_state_change)
220 self._categorySelectionButton.connect("clicked", self._on_category_selector_clicked)
221 self._categoryView.connect("cursor-changed", self._on_click_category)
222 self._findButton.connect("clicked", self._on_find_activate)
223 self._findEntry.connect("activate", self._on_find_activate)
224 self._findEntry.connect("changed", self._on_findEntry_changed)
225 self._previousUnitValue.connect("changed", self._on_previous_unit_value_changed)
226 self._unitValue.connect("changed", self._on_unit_value_changed)
227 self._unitsView.connect("cursor-changed", self._on_click_unit)
228 if hildonize.GTK_MENU_USED:
229 widgets.get_widget("aboutMenuItem").connect("activate", self._on_about_clicked)
230 widgets.get_widget("exitMenuItem").connect("activate", self._on_user_exit)
232 for scrollingWidgetName in (
233 "unitsViewScrolledWindow",
235 scrollingWidget = widgets.get_widget(scrollingWidgetName)
236 assert scrollingWidget is not None, scrollingWidgetName
237 hildonize.hildonize_scrollwindow_with_viewport(scrollingWidget)
239 if hildonize.IS_HILDON_SUPPORTED or FORCE_HILDON_LIKE:
240 self._categoryView.get_parent().hide()
241 self._unitsView.set_headers_visible(False)
242 self._previousUnitName.get_parent().hide()
243 self._unitDescription.get_parent().get_parent().hide()
245 self._categorySelectionButton.hide()
247 replacementButtons = []
248 menu = hildonize.hildonize_menu(
250 widgets.get_widget("mainMenuBar"),
254 if not hildonize.IS_HILDON_SUPPORTED:
255 _moduleLogger.info("No hildonization support")
257 hildonize.set_application_title(
258 self._mainWindow, "%s - Unit Conversion Utility" % constants.__pretty_app_name__
260 iconPath = pixmapspath + '/gonvert.png'
261 if os.path.exists(iconPath):
262 self._mainWindow.set_icon(gtk.gdk.pixbuf_new_from_file(iconPath))
264 _moduleLogger.warn("Error: Could not find gonvert icon: %s" % iconPath)
266 self._load_settings()
267 self._mainWindow.show()
269 def _load_settings(self):
270 #Restore window size from previously saved settings if it exists and is valid.
271 windowDatPath = "/".join((constants._data_path_, "window.dat"))
272 if os.path.exists(windowDatPath):
273 saved_window = pickle.load(open(windowDatPath, "r"))
275 a, b = saved_window['size']
279 self._mainWindow.resize(a, b)
281 #Restore selections from previously saved settings if it exists and is valid.
283 selectedCategoryName = unit_data.UNIT_CATEGORIES[0]
284 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
285 if os.path.exists(selectionsDatPath):
286 selections = pickle.load(open(selectionsDatPath, 'r'))
288 self._defaultUnitForCategory = selections['selected_units']
293 selectedCategoryName = selections['selected_category']
298 categoryIndex = unit_data.UNIT_CATEGORIES.index(selectedCategoryName)
300 _moduleLogger.warn("Unknown category: %s" % selectedCategoryName)
302 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % selectedCategoryName)
303 self._categoryView.set_cursor(categoryIndex, self._categoryColumn, False)
304 self._categoryView.grab_focus()
306 self._select_default_unit()
308 def _save_settings(self):
310 This routine saves the selections to a file, and
311 should therefore only be called when exiting the program.
313 Update selections dictionary which consists of the following keys:
314 'self._selectedCategoryName': full name of selected category
315 'self._defaultUnitForCategory': self._defaultUnitForCategory dictionary which contains:
316 [categoryname: #1 displayed unit, #2 displayed unit]
318 #Determine the contents of the selected category row
319 selected, iter = self._categoryView.get_selection().get_selected()
320 self._selectedCategoryName = self._categoryModel.get_value(iter, 0)
323 'selected_category': self._selectedCategoryName,
324 'selected_units': self._defaultUnitForCategory
326 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
327 pickle.dump(selections, open(selectionsDatPath, 'w'))
329 #Get last size of app and save it
331 'size': self._mainWindow.get_size()
333 windowDatPath = "/".join((constants._data_path_, "window.dat"))
334 pickle.dump(window_settings, open(windowDatPath, 'w'))
336 def _clear_find(self):
337 # switch to "new find" state
338 self._find_result = []
341 # Clear our user message
342 self._findLabel.set_text('')
344 def _find_first(self):
345 assert len(self._find_result) == 0
346 assert self._findIndex == 0
347 findString = self._findEntry.get_text().strip().lower()
351 # Gather info on all the matching units from all categories
352 for catIndex, category in enumerate(unit_data.UNIT_CATEGORIES):
353 units = unit_data.get_units(category)
354 for unitIndex, unit in enumerate(units):
355 loweredUnit = unit.lower()
356 if loweredUnit in findString or findString in loweredUnit:
357 self._find_result.append((category, unit, catIndex, unitIndex))
359 def _update_find_selection(self):
360 assert 0 < len(self._find_result)
362 #check if next find is in a new category (prevent category changes when unnecessary
363 searchCategoryName = self._find_result[self._findIndex][0]
364 if self._selectedCategoryName != searchCategoryName:
365 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % searchCategoryName)
366 self._categoryView.set_cursor(
367 self._find_result[self._findIndex][2], self._categoryColumn, False
370 self._unitsView.set_cursor(
371 self._find_result[self._findIndex][3], self._unitNameColumn, True
374 def _find_next(self):
375 if len(self._find_result) == 0:
378 if self._findIndex == len(self._find_result)-1:
383 if not self._find_result:
384 self._findLabel.set_text('Text not found')
386 self._update_find_selection()
387 resultsLeft = len(self._find_result) - self._findIndex - 1
388 self._findLabel.set_text(
389 '%s result(s) left' % (resultsLeft, )
392 def _find_previous(self):
393 if len(self._find_result) == 0:
396 if self._findIndex == 0:
397 self._findIndex = len(self._find_result)-1
401 if not self._find_result:
402 self._findLabel.set_text('Text not found')
404 self._update_find_selection()
405 resultsLeft = len(self._find_result) - self._findIndex - 1
406 self._findLabel.set_text(
407 '%s result(s) left' % (resultsLeft, )
410 def _toggle_find(self):
411 if self._searchLayout.get_property("visible"):
412 self._searchLayout.hide()
413 self._unitsView.grab_focus()
415 self._searchLayout.show()
416 self._findEntry.grab_focus()
418 def _unit_model_cmp(self, sortedModel, leftItr, rightItr):
419 leftUnitText = self._unitModel.get_value(leftItr, self.UNITS_NAME_IDX)
420 rightUnitText = self._unitModel.get_value(rightItr, self.UNITS_NAME_IDX)
421 return cmp(leftUnitText, rightUnitText)
423 def _symbol_model_cmp(self, sortedModel, leftItr, rightItr):
424 leftSymbolText = self._unitModel.get_value(leftItr, self.UNITS_SYMBOL_IDX)
425 rightSymbolText = self._unitModel.get_value(rightItr, self.UNITS_SYMBOL_IDX)
426 return cmp(leftSymbolText, rightSymbolText)
428 def _value_model_cmp(self, sortedModel, leftItr, rightItr):
429 #special sorting exceptions for ascii values (instead of float values)
430 if self._selectedCategoryName == "Computer Numbers":
431 leftValue = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
432 rightValue = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
434 leftValueText = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
435 leftValue = float(leftValueText) if leftValueText else 0.0
437 rightValueText = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
438 rightValue = float(rightValueText) if rightValueText else 0.0
439 return cmp(leftValue, rightValue)
441 def _get_column_sort_stuff(self):
443 (self._unitNameColumn, "_unit_sort_direction", self._unit_model_cmp),
444 (self._unitIntegerColumn, "_value_sort_direction", self._value_model_cmp),
445 (self._unitFractionalColumn, "_value_sort_direction", self._value_model_cmp),
446 (self._unitSymbolColumn, "_units_sort_direction", self._symbol_model_cmp),
450 def _switch_category(self, category):
451 self._selectedCategoryName = category
452 self._unitDataInCategory = unit_data.UNIT_DESCRIPTIONS[self._selectedCategoryName]
454 #Fill up the units descriptions and clear the value cells
455 self._clear_visible_unit_data()
457 for key in unit_data.get_units(self._selectedCategoryName):
458 row = key, '0.0', self._unitDataInCategory[key][1], '0.', '0'
459 self._unitModel.append(row)
460 nameLength = max(nameLength, len(key))
461 self._sortedUnitModel.sort_column_changed()
463 if FORCE_HILDON_LIKE:
464 charWidth = int(nameLength * 0.75)
465 charWidth = min(charWidth, 20)
466 self._unitsNameRenderer.set_property("width-chars", charWidth)
468 self._select_default_unit()
470 def _clear_visible_unit_data(self):
471 self._unitDescription.get_buffer().set_text("")
472 self._unitName.set_text('')
473 self._unitValue.set_text('')
474 self._unitSymbol.set_text('')
476 self._previousUnitName.set_text('')
477 self._previousUnitValue.set_text('')
478 self._previousUnitSymbol.set_text('')
480 self._unitModel.clear()
482 def _select_default_unit(self):
483 # Restore the previous historical settings of previously selected units
484 # in this newly selected category
485 defaultPrimary = unit_data.get_base_unit(self._selectedCategoryName)
486 defaultSecondary = ""
487 if self._selectedCategoryName in self._defaultUnitForCategory:
488 if self._defaultUnitForCategory[self._selectedCategoryName][0]:
489 defaultPrimary = self._defaultUnitForCategory[self._selectedCategoryName][0]
490 if self._defaultUnitForCategory[self._selectedCategoryName][1]:
491 defaultSecondary = self._defaultUnitForCategory[self._selectedCategoryName][1]
493 units = unit_data.get_units(self._selectedCategoryName)
495 #Restore oldest selection first.
498 unitIndex = units.index(defaultPrimary)
501 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
503 #Restore newest selection second.
506 unitIndex = units.index(defaultSecondary)
509 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
511 # select the text so user can start typing right away
512 self._unitValue.grab_focus()
513 self._unitValue.select_region(0, -1)
515 def _sanitize_value(self, userEntry):
516 if self._selectedCategoryName == "Computer Numbers":
525 value = float(userEntry)
528 def _on_key_press(self, widget, event, *args):
530 @note Hildon specific
532 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
535 event.keyval == gtk.keysyms.F6 or
536 event.keyval in RETURN_TYPES and event.get_state() & gtk.gdk.CONTROL_MASK
538 if self._isFullScreen:
539 self._mainWindow.unfullscreen()
541 self._mainWindow.fullscreen()
542 elif event.keyval == gtk.keysyms.f and event.get_state() & gtk.gdk.CONTROL_MASK:
544 elif event.keyval == gtk.keysyms.p and event.get_state() & gtk.gdk.CONTROL_MASK:
545 self._find_previous()
546 elif event.keyval == gtk.keysyms.n and event.get_state() & gtk.gdk.CONTROL_MASK:
549 _moduleLogger.exception("_on_key_press")
551 def _on_window_state_change(self, widget, event, *args):
553 @note Hildon specific
556 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
557 self._isFullScreen = True
559 self._isFullScreen = False
561 _moduleLogger.exception("_on_window_state_change")
563 def _on_findEntry_changed(self, *args):
565 Clear out find results since the user wants to look for something new
570 _moduleLogger.exception("_on_findEntry_changed")
572 def _on_find_activate(self, *args):
575 self._findButton.grab_focus()
577 _moduleLogger.exception("_on_find_activate")
579 def _on_click_unit_column(self, col):
581 Sort the contents of the col when the user clicks on the title.
584 #Determine which column requires sorting
585 columns = self._get_column_sort_stuff()
586 for columnIndex, (maybeCol, directionName, col_cmp) in enumerate(columns):
588 direction = getattr(self, directionName)
589 gtkDirection = gtk.SORT_ASCENDING if direction else gtk.SORT_DESCENDING
592 self._sortedUnitModel.set_sort_column_id(columnIndex, gtkDirection)
594 # set the visual for sorting
595 col.set_sort_indicator(True)
596 col.set_sort_order(not direction)
598 setattr(self, directionName, not direction)
601 maybeCol.set_sort_indicator(False)
603 assert False, "Unknown column: %s" % (col.get_title(), )
605 _moduleLogger.exception("_on_click_unit_column")
607 def _on_category_selector_clicked(self, *args):
609 currenntIndex = unit_data.UNIT_CATEGORIES.index(self._selectedCategoryName)
610 newIndex = hildonize.touch_selector(
613 unit_data.UNIT_CATEGORIES,
617 selectedCategoryName = unit_data.UNIT_CATEGORIES[newIndex]
618 self._categorySelectionButton.set_label(selectedCategoryName)
619 self._categoryView.set_cursor(newIndex, self._categoryColumn, False)
620 self._categoryView.grab_focus()
622 _moduleLogger.exception("_on_category_selector_clicked")
624 def _on_click_category(self, *args):
626 selected, iter = self._categoryView.get_selection().get_selected()
628 # User is typing in an invalid string, not selecting any category
630 selectedCategory = self._categoryModel.get_value(iter, 0)
631 self._switch_category(selectedCategory)
633 _moduleLogger.exception("_on_click_category")
635 def _on_click_unit(self, *args):
637 selected, iter = self._unitsView.get_selection().get_selected()
638 selected_unit = selected.get_value(iter, self.UNITS_NAME_IDX)
639 unit_spec = self._unitDataInCategory[selected_unit]
643 if self._unitName.get_text() != selected_unit:
644 self._previousUnitName.set_text(self._unitName.get_text())
645 self._previousUnitValue.set_text(self._unitValue.get_text())
646 self._previousUnitSymbol.set_text(self._unitSymbol.get_text())
647 if self._unitSymbol.get_text():
650 self._unitName.set_text(selected_unit)
651 self._unitValue.set_text(selected.get_value(iter, self.UNITS_VALUE_IDX))
652 buffer = self._unitDescription.get_buffer()
653 buffer.set_text(unit_spec[2])
654 self._unitSymbol.set_text(unit_spec[1]) # put units into label text
661 self._unitSymbol.show()
662 self._previousUnitSymbol.show()
664 self._unitSymbol.hide()
665 self._previousUnitSymbol.hide()
667 if self._unitValue.get_text() == '':
668 if self._selectedCategoryName == "Computer Numbers":
669 self._unitValue.set_text("0")
671 self._unitValue.set_text("0.0")
673 self._defaultUnitForCategory[self._selectedCategoryName] = [
674 self._unitName.get_text(), self._previousUnitName.get_text()
677 # select the text so user can start typing right away
678 self._unitValue.grab_focus()
679 self._unitValue.select_region(0, -1)
681 _moduleLogger.exception("_on_click_unit")
683 def _on_unit_value_changed(self, *args):
685 if self._unitName.get_text() == '':
687 if not self._unitValue.is_focus():
690 #retrieve the conversion function and value from the selected unit
691 value = self._sanitize_value(self._unitValue.get_text())
692 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
693 base = func.to_base(value, arg)
695 #point to the first row
696 for row in self._unitModel:
697 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
698 newValue = func.from_base(base, arg)
700 newValueDisplay = str(newValue)
701 integerDisplay, fractionalDisplay = split_number(newValue)
703 row[self.UNITS_VALUE_IDX] = newValueDisplay
704 row[self.UNITS_INTEGER_IDX] = integerDisplay
705 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
707 # Update the secondary unit entry
708 if self._previousUnitName.get_text() != '':
709 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
710 self._previousUnitValue.set_text(str(func.from_base(base, arg, )))
712 self._sortedUnitModel.sort_column_changed()
714 _moduleLogger.exception("_on_unit_value_changed")
716 def _on_previous_unit_value_changed(self, *args):
718 if self._previousUnitName.get_text() == '':
720 if not self._previousUnitValue.is_focus():
723 #retrieve the conversion function and value from the selected unit
724 value = self._sanitize_value(self._previousUnitValue.get_text())
725 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
726 base = func.to_base(value, arg)
728 #point to the first row
729 for row in self._unitModel:
730 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
731 newValue = func.from_base(base, arg)
733 newValueDisplay = str(newValue)
734 integerDisplay, fractionalDisplay = split_number(newValue)
736 row[self.UNITS_VALUE_IDX] = newValueDisplay
737 row[self.UNITS_INTEGER_IDX] = integerDisplay
738 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
740 # Update the primary unit entry
741 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
742 self._unitValue.set_text(str(func.from_base(base, arg, )))
744 self._sortedUnitModel.sort_column_changed()
746 _moduleLogger.exception("_on_previous_unit_value_changed")
748 def _on_about_clicked(self, a):
749 dlg = gtk.AboutDialog()
750 dlg.set_name(constants.__pretty_app_name__)
751 dlg.set_version("%s-%d" % (constants.__version__, constants.__build__))
752 dlg.set_copyright("Copyright 2009 - GPL")
754 dlg.set_website("http://unihedron.com/projects/gonvert/gonvert.php")
755 dlg.set_authors(["Anthony Tekatch <anthony@unihedron.com>", "Ed Page <edpage@byu.net>"])
759 def _on_user_exit(self, *args):
761 self._save_settings()
763 _moduleLogger.exception("_on_user_exit")
769 gtk.gdk.threads_init()
770 if hildonize.IS_HILDON_SUPPORTED:
771 gtk.set_application_name(constants.__pretty_app_name__)
773 if not PROFILE_STARTUP:
777 if __name__ == "__main__":
778 logging.basicConfig(level = logging.DEBUG)
780 os.makedirs(constants._data_path_)