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
89 self._clipboard = gtk.clipboard_get()
91 self._find_result = [] # empty find result list
92 self._findIndex = 0 # default to find result number zero
94 self._selectedCategoryName = '' # preset to no selected category
95 self._defaultUnitForCategory = {} # empty dictionary for later use
97 #check to see if glade file is in current directory (user must be
98 # running from download untar directory)
99 for gladePath in self._glade_files:
100 if os.path.isfile(gladePath):
101 homepath = os.path.dirname(gladePath)
102 pixmapspath = "/".join((homepath, "pixmaps"))
103 widgets = gtk.glade.XML(gladePath)
106 _moduleLogger.error("UI Descriptor not found!")
110 self._mainWindow = widgets.get_widget('mainWindow')
111 self._app = hildonize.get_app_class()()
112 self._mainWindow = hildonize.hildonize_window(self._app, self._mainWindow)
114 change_menu_label(widgets, 'fileMenuItem', _('File'))
115 change_menu_label(widgets, 'exitMenuItem', _('Exit'))
116 change_menu_label(widgets, 'helpMenuItem', _('Help'))
117 change_menu_label(widgets, 'aboutMenuItem', _('About'))
118 change_menu_label(widgets, 'findButton', _('Find'))
120 self._categorySelectionButton = widgets.get_widget("categorySelectionButton")
121 self._categoryView = widgets.get_widget('categoryView')
123 self._unitsView = widgets.get_widget('unitsView')
124 self._unitsView.set_property('rules_hint', 1)
125 self._unitsView_selection = self._unitsView.get_selection()
127 self._unitName = widgets.get_widget('unitName')
128 self._unitValue = widgets.get_widget('unitValue')
129 self._previousUnitName = widgets.get_widget('previousUnitName')
130 self._previousUnitValue = widgets.get_widget('previousUnitValue')
132 self._unitSymbol = widgets.get_widget('unitSymbol')
133 self._previousUnitSymbol = widgets.get_widget('previousUnitSymbol')
135 self._unitDescription = widgets.get_widget('unitDescription')
137 self._searchLayout = widgets.get_widget('searchLayout')
138 self._searchLayout.hide()
139 self._findEntry = widgets.get_widget('findEntry')
140 self._findLabel = widgets.get_widget('findLabel')
141 self._findButton = widgets.get_widget('findButton')
143 self._unitsNameRenderer = gtk.CellRendererText()
144 self._unitsNameRenderer.set_property("scale", 0.75)
145 if FORCE_HILDON_LIKE:
146 self._unitsNameRenderer.set_property("ellipsize", pango.ELLIPSIZE_END)
147 self._unitsNameRenderer.set_property("width-chars", 5)
148 self._unitNameColumn = gtk.TreeViewColumn(_('Name'), self._unitsNameRenderer)
149 self._unitNameColumn.set_property('resizable', True)
150 self._unitNameColumn.add_attribute(self._unitsNameRenderer, 'text', self.UNITS_NAME_IDX)
151 self._unitNameColumn.set_clickable(True)
152 self._unitNameColumn.connect("clicked", self._on_click_unit_column)
153 self._unitsView.append_column(self._unitNameColumn)
155 renderer = gtk.CellRendererText()
156 renderer.set_property("xalign", 1.0)
157 renderer.set_property("alignment", pango.ALIGN_RIGHT)
158 hildonize.set_cell_thumb_selectable(renderer)
159 self._unitIntegerColumn = gtk.TreeViewColumn(_('Value'), renderer)
160 self._unitIntegerColumn.set_property('resizable', True)
161 self._unitIntegerColumn.add_attribute(renderer, 'text', self.UNITS_INTEGER_IDX)
162 self._unitIntegerColumn.set_clickable(True)
163 self._unitIntegerColumn.connect("clicked", self._on_click_unit_column)
164 self._unitsView.append_column(self._unitIntegerColumn)
166 renderer = gtk.CellRendererText()
167 renderer.set_property("xalign", 0.0)
168 renderer.set_property("alignment", pango.ALIGN_LEFT)
169 renderer.set_property("scale", 0.75)
170 self._unitFractionalColumn = gtk.TreeViewColumn(_(''), renderer)
171 self._unitFractionalColumn.set_property('resizable', True)
172 self._unitFractionalColumn.add_attribute(renderer, 'text', self.UNITS_FRACTION_IDX)
173 self._unitFractionalColumn.set_clickable(True)
174 self._unitFractionalColumn.connect("clicked", self._on_click_unit_column)
175 self._unitsView.append_column(self._unitFractionalColumn)
177 renderer = gtk.CellRendererText()
178 renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
179 #renderer.set_property("scale", 0.5)
180 self._unitSymbolColumn = gtk.TreeViewColumn(_('Units'), renderer)
181 self._unitSymbolColumn.set_property('resizable', True)
182 self._unitSymbolColumn.add_attribute(renderer, 'text', self.UNITS_SYMBOL_IDX)
183 self._unitSymbolColumn.set_clickable(True)
184 self._unitSymbolColumn.connect("clicked", self._on_click_unit_column)
185 self._unitsView.append_column(self._unitSymbolColumn)
187 self._unitModel = gtk.ListStore(
188 gobject.TYPE_STRING, # UNITS_NAME_IDX
189 gobject.TYPE_STRING, # UNITS_VALUE_IDX
190 gobject.TYPE_STRING, # UNITS_SYMBOL_IDX
191 gobject.TYPE_STRING, # UNITS_INTEGER_IDX
192 gobject.TYPE_STRING, # UNITS_FRACTION_IDX
194 self._sortedUnitModel = gtk.TreeModelSort(self._unitModel)
195 columns = self._get_column_sort_stuff()
196 for columnIndex, (column, sortDirection, col_cmp) in enumerate(columns):
197 self._sortedUnitModel.set_sort_func(columnIndex, col_cmp)
198 self._unitsView.set_model(self._sortedUnitModel)
200 #Insert a column into the category list even though the heading will not be seen
201 renderer = gtk.CellRendererText()
202 self._categoryColumn = gtk.TreeViewColumn('Title', renderer)
203 self._categoryColumn.set_property('resizable', 1)
204 self._categoryColumn.add_attribute(renderer, 'text', 0)
205 self._categoryView.append_column(self._categoryColumn)
207 self._categoryModel = gtk.ListStore(gobject.TYPE_STRING)
208 self._categoryView.set_model(self._categoryModel)
209 #colourize each row differently for easier reading
210 self._categoryView.set_property('rules_hint', 1)
212 #Populate the catagories list
213 for key in unit_data.UNIT_CATEGORIES:
215 self._categoryModel.append(row)
217 #--------- connections to GUI ----------------
218 self._mainWindow.connect("delete-event", self._on_user_exit)
219 self._mainWindow.connect("key-press-event", self._on_key_press)
220 self._mainWindow.connect("window-state-event", self._on_window_state_change)
221 self._categorySelectionButton.connect("clicked", self._on_category_selector_clicked)
222 self._categoryView.connect("cursor-changed", self._on_click_category)
223 self._findButton.connect("clicked", self._on_find_activate)
224 self._findEntry.connect("activate", self._on_find_activate)
225 self._findEntry.connect("changed", self._on_findEntry_changed)
226 self._previousUnitValue.connect("changed", self._on_previous_unit_value_changed)
227 self._unitValue.connect("changed", self._on_unit_value_changed)
228 self._unitsView.connect("cursor-changed", self._on_click_unit)
229 if hildonize.GTK_MENU_USED:
230 widgets.get_widget("aboutMenuItem").connect("activate", self._on_about_clicked)
231 widgets.get_widget("exitMenuItem").connect("activate", self._on_user_exit)
233 for scrollingWidgetName in (
234 "unitsViewScrolledWindow",
236 scrollingWidget = widgets.get_widget(scrollingWidgetName)
237 assert scrollingWidget is not None, scrollingWidgetName
238 hildonize.hildonize_scrollwindow_with_viewport(scrollingWidget)
240 if hildonize.IS_HILDON_SUPPORTED or FORCE_HILDON_LIKE:
241 self._categoryView.get_parent().hide()
242 self._unitsView.set_headers_visible(False)
243 self._previousUnitName.get_parent().hide()
244 self._unitDescription.get_parent().get_parent().hide()
246 self._categorySelectionButton.hide()
248 replacementButtons = []
249 menu = hildonize.hildonize_menu(
251 widgets.get_widget("mainMenuBar"),
255 if not hildonize.IS_HILDON_SUPPORTED:
256 _moduleLogger.info("No hildonization support")
258 hildonize.set_application_title(
259 self._mainWindow, "%s - Unit Conversion Utility" % constants.__pretty_app_name__
261 iconPath = pixmapspath + '/gonvert.png'
262 if os.path.exists(iconPath):
263 self._mainWindow.set_icon(gtk.gdk.pixbuf_new_from_file(iconPath))
265 _moduleLogger.warn("Error: Could not find gonvert icon: %s" % iconPath)
267 self._load_settings()
268 self._mainWindow.show()
270 def _load_settings(self):
271 #Restore window size from previously saved settings if it exists and is valid.
272 windowDatPath = "/".join((constants._data_path_, "window.dat"))
273 if os.path.exists(windowDatPath):
274 saved_window = pickle.load(open(windowDatPath, "r"))
276 a, b = saved_window['size']
280 self._mainWindow.resize(a, b)
282 #Restore selections from previously saved settings if it exists and is valid.
284 selectedCategoryName = unit_data.UNIT_CATEGORIES[0]
285 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
286 if os.path.exists(selectionsDatPath):
287 selections = pickle.load(open(selectionsDatPath, 'r'))
289 self._defaultUnitForCategory = selections['selected_units']
294 selectedCategoryName = selections['selected_category']
299 categoryIndex = unit_data.UNIT_CATEGORIES.index(selectedCategoryName)
301 _moduleLogger.warn("Unknown category: %s" % selectedCategoryName)
303 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % selectedCategoryName)
304 self._categoryView.set_cursor(categoryIndex, self._categoryColumn, False)
305 self._categoryView.grab_focus()
307 self._select_default_unit()
309 def _save_settings(self):
311 This routine saves the selections to a file, and
312 should therefore only be called when exiting the program.
314 Update selections dictionary which consists of the following keys:
315 'self._selectedCategoryName': full name of selected category
316 'self._defaultUnitForCategory': self._defaultUnitForCategory dictionary which contains:
317 [categoryname: #1 displayed unit, #2 displayed unit]
319 #Determine the contents of the selected category row
320 selected, iter = self._categoryView.get_selection().get_selected()
321 self._selectedCategoryName = self._categoryModel.get_value(iter, 0)
324 'selected_category': self._selectedCategoryName,
325 'selected_units': self._defaultUnitForCategory
327 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
328 pickle.dump(selections, open(selectionsDatPath, 'w'))
330 #Get last size of app and save it
332 'size': self._mainWindow.get_size()
334 windowDatPath = "/".join((constants._data_path_, "window.dat"))
335 pickle.dump(window_settings, open(windowDatPath, 'w'))
337 def _refresh_columns(self):
338 self._unitsView.remove_column(self._unitNameColumn)
339 self._unitsView.remove_column(self._unitIntegerColumn)
340 self._unitsView.remove_column(self._unitFractionalColumn)
341 self._unitsView.remove_column(self._unitSymbolColumn)
343 self._unitsView.append_column(self._unitNameColumn)
344 self._unitsView.append_column(self._unitIntegerColumn)
345 self._unitsView.append_column(self._unitFractionalColumn)
346 self._unitsView.append_column(self._unitSymbolColumn)
348 def _clear_find(self):
349 # switch to "new find" state
350 self._find_result = []
353 # Clear our user message
354 self._findLabel.set_text('')
356 def _find_first(self):
357 assert len(self._find_result) == 0
358 assert self._findIndex == 0
359 findString = self._findEntry.get_text().strip().lower()
363 # Gather info on all the matching units from all categories
364 for catIndex, category in enumerate(unit_data.UNIT_CATEGORIES):
365 units = unit_data.get_units(category)
366 for unitIndex, unit in enumerate(units):
367 loweredUnit = unit.lower()
368 if loweredUnit in findString or findString in loweredUnit:
369 self._find_result.append((category, unit, catIndex, unitIndex))
371 def _update_find_selection(self):
372 assert 0 < len(self._find_result)
374 #check if next find is in a new category (prevent category changes when unnecessary
375 searchCategoryName = self._find_result[self._findIndex][0]
376 if self._selectedCategoryName != searchCategoryName:
377 self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % searchCategoryName)
378 self._categoryView.set_cursor(
379 self._find_result[self._findIndex][2], self._categoryColumn, False
382 self._unitsView.set_cursor(
383 self._find_result[self._findIndex][3], self._unitNameColumn, True
386 def _find_next(self):
387 if len(self._find_result) == 0:
390 if self._findIndex == len(self._find_result)-1:
395 if not self._find_result:
396 self._findLabel.set_text('Text not found')
398 self._update_find_selection()
399 resultsLeft = len(self._find_result) - self._findIndex - 1
400 self._findLabel.set_text(
401 '%s result(s) left' % (resultsLeft, )
404 def _find_previous(self):
405 if len(self._find_result) == 0:
408 if self._findIndex == 0:
409 self._findIndex = len(self._find_result)-1
413 if not self._find_result:
414 self._findLabel.set_text('Text not found')
416 self._update_find_selection()
417 resultsLeft = len(self._find_result) - self._findIndex - 1
418 self._findLabel.set_text(
419 '%s result(s) left' % (resultsLeft, )
422 def _toggle_find(self):
423 if self._searchLayout.get_property("visible"):
424 self._searchLayout.hide()
425 self._unitsView.grab_focus()
427 self._searchLayout.show()
428 self._findEntry.grab_focus()
430 def _unit_model_cmp(self, sortedModel, leftItr, rightItr):
431 leftUnitText = self._unitModel.get_value(leftItr, self.UNITS_NAME_IDX)
432 rightUnitText = self._unitModel.get_value(rightItr, self.UNITS_NAME_IDX)
433 return cmp(leftUnitText, rightUnitText)
435 def _symbol_model_cmp(self, sortedModel, leftItr, rightItr):
436 leftSymbolText = self._unitModel.get_value(leftItr, self.UNITS_SYMBOL_IDX)
437 rightSymbolText = self._unitModel.get_value(rightItr, self.UNITS_SYMBOL_IDX)
438 return cmp(leftSymbolText, rightSymbolText)
440 def _value_model_cmp(self, sortedModel, leftItr, rightItr):
441 #special sorting exceptions for ascii values (instead of float values)
442 if self._selectedCategoryName == "Computer Numbers":
443 leftValue = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
444 rightValue = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
446 leftValueText = self._unitModel.get_value(leftItr, self.UNITS_VALUE_IDX)
447 leftValue = float(leftValueText) if leftValueText else 0.0
449 rightValueText = self._unitModel.get_value(rightItr, self.UNITS_VALUE_IDX)
450 rightValue = float(rightValueText) if rightValueText else 0.0
451 return cmp(leftValue, rightValue)
453 def _get_column_sort_stuff(self):
455 (self._unitNameColumn, "_unit_sort_direction", self._unit_model_cmp),
456 (self._unitIntegerColumn, "_value_sort_direction", self._value_model_cmp),
457 (self._unitFractionalColumn, "_value_sort_direction", self._value_model_cmp),
458 (self._unitSymbolColumn, "_units_sort_direction", self._symbol_model_cmp),
462 def _switch_category(self, category):
463 self._selectedCategoryName = category
464 self._unitDataInCategory = unit_data.UNIT_DESCRIPTIONS[self._selectedCategoryName]
466 #Fill up the units descriptions and clear the value cells
467 self._clear_visible_unit_data()
469 for key in unit_data.get_units(self._selectedCategoryName):
470 row = key, '0.0', self._unitDataInCategory[key][1], '0.', '0'
471 self._unitModel.append(row)
472 nameLength = max(nameLength, len(key))
473 self._sortedUnitModel.sort_column_changed()
475 if FORCE_HILDON_LIKE:
476 maxCatCharWidth = int(nameLength * 0.75)
477 maxCharWidth = int(len("nibble | hexit | quadbit") * 0.75)
478 charWidth = min(maxCatCharWidth, maxCharWidth)
479 self._unitsNameRenderer.set_property("width-chars", charWidth)
481 self._select_default_unit()
483 def _clear_visible_unit_data(self):
484 self._unitDescription.get_buffer().set_text("")
485 self._unitName.set_text('')
486 self._unitValue.set_text('')
487 self._unitSymbol.set_text('')
489 self._previousUnitName.set_text('')
490 self._previousUnitValue.set_text('')
491 self._previousUnitSymbol.set_text('')
493 self._unitModel.clear()
495 def _select_default_unit(self):
496 # Restore the previous historical settings of previously selected units
497 # in this newly selected category
498 defaultPrimary = unit_data.get_base_unit(self._selectedCategoryName)
499 defaultSecondary = ""
500 if self._selectedCategoryName in self._defaultUnitForCategory:
501 if self._defaultUnitForCategory[self._selectedCategoryName][0]:
502 defaultPrimary = self._defaultUnitForCategory[self._selectedCategoryName][0]
503 if self._defaultUnitForCategory[self._selectedCategoryName][1]:
504 defaultSecondary = self._defaultUnitForCategory[self._selectedCategoryName][1]
506 units = unit_data.get_units(self._selectedCategoryName)
508 #Restore oldest selection first.
511 unitIndex = units.index(defaultPrimary)
514 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
516 #Restore newest selection second.
519 unitIndex = units.index(defaultSecondary)
522 self._unitsView.set_cursor(unitIndex, self._unitNameColumn, True)
524 # select the text so user can start typing right away
525 self._unitValue.grab_focus()
526 self._unitValue.select_region(0, -1)
528 def _sanitize_value(self, userEntry):
529 if self._selectedCategoryName == "Computer Numbers":
538 value = float(userEntry)
541 def _on_key_press(self, widget, event, *args):
543 @note Hildon specific
545 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
548 event.keyval == gtk.keysyms.F6 or
549 event.keyval in RETURN_TYPES and event.get_state() & gtk.gdk.CONTROL_MASK
551 if self._isFullScreen:
552 self._mainWindow.unfullscreen()
554 self._mainWindow.fullscreen()
555 elif event.keyval == gtk.keysyms.f and event.get_state() & gtk.gdk.CONTROL_MASK:
557 elif event.keyval == gtk.keysyms.p and event.get_state() & gtk.gdk.CONTROL_MASK:
558 self._find_previous()
559 elif event.keyval == gtk.keysyms.n and event.get_state() & gtk.gdk.CONTROL_MASK:
561 elif event.keyval == ord("l") and event.get_state() & gtk.gdk.CONTROL_MASK:
562 with open(constants._user_logpath_, "r") as f:
563 logLines = f.xreadlines()
564 log = "".join(logLines)
565 self._clipboard.set_text(str(log))
567 _moduleLogger.exception("_on_key_press")
569 def _on_window_state_change(self, widget, event, *args):
571 @note Hildon specific
574 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
575 self._isFullScreen = True
577 self._isFullScreen = False
579 _moduleLogger.exception("_on_window_state_change")
581 def _on_findEntry_changed(self, *args):
583 Clear out find results since the user wants to look for something new
588 _moduleLogger.exception("_on_findEntry_changed")
590 def _on_find_activate(self, *args):
593 self._findButton.grab_focus()
595 _moduleLogger.exception("_on_find_activate")
597 def _on_click_unit_column(self, col):
599 Sort the contents of the col when the user clicks on the title.
602 #Determine which column requires sorting
603 columns = self._get_column_sort_stuff()
604 for columnIndex, (maybeCol, directionName, col_cmp) in enumerate(columns):
606 direction = getattr(self, directionName)
607 gtkDirection = gtk.SORT_ASCENDING if direction else gtk.SORT_DESCENDING
610 self._sortedUnitModel.set_sort_column_id(columnIndex, gtkDirection)
612 # set the visual for sorting
613 col.set_sort_indicator(True)
614 col.set_sort_order(not direction)
616 setattr(self, directionName, not direction)
619 maybeCol.set_sort_indicator(False)
621 assert False, "Unknown column: %s" % (col.get_title(), )
623 _moduleLogger.exception("_on_click_unit_column")
625 def _on_category_selector_clicked(self, *args):
627 currenntIndex = unit_data.UNIT_CATEGORIES.index(self._selectedCategoryName)
628 newIndex = hildonize.touch_selector(
631 unit_data.UNIT_CATEGORIES,
635 selectedCategoryName = unit_data.UNIT_CATEGORIES[newIndex]
636 self._categorySelectionButton.set_label(selectedCategoryName)
637 self._categoryView.set_cursor(newIndex, self._categoryColumn, False)
638 self._categoryView.grab_focus()
640 _moduleLogger.exception("_on_category_selector_clicked")
642 def _on_click_category(self, *args):
644 selected, iter = self._categoryView.get_selection().get_selected()
646 # User is typing in an invalid string, not selecting any category
648 selectedCategory = self._categoryModel.get_value(iter, 0)
649 self._switch_category(selectedCategory)
651 _moduleLogger.exception("_on_click_category")
653 def _on_click_unit(self, *args):
655 selected, iter = self._unitsView.get_selection().get_selected()
656 selected_unit = selected.get_value(iter, self.UNITS_NAME_IDX)
657 unit_spec = self._unitDataInCategory[selected_unit]
661 if self._unitName.get_text() != selected_unit:
662 self._previousUnitName.set_text(self._unitName.get_text())
663 self._previousUnitValue.set_text(self._unitValue.get_text())
664 self._previousUnitSymbol.set_text(self._unitSymbol.get_text())
665 if self._unitSymbol.get_text():
668 self._unitName.set_text(selected_unit)
669 self._unitValue.set_text(selected.get_value(iter, self.UNITS_VALUE_IDX))
670 buffer = self._unitDescription.get_buffer()
671 buffer.set_text(unit_spec[2])
672 self._unitSymbol.set_text(unit_spec[1]) # put units into label text
679 self._unitSymbol.show()
680 self._previousUnitSymbol.show()
682 self._unitSymbol.hide()
683 self._previousUnitSymbol.hide()
685 if self._unitValue.get_text() == '':
686 if self._selectedCategoryName == "Computer Numbers":
687 self._unitValue.set_text("0")
689 self._unitValue.set_text("0.0")
691 self._defaultUnitForCategory[self._selectedCategoryName] = [
692 self._unitName.get_text(), self._previousUnitName.get_text()
695 # select the text so user can start typing right away
696 self._unitValue.grab_focus()
697 self._unitValue.select_region(0, -1)
699 _moduleLogger.exception("_on_click_unit")
701 def _on_unit_value_changed(self, *args):
703 if self._unitName.get_text() == '':
705 if not self._unitValue.is_focus():
708 #retrieve the conversion function and value from the selected unit
709 value = self._sanitize_value(self._unitValue.get_text())
710 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
711 base = func.to_base(value, arg)
713 #point to the first row
714 for row in self._unitModel:
715 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
716 newValue = func.from_base(base, arg)
718 newValueDisplay = str(newValue)
719 integerDisplay, fractionalDisplay = split_number(newValue)
721 row[self.UNITS_VALUE_IDX] = newValueDisplay
722 row[self.UNITS_INTEGER_IDX] = integerDisplay
723 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
725 # Update the secondary unit entry
726 if self._previousUnitName.get_text() != '':
727 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
728 self._previousUnitValue.set_text(str(func.from_base(base, arg, )))
730 self._sortedUnitModel.sort_column_changed()
731 self._refresh_columns()
733 _moduleLogger.exception("_on_unit_value_changed")
735 def _on_previous_unit_value_changed(self, *args):
737 if self._previousUnitName.get_text() == '':
739 if not self._previousUnitValue.is_focus():
742 #retrieve the conversion function and value from the selected unit
743 value = self._sanitize_value(self._previousUnitValue.get_text())
744 func, arg = self._unitDataInCategory[self._previousUnitName.get_text()][0]
745 base = func.to_base(value, arg)
747 #point to the first row
748 for row in self._unitModel:
749 func, arg = self._unitDataInCategory[row[self.UNITS_NAME_IDX]][0]
750 newValue = func.from_base(base, arg)
752 newValueDisplay = str(newValue)
753 integerDisplay, fractionalDisplay = split_number(newValue)
755 row[self.UNITS_VALUE_IDX] = newValueDisplay
756 row[self.UNITS_INTEGER_IDX] = integerDisplay
757 row[self.UNITS_FRACTION_IDX] = fractionalDisplay
759 # Update the primary unit entry
760 func, arg = self._unitDataInCategory[self._unitName.get_text()][0]
761 self._unitValue.set_text(str(func.from_base(base, arg, )))
763 self._sortedUnitModel.sort_column_changed()
764 self._refresh_columns()
766 _moduleLogger.exception("_on_previous_unit_value_changed")
768 def _on_about_clicked(self, a):
769 dlg = gtk.AboutDialog()
770 dlg.set_name(constants.__pretty_app_name__)
771 dlg.set_version("%s-%d" % (constants.__version__, constants.__build__))
772 dlg.set_copyright("Copyright 2009 - GPL")
774 dlg.set_website("http://unihedron.com/projects/gonvert/gonvert.php")
775 dlg.set_authors(["Anthony Tekatch <anthony@unihedron.com>", "Ed Page <edpage@byu.net>"])
779 def _on_user_exit(self, *args):
781 self._save_settings()
783 _moduleLogger.exception("_on_user_exit")
789 gtk.gdk.threads_init()
790 if hildonize.IS_HILDON_SUPPORTED:
791 gtk.set_application_name(constants.__pretty_app_name__)
793 if not PROFILE_STARTUP:
797 if __name__ == "__main__":
798 logging.basicConfig(level = logging.DEBUG)
800 os.makedirs(constants._data_path_)