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("ellipsize", pango.ELLIPSIZE_END)
144 self._unitsNameRenderer.set_property("scale", 0.75)
145 self._unitsNameRenderer.set_property("width-chars", 5)
146 self._unitNameColumn = gtk.TreeViewColumn(_('Name'), self._unitsNameRenderer)
147 self._unitNameColumn.set_property('resizable', True)
148 self._unitNameColumn.add_attribute(self._unitsNameRenderer, 'text', self.UNITS_NAME_IDX)
149 self._unitNameColumn.set_clickable(True)
150 self._unitNameColumn.connect("clicked", self._on_click_unit_column)
151 self._unitsView.append_column(self._unitNameColumn)
153 renderer = gtk.CellRendererText()
154 renderer.set_property("xalign", 1.0)
155 renderer.set_property("alignment", pango.ALIGN_RIGHT)
156 hildonize.set_cell_thumb_selectable(renderer)
157 self._unitIntegerColumn = gtk.TreeViewColumn(_('Value'), renderer)
158 self._unitIntegerColumn.set_property('resizable', True)
159 self._unitIntegerColumn.add_attribute(renderer, 'text', self.UNITS_INTEGER_IDX)
160 self._unitIntegerColumn.set_clickable(True)
161 self._unitIntegerColumn.connect("clicked", self._on_click_unit_column)
162 self._unitsView.append_column(self._unitIntegerColumn)
164 renderer = gtk.CellRendererText()
165 renderer.set_property("xalign", 0.0)
166 renderer.set_property("alignment", pango.ALIGN_LEFT)
167 renderer.set_property("scale", 0.75)
168 self._unitFractionalColumn = gtk.TreeViewColumn(_(''), renderer)
169 self._unitFractionalColumn.set_property('resizable', True)
170 self._unitFractionalColumn.add_attribute(renderer, 'text', self.UNITS_FRACTION_IDX)
171 self._unitFractionalColumn.set_clickable(True)
172 self._unitFractionalColumn.connect("clicked", self._on_click_unit_column)
173 self._unitsView.append_column(self._unitFractionalColumn)
175 renderer = gtk.CellRendererText()
176 renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
177 #renderer.set_property("scale", 0.5)
178 self._unitSymbolColumn = gtk.TreeViewColumn(_('Units'), renderer)
179 self._unitSymbolColumn.set_property('resizable', True)
180 self._unitSymbolColumn.add_attribute(renderer, 'text', self.UNITS_SYMBOL_IDX)
181 self._unitSymbolColumn.set_clickable(True)
182 self._unitSymbolColumn.connect("clicked", self._on_click_unit_column)
183 self._unitsView.append_column(self._unitSymbolColumn)
185 self._unitModel = gtk.ListStore(
186 gobject.TYPE_STRING, # UNITS_NAME_IDX
187 gobject.TYPE_STRING, # UNITS_VALUE_IDX
188 gobject.TYPE_STRING, # UNITS_SYMBOL_IDX
189 gobject.TYPE_STRING, # UNITS_INTEGER_IDX
190 gobject.TYPE_STRING, # UNITS_FRACTION_IDX
192 self._sortedUnitModel = gtk.TreeModelSort(self._unitModel)
193 columns = self._get_column_sort_stuff()
194 for columnIndex, (column, sortDirection, col_cmp) in enumerate(columns):
195 self._sortedUnitModel.set_sort_func(columnIndex, col_cmp)
196 self._unitsView.set_model(self._sortedUnitModel)
198 #Insert a column into the category list even though the heading will not be seen
199 renderer = gtk.CellRendererText()
200 self._categoryColumn = gtk.TreeViewColumn('Title', renderer)
201 self._categoryColumn.set_property('resizable', 1)
202 self._categoryColumn.add_attribute(renderer, 'text', 0)
203 self._categoryView.append_column(self._categoryColumn)
205 self._categoryModel = gtk.ListStore(gobject.TYPE_STRING)
206 self._categoryView.set_model(self._categoryModel)
207 #colourize each row differently for easier reading
208 self._categoryView.set_property('rules_hint', 1)
210 #Populate the catagories list
211 for key in unit_data.UNIT_CATEGORIES:
213 self._categoryModel.append(row)
215 #--------- connections to GUI ----------------
216 self._mainWindow.connect("delete-event", self._on_user_exit)
217 self._mainWindow.connect("key-press-event", self._on_key_press)
218 self._mainWindow.connect("window-state-event", self._on_window_state_change)
219 self._categorySelectionButton.connect("clicked", self._on_category_selector_clicked)
220 self._categoryView.connect("cursor-changed", self._on_click_category)
221 self._findButton.connect("clicked", self._on_find_activate)
222 self._findEntry.connect("activate", self._on_find_activate)
223 self._findEntry.connect("changed", self._on_findEntry_changed)
224 self._previousUnitValue.connect("changed", self._on_previous_unit_value_changed)
225 self._unitValue.connect("changed", self._on_unit_value_changed)
226 self._unitsView.connect("cursor-changed", self._on_click_unit)
227 if hildonize.GTK_MENU_USED:
228 widgets.get_widget("aboutMenuItem").connect("activate", self._on_about_clicked)
229 widgets.get_widget("exitMenuItem").connect("activate", self._on_user_exit)
231 for scrollingWidgetName in (
232 "unitsViewScrolledWindow",
234 scrollingWidget = widgets.get_widget(scrollingWidgetName)
235 assert scrollingWidget is not None, scrollingWidgetName
236 hildonize.hildonize_scrollwindow_with_viewport(scrollingWidget)
238 if hildonize.IS_HILDON_SUPPORTED or FORCE_HILDON_LIKE:
239 self._categoryView.get_parent().hide()
240 self._unitsView.set_headers_visible(False)
241 self._previousUnitName.get_parent().hide()
242 self._unitDescription.get_parent().get_parent().hide()
244 self._categorySelectionButton.hide()
246 replacementButtons = []
247 menu = hildonize.hildonize_menu(
249 widgets.get_widget("mainMenuBar"),
253 if not hildonize.IS_HILDON_SUPPORTED:
254 _moduleLogger.info("No hildonization support")
256 hildonize.set_application_title(
257 self._mainWindow, "%s - Unit Conversion Utility" % constants.__pretty_app_name__
259 iconPath = pixmapspath + '/gonvert.png'
260 if os.path.exists(iconPath):
261 self._mainWindow.set_icon(gtk.gdk.pixbuf_new_from_file(iconPath))
263 _moduleLogger.warn("Error: Could not find gonvert icon: %s" % iconPath)
265 self._load_settings()
266 self._mainWindow.show()
268 def _load_settings(self):
269 #Restore window size from previously saved settings if it exists and is valid.
270 windowDatPath = "/".join((constants._data_path_, "window.dat"))
271 if os.path.exists(windowDatPath):
272 saved_window = pickle.load(open(windowDatPath, "r"))
274 a, b = saved_window['size']
278 self._mainWindow.resize(a, b)
280 #Restore selections from previously saved settings if it exists and is valid.
282 selectedCategoryName = unit_data.UNIT_CATEGORIES[0]
283 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
284 if os.path.exists(selectionsDatPath):
285 selections = pickle.load(open(selectionsDatPath, 'r'))
287 self._defaultUnitForCategory = selections['selected_units']
292 selectedCategoryName = selections['selected_category']
297 categoryIndex = unit_data.UNIT_CATEGORIES.index(selectedCategoryName)
299 _moduleLogger.warn("Unknown category: %s" % selectedCategoryName)
301 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % selectedCategoryName)
302 self._categoryView.set_cursor(categoryIndex, self._categoryColumn, False)
303 self._categoryView.grab_focus()
305 self._select_default_unit()
307 def _save_settings(self):
309 This routine saves the selections to a file, and
310 should therefore only be called when exiting the program.
312 Update selections dictionary which consists of the following keys:
313 'self._selectedCategoryName': full name of selected category
314 'self._defaultUnitForCategory': self._defaultUnitForCategory dictionary which contains:
315 [categoryname: #1 displayed unit, #2 displayed unit]
317 #Determine the contents of the selected category row
318 selected, iter = self._categoryView.get_selection().get_selected()
319 self._selectedCategoryName = self._categoryModel.get_value(iter, 0)
322 'selected_category': self._selectedCategoryName,
323 'selected_units': self._defaultUnitForCategory
325 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
326 pickle.dump(selections, open(selectionsDatPath, 'w'))
328 #Get last size of app and save it
330 'size': self._mainWindow.get_size()
332 windowDatPath = "/".join((constants._data_path_, "window.dat"))
333 pickle.dump(window_settings, open(windowDatPath, 'w'))
335 def _clear_find(self):
336 # switch to "new find" state
337 self._find_result = []
340 # Clear our user message
341 self._findLabel.set_text('')
343 def _find_first(self):
344 assert len(self._find_result) == 0
345 assert self._findIndex == 0
346 findString = self._findEntry.get_text().strip().lower()
350 # Gather info on all the matching units from all categories
351 for catIndex, category in enumerate(unit_data.UNIT_CATEGORIES):
352 units = unit_data.get_units(category)
353 for unitIndex, unit in enumerate(units):
354 loweredUnit = unit.lower()
355 if loweredUnit in findString or findString in loweredUnit:
356 self._find_result.append((category, unit, catIndex, unitIndex))
358 def _update_find_selection(self):
359 assert 0 < len(self._find_result)
361 #check if next find is in a new category (prevent category changes when unnecessary
362 searchCategoryName = self._find_result[self._findIndex][0]
363 if self._selectedCategoryName != searchCategoryName:
364 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % searchCategoryName)
365 self._categoryView.set_cursor(
366 self._find_result[self._findIndex][2], self._categoryColumn, False
369 self._unitsView.set_cursor(
370 self._find_result[self._findIndex][3], self._unitNameColumn, True
373 def _find_next(self):
374 if len(self._find_result) == 0:
377 if self._findIndex == len(self._find_result)-1:
382 if not self._find_result:
383 self._findLabel.set_text('Text not found')
385 self._update_find_selection()
386 resultsLeft = len(self._find_result) - self._findIndex - 1
387 self._findLabel.set_text(
388 '%s result(s) left' % (resultsLeft, )
391 def _find_previous(self):
392 if len(self._find_result) == 0:
395 if self._findIndex == 0:
396 self._findIndex = len(self._find_result)-1
400 if not self._find_result:
401 self._findLabel.set_text('Text not found')
403 self._update_find_selection()
404 resultsLeft = len(self._find_result) - self._findIndex - 1
405 self._findLabel.set_text(
406 '%s result(s) left' % (resultsLeft, )
409 def _toggle_find(self):
410 if self._searchLayout.get_property("visible"):
411 self._searchLayout.hide()
412 self._unitsView.grab_focus()
414 self._searchLayout.show()
415 self._findEntry.grab_focus()
417 def _unit_model_cmp(self, sortedModel, leftItr, rightItr):
418 leftUnitText = self._unitModel.get_value(leftItr, self.UNITS_NAME_IDX)
419 rightUnitText = self._unitModel.get_value(rightItr, self.UNITS_NAME_IDX)
420 return cmp(leftUnitText, rightUnitText)
422 def _symbol_model_cmp(self, sortedModel, leftItr, rightItr):
423 leftSymbolText = self._unitModel.get_value(leftItr, self.UNITS_SYMBOL_IDX)
424 rightSymbolText = self._unitModel.get_value(rightItr, self.UNITS_SYMBOL_IDX)
425 return cmp(leftSymbolText, rightSymbolText)
427 def _value_model_cmp(self, sortedModel, leftItr, rightItr):
428 #special sorting exceptions for ascii values (instead of float values)
429 if self._selectedCategoryName == "Computer Numbers":
430 leftValue = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
431 rightValue = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
433 leftValueText = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
434 leftValue = float(leftValueText) if leftValueText else 0.0
436 rightValueText = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
437 rightValue = float(rightValueText) if rightValueText else 0.0
438 return cmp(leftValue, rightValue)
440 def _get_column_sort_stuff(self):
442 (self._unitNameColumn, "_unit_sort_direction", self._unit_model_cmp),
443 (self._unitIntegerColumn, "_value_sort_direction", self._value_model_cmp),
444 (self._unitFractionalColumn, "_value_sort_direction", self._value_model_cmp),
445 (self._unitSymbolColumn, "_units_sort_direction", self._symbol_model_cmp),
449 def _switch_category(self, category):
450 self._selectedCategoryName = category
451 self._unitDataInCategory = unit_data.UNIT_DESCRIPTIONS[self._selectedCategoryName]
453 #Fill up the units descriptions and clear the value cells
454 self._clear_visible_unit_data()
456 for key in unit_data.get_units(self._selectedCategoryName):
457 row = key, '0.0', self._unitDataInCategory[key][1], '0.', '0'
458 self._unitModel.append(row)
459 nameLength = max(nameLength, len(key))
460 self._sortedUnitModel.sort_column_changed()
461 self._unitsNameRenderer.set_property("width-chars", int(nameLength * 0.75))
463 self._select_default_unit()
465 def _clear_visible_unit_data(self):
466 self._unitDescription.get_buffer().set_text("")
467 self._unitName.set_text('')
468 self._unitValue.set_text('')
469 self._unitSymbol.set_text('')
471 self._previousUnitName.set_text('')
472 self._previousUnitValue.set_text('')
473 self._previousUnitSymbol.set_text('')
475 self._unitModel.clear()
477 def _select_default_unit(self):
478 # Restore the previous historical settings of previously selected units
479 # in this newly selected category
480 defaultPrimary = unit_data.get_base_unit(self._selectedCategoryName)
481 defaultSecondary = ""
482 if self._selectedCategoryName in self._defaultUnitForCategory:
483 if self._defaultUnitForCategory[self._selectedCategoryName][0]:
484 defaultPrimary = self._defaultUnitForCategory[self._selectedCategoryName][0]
485 if self._defaultUnitForCategory[self._selectedCategoryName][1]:
486 defaultSecondary = self._defaultUnitForCategory[self._selectedCategoryName][1]
488 units = unit_data.get_units(self._selectedCategoryName)
490 #Restore oldest selection first.
493 unitIndex = units.index(defaultPrimary)
496 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
498 #Restore newest selection second.
501 unitIndex = units.index(defaultSecondary)
504 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
506 # select the text so user can start typing right away
507 self._unitValue.grab_focus()
508 self._unitValue.select_region(0, -1)
510 def _sanitize_value(self, userEntry):
511 if self._selectedCategoryName == "Computer Numbers":
520 value = float(userEntry)
523 def _on_key_press(self, widget, event, *args):
525 @note Hildon specific
527 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
530 event.keyval == gtk.keysyms.F6 or
531 event.keyval in RETURN_TYPES and event.get_state() & gtk.gdk.CONTROL_MASK
533 if self._isFullScreen:
534 self._mainWindow.unfullscreen()
536 self._mainWindow.fullscreen()
537 elif event.keyval == gtk.keysyms.f and event.get_state() & gtk.gdk.CONTROL_MASK:
539 elif event.keyval == gtk.keysyms.p and event.get_state() & gtk.gdk.CONTROL_MASK:
540 self._find_previous()
541 elif event.keyval == gtk.keysyms.n and event.get_state() & gtk.gdk.CONTROL_MASK:
544 _moduleLogger.exception("_on_key_press")
546 def _on_window_state_change(self, widget, event, *args):
548 @note Hildon specific
551 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
552 self._isFullScreen = True
554 self._isFullScreen = False
556 _moduleLogger.exception("_on_window_state_change")
558 def _on_findEntry_changed(self, *args):
560 Clear out find results since the user wants to look for something new
565 _moduleLogger.exception("_on_findEntry_changed")
567 def _on_find_activate(self, *args):
570 self._findButton.grab_focus()
572 _moduleLogger.exception("_on_find_activate")
574 def _on_click_unit_column(self, col):
576 Sort the contents of the col when the user clicks on the title.
579 #Determine which column requires sorting
580 columns = self._get_column_sort_stuff()
581 for columnIndex, (maybeCol, directionName, col_cmp) in enumerate(columns):
583 direction = getattr(self, directionName)
584 gtkDirection = gtk.SORT_ASCENDING if direction else gtk.SORT_DESCENDING
587 self._sortedUnitModel.set_sort_column_id(columnIndex, gtkDirection)
589 # set the visual for sorting
590 col.set_sort_indicator(True)
591 col.set_sort_order(not direction)
593 setattr(self, directionName, not direction)
596 maybeCol.set_sort_indicator(False)
598 assert False, "Unknown column: %s" % (col.get_title(), )
600 _moduleLogger.exception("_on_click_unit_column")
602 def _on_category_selector_clicked(self, *args):
604 currenntIndex = unit_data.UNIT_CATEGORIES.index(self._selectedCategoryName)
605 newIndex = hildonize.touch_selector(
608 unit_data.UNIT_CATEGORIES,
612 selectedCategoryName = unit_data.UNIT_CATEGORIES[newIndex]
613 self._categorySelectionButton.set_label(selectedCategoryName)
614 self._categoryView.set_cursor(newIndex, self._categoryColumn, False)
615 self._categoryView.grab_focus()
617 _moduleLogger.exception("_on_category_selector_clicked")
619 def _on_click_category(self, *args):
621 selected, iter = self._categoryView.get_selection().get_selected()
623 # User is typing in an invalid string, not selecting any category
625 selectedCategory = self._categoryModel.get_value(iter, 0)
626 self._switch_category(selectedCategory)
628 _moduleLogger.exception("_on_click_category")
630 def _on_click_unit(self, *args):
632 selected, iter = self._unitsView.get_selection().get_selected()
633 selected_unit = selected.get_value(iter, self.UNITS_NAME_IDX)
634 unit_spec = self._unitDataInCategory[selected_unit]
638 if self._unitName.get_text() != selected_unit:
639 self._previousUnitName.set_text(self._unitName.get_text())
640 self._previousUnitValue.set_text(self._unitValue.get_text())
641 self._previousUnitSymbol.set_text(self._unitSymbol.get_text())
642 if self._unitSymbol.get_text():
645 self._unitName.set_text(selected_unit)
646 self._unitValue.set_text(selected.get_value(iter, self.UNITS_VALUE_IDX))
647 buffer = self._unitDescription.get_buffer()
648 buffer.set_text(unit_spec[2])
649 self._unitSymbol.set_text(unit_spec[1]) # put units into label text
656 self._unitSymbol.show()
657 self._previousUnitSymbol.show()
659 self._unitSymbol.hide()
660 self._previousUnitSymbol.hide()
662 if self._unitValue.get_text() == '':
663 if self._selectedCategoryName == "Computer Numbers":
664 self._unitValue.set_text("0")
666 self._unitValue.set_text("0.0")
668 self._defaultUnitForCategory[self._selectedCategoryName] = [
669 self._unitName.get_text(), self._previousUnitName.get_text()
672 # select the text so user can start typing right away
673 self._unitValue.grab_focus()
674 self._unitValue.select_region(0, -1)
676 _moduleLogger.exception("_on_click_unit")
678 def _on_unit_value_changed(self, *args):
680 if self._unitName.get_text() == '':
682 if not self._unitValue.is_focus():
685 #retrieve the conversion function and value from the selected unit
686 value = self._sanitize_value(self._unitValue.get_text())
687 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
688 base = func.to_base(value, arg)
690 #point to the first row
691 for row in self._unitModel:
692 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
693 newValue = func.from_base(base, arg)
695 newValueDisplay = str(newValue)
696 integerDisplay, fractionalDisplay = split_number(newValue)
698 row[self.UNITS_VALUE_IDX] = newValueDisplay
699 row[self.UNITS_INTEGER_IDX] = integerDisplay
700 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
702 # Update the secondary unit entry
703 if self._previousUnitName.get_text() != '':
704 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
705 self._previousUnitValue.set_text(str(func.from_base(base, arg, )))
707 self._sortedUnitModel.sort_column_changed()
709 _moduleLogger.exception("_on_unit_value_changed")
711 def _on_previous_unit_value_changed(self, *args):
713 if self._previousUnitName.get_text() == '':
715 if not self._previousUnitValue.is_focus():
718 #retrieve the conversion function and value from the selected unit
719 value = self._sanitize_value(self._previousUnitValue.get_text())
720 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
721 base = func.to_base(value, arg)
723 #point to the first row
724 for row in self._unitModel:
725 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
726 newValue = func.from_base(base, arg)
728 newValueDisplay = str(newValue)
729 integerDisplay, fractionalDisplay = split_number(newValue)
731 row[self.UNITS_VALUE_IDX] = newValueDisplay
732 row[self.UNITS_INTEGER_IDX] = integerDisplay
733 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
735 # Update the primary unit entry
736 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
737 self._unitValue.set_text(str(func.from_base(base, arg, )))
739 self._sortedUnitModel.sort_column_changed()
741 _moduleLogger.exception("_on_previous_unit_value_changed")
743 def _on_about_clicked(self, a):
744 dlg = gtk.AboutDialog()
745 dlg.set_name(constants.__pretty_app_name__)
746 dlg.set_version("%s-%d" % (constants.__version__, constants.__build__))
747 dlg.set_copyright("Copyright 2009 - GPL")
749 dlg.set_website("http://unihedron.com/projects/gonvert/gonvert.php")
750 dlg.set_authors(["Anthony Tekatch <anthony@unihedron.com>", "Ed Page <edpage@byu.net>"])
754 def _on_user_exit(self, *args):
756 self._save_settings()
758 _moduleLogger.exception("_on_user_exit")
764 gtk.gdk.threads_init()
765 if hildonize.IS_HILDON_SUPPORTED:
766 gtk.set_application_name(constants.__pretty_app_name__)
768 if not PROFILE_STARTUP:
772 if __name__ == "__main__":
773 logging.basicConfig(level = logging.DEBUG)
775 os.makedirs(constants._data_path_)