0c2734415e89c04228d4bec25239d2e1abc2d8d0
[gonvert] / src / gonvert_glade.py
1 #!/usr/bin/env python
2 # -*- coding: UTF8 -*-
3
4 import os
5 import pickle
6 import string
7 import sys
8 import gettext
9 import logging
10
11 import gobject
12 import gtk
13 import gtk.glade
14 import gtk.gdk
15
16 import constants
17 import evil_globals
18 import unit_data
19
20
21 _moduleLogger = logging.getLogger("gonvert_glade")
22
23 gettext.bindtextdomain('gonvert', '/usr/share/locale')
24 gettext.textdomain('gonvert')
25 _ = gettext.gettext
26
27
28 def shortlist_changed(a):
29         print "shortlist"
30         if shortlistcheck.get_active():
31                 print "1"
32         else:
33                 print "0"
34
35
36 def edit_shortlist(a):
37         print "edit shortlist"
38         if toggleShortList.get_active():
39                 print "1"
40         else:
41                 print "0"
42
43
44 def app_size_changed(a, b):
45         ''"get current size of window as it changes.''"
46         evil_globals.window_size = mainWindow.get_size()
47
48
49 def clear_selections(a):
50         selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
51         os.remove(selectionsDatPath)
52         evil_globals.selected_units = {}
53
54
55 def exitprogram(a):
56         """
57         This routine saves the selections to a file, and
58         should therefore only be called when exiting the program.
59
60         Update selections dictionary which consists of the following keys:
61         'evil_globals.selected_category': full name of selected category
62         'evil_globals.selected_units': evil_globals.selected_units dictionary which contains:
63         [categoryname: #1 displayed unit, #2 displayed unit]
64         """
65         #Determine the contents of the selected category row
66         selected, iter = categoryView.get_selection().get_selected()
67         evil_globals.selected_category = categoryModel.get_value(iter, 0)
68
69         selections = {'evil_globals.selected_category': evil_globals.selected_category, 'evil_globals.selected_units': evil_globals.selected_units}
70         selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
71         pickle.dump(selections, open(selectionsDatPath, 'w'))
72
73         #Get last size of app and save it
74         window_settings = {'size': evil_globals.window_size}
75         windowDatPath = "/".join((constants._data_path_, "window.dat"))
76         pickle.dump(window_settings, open(windowDatPath, 'w'))
77
78         gtk.mainquit
79         sys.exit()
80
81
82 def findEntry_changed(a):
83         #Clear out find results since the user wants to look for something new
84         evil_globals.find_result = [] #empty find result list
85         evil_globals.find_count = 0 #default to find result number zero
86         findLabel.set_text('') #clear result
87
88
89 def find_key_press(a, b):
90         #Check if the key pressed was an ASCII key
91         if len(b.string)>0:
92                 #Check if the key pressed was the 'Enter' key
93                 if ord(b.string[0]) == 13:
94                         #Execute the find units function
95                         find_units(1)
96
97
98 def about_clicked(a):
99         about_box.show()
100
101
102 def about_hide(*args):
103         about_box.hide()
104         return gtk.TRUE
105
106
107 def messagebox_ok_clicked(a):
108         messagebox.hide()
109
110
111 def find_units(a):
112         global unitNameColumn
113         global categoryColumn
114         #check if 'new find' or 'last find' or 'next-find'
115
116         #new-find = run the find algorithm which also selects the first found unit
117         #         = evil_globals.find_count = 0 and evil_globals.find_result = []
118
119         #last-find = restart from top again
120         #          = evil_globals.find_count = len(evil_globals.find_result)
121
122         #next-find = continue to next found location
123         #           = evil_globals.find_count = 0 and len(evil_globals.find_result)>0
124
125         #check for new-find
126         if len(evil_globals.find_result) == 0:
127                 find_string = string.lower(string.strip(findEntry.get_text()))
128                 #Make sure that a valid find string has been requested
129                 if len(find_string)>0:
130                         categories = unit_data.list_dic.keys()
131                         categories.sort()
132                         found_a_unit = 0 #reset the 'found-a-unit' flag
133                         cat_no = 0
134                         for category in categories:
135                                 units = unit_data.list_dic[category].keys()
136                                 units.sort()
137                                 del units[0] # do not display .base_unit description key
138                                 unit_no = 0
139                                 for unit in units:
140                                         if string.find(string.lower(unit), find_string) >= 0:
141                                                 found_a_unit = 1 #indicate that a unit was found
142                                                 #print "'", find_string, "'", " found at category = ", category, " unit = ", unit
143                                                 evil_globals.find_result.append((category, unit, cat_no, unit_no))
144                                         unit_no = unit_no+1
145                                 cat_no = cat_no+1
146
147                         if found_a_unit == 1:
148                                 #select the first found unit
149                                 evil_globals.find_count = 0
150                                 #check if next find is in a new category (prevent category changes when unnecessary
151                                 if evil_globals.selected_category != evil_globals.find_result[evil_globals.find_count][0]:
152                                         categoryView.set_cursor(evil_globals.find_result[0][2], categoryColumn, False)
153                                         unitsView.set_cursor(evil_globals.find_result[0][3], unitNameColumn, True)
154                                         if len(evil_globals.find_result)>1:
155                                                 findLabel.set_text(('Press Find for next unit. '+ str(len(evil_globals.find_result))+' result(s).'))
156                                         else:
157                                                 findLabel.set_text('Text not found') #Display error
158         else: #must be next-find or last-find
159                 #check for last-find
160                 if evil_globals.find_count == len(evil_globals.find_result)-1:
161                         #select first result
162                         evil_globals.find_count = 0
163                         categoryView.set_cursor(evil_globals.find_result[evil_globals.find_count][2], categoryColumn, False)
164                         unitsView.set_cursor(evil_globals.find_result[evil_globals.find_count][3], unitNameColumn, True)
165                 else: #must be next-find
166                         evil_globals.find_count = evil_globals.find_count+1
167                         #check if next find is in a new category (prevent category changes when unnecessary
168                         if evil_globals.selected_category != evil_globals.find_result[evil_globals.find_count][0]:
169                                 categoryView.set_cursor(evil_globals.find_result[evil_globals.find_count][2], categoryColumn, False)
170                         unitsView.set_cursor(evil_globals.find_result[evil_globals.find_count][3], unitNameColumn, True)
171
172
173 def click_unit_column(col):
174         """
175         Sort the contents of the col when the user clicks on the title.
176         """
177         global unitNameColumn
178         global unitValueColumn
179         global unitSymbolColumn
180         global unitModel
181
182         #Determine which column requires sorting
183         if col is unitNameColumn:
184                 selectedUnitColumn = 0
185                 unitNameColumn.set_sort_indicator(True)
186                 unitValueColumn.set_sort_indicator(False)
187                 unitSymbolColumn.set_sort_indicator(False)
188                 unitNameColumn.set_sort_order(not evil_globals.unit_sort_direction)
189         elif col is unitValueColumn:
190                 selectedUnitColumn = 1
191                 unitNameColumn.set_sort_indicator(False)
192                 unitValueColumn.set_sort_indicator(True)
193                 unitSymbolColumn.set_sort_indicator(False)
194                 unitValueColumn.set_sort_order(not evil_globals.value_sort_direction)
195         elif col is unitSymbolColumn:
196                 selectedUnitColumn = 2
197                 unitNameColumn.set_sort_indicator(False)
198                 unitValueColumn.set_sort_indicator(False)
199                 unitSymbolColumn.set_sort_indicator(True)
200                 unitSymbolColumn.set_sort_order(not evil_globals.units_sort_direction)
201         else:
202                 assert False, "Unknown column: %s" % (col.get_title(), )
203
204         #declare a spot to hold the sorted list
205         sorted_list = []
206
207         #point to the first row
208         iter = unitModel.get_iter_first()
209         row = 0
210
211         while iter:
212                 #grab all text from columns for sorting
213
214                 #get the text from each column
215                 unit_text = unitModel.get_value(iter, 0)
216                 units_text = unitModel.get_value(iter, 2)
217
218                 #do not bother sorting if the value column is empty
219                 if unitModel.get_value(iter, 1) == '' and selectedUnitColumn == 1:
220                         return
221
222                 #special sorting exceptions for ascii values (instead of float values)
223                 if evil_globals.selected_category == "Computer Numbers":
224                         value_text = unitModel.get_value(iter, 1)
225                 else:
226                         if unitModel.get_value(iter, 1) == None or unit_model.get_value(iter, 1) == '':
227                                 value_text = ''
228                         else:
229                                 value_text = float(unitModel.get_value(iter, 1))
230
231                 if selectedUnitColumn == 0:
232                         sorted_list.append((unit_text, value_text, units_text))
233                 elif selectedUnitColumn == 1:
234                         sorted_list.append((value_text, unit_text, units_text))
235                 else:
236                         sorted_list.append((units_text, value_text, unit_text))
237
238                 #point to the next row in the unitModel
239                 iter = unitModel.iter_next(iter)
240                 row = row+1
241
242         #check if no calculations have been made yet (don't bother sorting)
243         if row == 0:
244                 return
245         else:
246                 if selectedUnitColumn == 0:
247                         if not evil_globals.unit_sort_direction:
248                                 sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(x), string.lower(y)))
249                                 evil_globals.unit_sort_direction = True
250                         else:
251                                 sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(y), string.lower(x)))
252                                 evil_globals.unit_sort_direction = False
253                 elif selectedUnitColumn == 1:
254                         sorted_list.sort()
255                         if not evil_globals.value_sort_direction:
256                                 evil_globals.value_sort_direction = True
257                         else:
258                                 sorted_list.reverse()
259                                 evil_globals.value_sort_direction = False
260                 else:
261                         if not evil_globals.units_sort_direction:
262                                 sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(x), string.lower(y)))
263                                 evil_globals.units_sort_direction = True
264                         else:
265                                 sorted_list.sort(lambda (x, xx, xxx), (y, yy, yyy): cmp(string.lower(y), string.lower(x)))
266                                 evil_globals.units_sort_direction = False
267
268                 #Clear out the previous list of units
269                 unitModel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
270                 unitsView.set_model(unitModel)
271
272                 #colourize each row differently for easier reading
273                 unitsView.set_property('rules_hint', 1)
274
275                 #Clear out the description
276                 text_model = gtk.TextBuffer(None)
277                 unitDescription.set_buffer(text_model)
278
279                 if selectedUnitColumn == 0:
280                         for unit, value, units in sorted_list:
281                                 iter = unitModel.append()
282                                 unitModel.set(iter, 0, unit, 1, str(value), 2, units)
283                 elif selectedUnitColumn == 1:
284                         for value, unit, units in sorted_list:
285                                 iter = unitModel.append()
286                                 unitModel.set(iter, 0, unit, 1, str(value), 2, units)
287                 else:
288                         for units, value, unit in sorted_list:
289                                 iter = unitModel.append()
290                                 unitModel.set(iter, 0, unit, 1, str(value), 2, units)
291         return
292
293
294 def click_category(row):
295         global unitModel, categoryModel
296         global unitDataInCategory, list_dic
297
298         #Clear out the previous list of units
299         unitModel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
300         unitsView.set_model(unitModel)
301
302         #Colourize each row alternately for easier reading
303         unitsView.set_property('rules_hint', 1)
304
305         #Clear out the description
306         text_model = gtk.TextBuffer(None)
307         unitDescription.set_buffer(text_model)
308
309         #Determine the contents of the selected category row
310         selected, iter = row.get_selection().get_selected()
311
312         evil_globals.selected_category = categoryModel.get_value(iter, 0)
313
314         evil_globals.unit_sort_direction = False
315         evil_globals.value_sort_direction = False
316         evil_globals.units_sort_direction = False
317         unitNameColumn.set_sort_indicator(False)
318         unitValueColumn.set_sort_indicator(False)
319         unitSymbolColumn.set_sort_indicator(False)
320
321         unitDataInCategory = unit_data.list_dic[selected.get_value(iter, 0)]
322         keys = unitDataInCategory.keys()
323         keys.sort()
324         del keys[0] # do not display .base_unit description key
325
326         #Fill up the units descriptions and clear the value cells
327         for key in keys:
328                 iter = unitModel.append()
329                 unitModel.set(iter, 0, key, 1, '', 2, unitDataInCategory[key][1])
330
331         unitName.set_text('')
332         unitValue.set_text('')
333         previousUnitName.set_text('')
334         previousUnitValue.set_text('')
335         unitSymbol.set_text('')
336         previousUnitSymbol.set_text('')
337
338         restore_units()
339
340
341 def restore_units():
342         global unitDataInCategory, list_dic
343
344         # Restore the previous historical settings of previously selected units in this newly selected category
345         #Since category has just been clicked, the list will be sorted already.
346         if evil_globals.selected_category in evil_globals.selected_units:
347                 if evil_globals.selected_units[evil_globals.selected_category][0]:
348                         ''"debug ''"
349                         #evil_globals.selected_units[evil_globals.selected_category] = [selected_unit, evil_globals.selected_units[evil_globals.selected_category][0]]
350
351                         units = unit_data.list_dic[evil_globals.selected_category].keys()
352                         units.sort()
353                         del units[0] # do not display .base_unit description key
354
355                         #Restore oldest selection first.
356                         if evil_globals.selected_units[evil_globals.selected_category][1]:
357                                 unit_no = 0
358                                 for unit in units:
359                                         if unit == evil_globals.selected_units[evil_globals.selected_category][1]:
360                                                 unitsView.set_cursor(unit_no, unitNameColumn, True)
361                                         unit_no = unit_no+1
362
363                         #Restore newest selection second.
364                         unit_no = 0
365                         for unit in units:
366                                 if unit == evil_globals.selected_units[evil_globals.selected_category][0]:
367                                         unitsView.set_cursor(unit_no, unitNameColumn, True)
368                                 unit_no = unit_no+1
369
370         # select the text so user can start typing right away
371         unitValue.grab_focus()
372         unitValue.select_region(0, -1)
373
374
375 def button_released(row, a):
376         click_unit(row)
377
378
379 def click_unit(row):
380         evil_globals.calcsuppress = 1 #suppress calculations
381
382         #Determine the contents of the selected row.
383         selected, iter = unitsView.get_selection().get_selected()
384
385         selected_unit = selected.get_value(iter, 0)
386
387         unit_spec = unitDataInCategory[selected_unit]
388
389         #Clear out the description
390         text_model = gtk.TextBuffer(None)
391         unitDescription.set_buffer(text_model)
392
393         enditer = text_model.get_end_iter()
394         text_model.insert(enditer, unit_spec[2])
395
396         if unitName.get_text() != selected_unit:
397                 previousUnitName.set_text(unitName.get_text())
398                 previousUnitValue.set_text(unitValue.get_text())
399                 if unitSymbol.get() == None:
400                         previousUnitSymbol.set_text('')
401                 else:
402                         previousUnitSymbol.set_text(unitSymbol.get())
403         unitName.set_text(selected_unit)
404
405         unitValue.set_text(selected.get_value(iter, 1))
406
407         unitSymbol.set_text(unit_spec[1]) # put units into label text
408         if unitValue.get_text() == '':
409                 if evil_globals.selected_category == "Computer Numbers":
410                         unitValue.set_text("0")
411                 else:
412                         unitValue.set_text("0.0")
413
414         #For historical purposes, record this unit as the most recent one in this category.
415         # Also, if a previous unit exists, then shift that previous unit to oldest unit.
416         if evil_globals.selected_category in evil_globals.selected_units:
417                 if evil_globals.selected_units[evil_globals.selected_category][0]:
418                         evil_globals.selected_units[evil_globals.selected_category] = [selected_unit, evil_globals.selected_units[evil_globals.selected_category][0]]
419         else:
420                 evil_globals.selected_units[evil_globals.selected_category] = [selected_unit, '']
421
422         # select the text so user can start typing right away
423         unitValue.grab_focus()
424         unitValue.select_region(0, -1)
425
426         evil_globals.calcsuppress = 0 #enable calculations
427
428
429 def write_units(a):
430         ''"Write the list of categories and units to stdout for documentation purposes.''"
431         messagebox_model = gtk.TextBuffer(None)
432         messageboxtext.set_buffer(messagebox_model)
433         messagebox_model.insert_at_cursor(_(u'The units are being written to stdout. You can capture this printout by starting gonvert from the command line as follows: \n$ gonvert > file.txt'), -1)
434         messagebox.show()
435         while gtk.events_pending():
436                 gtk.mainiteration(False)
437         category_keys = unit_data.list_dic.keys()
438         category_keys.sort()
439         total_categories = 0
440         total_units = 0
441         print 'gonvert-%s%s' % (
442                 constants.__version__,
443                 _(u' - Unit Conversion Utility  - Convertible units listing: ')
444         )
445         for category_key in category_keys:
446                 total_categories = total_categories + 1
447                 print category_key, ": "
448                 unitDataInCategory = unit_data.list_dic[category_key]
449                 unit_keys = unitDataInCategory.keys()
450                 unit_keys.sort()
451                 del unit_keys[0] # do not display .base_unit description key
452                 for unit_key in unit_keys:
453                         total_units = total_units + 1
454                         print "\t", unit_key
455         print total_categories, ' categories'
456         print total_units, ' units'
457         messagebox_model = gtk.TextBuffer(None)
458         messageboxtext.set_buffer(messagebox_model)
459         messagebox_model.insert_at_cursor(_(u'The units list has been written to stdout. You can capture this printout by starting gonvert from the command line as follows: \n$ gonvert > file.txt'), -1)
460
461
462 class Ccalculate(object):
463
464         def top(self, a):
465                 global unitModel
466                 global testvalue
467
468                 if evil_globals.calcsuppress == 1:
469                         #evil_globals.calcsuppress = 0
470                         return
471                 # determine if value to be calculated is empty
472                 if evil_globals.selected_category == "Computer Numbers":
473                         if unitValue.get_text() == '':
474                                 value = '0'
475                         else:
476                                 value = unitValue.get_text()
477                 else:
478                         if unitValue.get_text() == '':
479                                 value = 0.0
480                         else:
481                                 value = float(unitValue.get_text())
482
483                 if unitName.get_text() != '':
484                         func, arg = unitDataInCategory[unitName.get_text()][0] #retrieve the conversion function and value from the selected unit
485                         base = apply(func.to_base, (value, arg, )) #determine the base unit value
486
487                         keys = unitDataInCategory.keys()
488                         keys.sort()
489                         del keys[0]
490                         row = 0
491
492                         #point to the first row
493                         iter = unitModel.get_iter_first()
494
495                         while iter:
496                                 #get the formula from the name at the row
497                                 func, arg = unitDataInCategory[unitModel.get_value(iter, 0)][0]
498
499                                 #set the result in the value column
500                                 unitModel.set(iter, 1, str(apply(func.from_base, (base, arg, ))))
501
502                                 #point to the next row in the unitModel
503                                 iter = unitModel.iter_next(iter)
504
505                         # if the second row has a unit then update its value
506                         if previousUnitName.get_text() != '':
507                                 evil_globals.calcsuppress = 1
508                                 func, arg = unitDataInCategory[previousUnitName.get_text()][0]
509                                 previousUnitValue.set_text(str(apply(func.from_base, (base, arg, ))))
510                                 evil_globals.calcsuppress = 0
511
512         def bottom(self, a):
513                 if evil_globals.calcsuppress == 1:
514                         #evil_globals.calcsuppress = 0
515                         return
516                 # determine if value to be calculated is empty
517                 if evil_globals.selected_category == "Computer Numbers":
518                         if previousUnitValue.get_text() == '':
519                                 value = '0'
520                         else:
521                                 value = previousUnitValue.get_text()
522                 else:
523                         if previousUnitValue.get_text() == '':
524                                 value = 0.0
525                         else:
526                                 value = float(previousUnitValue.get_text())
527
528                 if previousUnitName.get_text() != '':
529                         func, arg = unitDataInCategory[previousUnitName.get_text()][0] #retrieve the conversion function and value from the selected unit
530                         base = apply(func.to_base, (value, arg, )) #determine the base unit value
531
532                         keys = unitDataInCategory.keys()
533                         keys.sort()
534                         del keys[0]
535                         row = 0
536
537                         #point to the first row
538                         iter = unitModel.get_iter_first()
539
540                         while iter:
541                                 #get the formula from the name at the row
542                                 func, arg = unitDataInCategory[unitModel.get_value(iter, 0)][0]
543
544                                 #set the result in the value column
545                                 unitModel.set(iter, 1, str(apply(func.from_base, (base, arg, ))))
546
547                                 #point to the next row in the unitModel
548                                 iter = unitModel.iter_next(iter)
549
550                         # if the second row has a unit then update its value
551                         if unitName.get_text() != '':
552                                 evil_globals.calcsuppress = 1
553                                 func, arg = unitDataInCategory[unitName.get_text()][0]
554                                 unitValue.set_text(str(apply(func.from_base, (base, arg, ))))
555                                 evil_globals.calcsuppress = 0
556
557
558 def main():
559         global mainWindow
560         global categoryView
561         global categoryModel
562         global unitValue
563         global unitName
564         global unitSymbol
565         global unitsView
566         global calculate
567         global shortlistcheck
568         global about_box
569         global unitDescription
570         global unitNameColumn
571         global unitValueColumn
572         global unitSymbolColumn
573         global previousUnitName
574         global previousUnitValue
575         global previousUnitSymbol
576         global findLabel
577         global findEntry
578         global categoryColumn
579         global toggleShortList
580
581         logging.basicConfig(level = logging.DEBUG)
582
583         try:
584                 os.makedirs(constants._data_path_)
585         except OSError, e:
586                 if e.errno != 17:
587                         raise
588
589         #check to see if glade file is in current directory (user must be running from download untar directory)
590         _glade_files = [
591                 os.path.join(os.path.dirname(__file__), "gonvert.glade"),
592                 os.path.join(os.path.dirname(__file__), "../data/gonvert.glade"),
593                 os.path.join(os.path.dirname(__file__), "../lib/gonvert.glade"),
594                 '/usr/lib/gonvert/gonvert.glade',
595         ]
596         for gladePath in _glade_files:
597                 if os.path.isfile(gladePath):
598                         homepath = os.path.dirname(gladePath)
599                         pixmapspath = "/".join((homepath, "pixmaps"))
600                         widgets = gtk.glade.XML(gladePath)
601                         break
602         else:
603                 return
604
605         calculate = Ccalculate()
606         mainWindow = widgets.get_widget('mainWindow')
607
608         #Restore window size from previously saved settings if it exists and is valid.
609         windowDatPath = "/".join((constants._data_path_, "window.dat"))
610         if os.path.exists(windowDatPath):
611                 #Retrieving previous window settings from ~/.gonvert/window.dat
612                 saved_window = pickle.load(open(windowDatPath, "r"))
613                 #If the 'size' has been stored, then extract size from saved_window.
614                 if 'size' in saved_window:
615                         a, b = saved_window['size']
616                         mainWindow.resize(a, b)
617                 else:
618                         #Maximize if no previous size was found
619                         #mainWindow.maximize()
620                         pass
621         else:
622                 #Maximize if no previous window.dat file was found
623                 #mainWindow.maximize()
624                 pass
625
626         mainWindow.set_title('gonvert- %s - Unit Conversion Utility' % constants.__version__)
627         iconPath = pixmapspath + '/gonvert.png'
628         if os.path.exists(iconPath):
629                 mainWindow.set_icon(gtk.gdk.pixbuf_new_from_file(iconPath))
630         else:
631                 _moduleLogger.warn("Error: Could not find gonvert icon: %s" % iconPath)
632
633         #--------- connections to GUI ----------------
634         dic = {
635                 "on_exitMenuItem_activate": exitprogram,
636                 "on_mainWindow_destroy": exitprogram,
637                 "on_categoryView_select_row": click_category,
638                 "on_unitsView_click_unit_column": click_unit_column,
639                 "on_unitValue_changed": calculate.top,
640                 "on_previousUnitValue_changed": calculate.bottom,
641                 "on_writeUnitsMenuItem_activate": write_units,
642                 "on_findButton_clicked": find_units,
643                 "on_findEntry_key_press_event": find_key_press,
644                 "on_findEntry_changed": findEntry_changed,
645                 "on_about1_activate": about_clicked,
646                 "on_about_close_clicked": about_hide,
647                 "on_messagebox_ok_clicked": messagebox_ok_clicked,
648                 "on_clearSelectionMenuItem_activate": clear_selections,
649                 "on_unitsView_cursor_changed": click_unit,
650                 "on_unitsView_button_released": button_released,
651                 "on_mainWindow_size_allocate": app_size_changed,
652                 "on_shortlistcheck_toggled": shortlist_changed,
653                 "on_toggleShortList_activate": edit_shortlist,
654         }
655
656         widgets.signal_autoconnect(dic)
657         mainWindow.connect("destroy", exitprogram)
658
659         def change_menu_label(labelname, newtext):
660                 item_label = widgets.get_widget(labelname).get_children()[0]
661                 item_label.set_text(newtext)
662
663         def change_label(labelname, newtext):
664                 item_label = widgets.get_widget(labelname)
665                 item_label.set_text(newtext)
666
667         change_menu_label('fileMenuItem', _('File'))
668         change_menu_label('exitMenuItem', _('Exit'))
669         change_menu_label('toolsMenuItem', _('Tools'))
670         change_menu_label('clearSelectionMenuItem', _('Clear selections'))
671         change_menu_label('writeUnitsMenuItem', _('Write Units'))
672         change_menu_label('helpMenuItem', _('Help'))
673         change_menu_label('aboutMenuItem', _('About'))
674
675         change_menu_label('findButton', _('Find'))
676
677         shortlistcheck = widgets.get_widget('shortlistcheck')
678         toggleShortList = widgets.get_widget('toggleShortList')
679
680         categoryView = widgets.get_widget('categoryView')
681
682         unitsView = widgets.get_widget('unitsView')
683         unitsView_selection = unitsView.get_selection()
684
685         unitName = widgets.get_widget('unitName')
686         unitValue = widgets.get_widget('unitValue')
687         previousUnitName = widgets.get_widget('previousUnitName')
688         previousUnitValue = widgets.get_widget('previousUnitValue')
689         about_box = widgets.get_widget('about_box')
690         messagebox = widgets.get_widget('msgbox')
691         messageboxtext = widgets.get_widget('msgboxtext')
692
693         about_image = widgets.get_widget('about_image')
694         about_image.set_from_file(pixmapspath +'gonvert.png')
695         versionlabel = widgets.get_widget('versionlabel')
696         versionlabel.set_text(constants.__version__)
697
698         unitSymbol = widgets.get_widget('unitSymbol')
699         previousUnitSymbol = widgets.get_widget('previousUnitSymbol')
700
701         unitDescription = widgets.get_widget('unitDescription')
702
703         findEntry = widgets.get_widget('findEntry')
704         findLabel = widgets.get_widget('findLabel')
705
706         #insert a categoryColumnumn into the units list even though the heading will not be seen
707         renderer = gtk.CellRendererText()
708         unitNameColumn = gtk.TreeViewColumn(_('Unit Name'), renderer)
709         unitNameColumn.set_property('resizable', 1)
710         unitNameColumn.add_attribute(renderer, 'text', 0)
711         unitNameColumn.set_clickable(True)
712         unitNameColumn.connect("clicked", click_unit_column)
713         unitsView.append_column(unitNameColumn)
714
715         unitValueColumn = gtk.TreeViewColumn(_('Value'), renderer)
716         unitValueColumn.set_property('resizable', 1)
717         unitValueColumn.add_attribute(renderer, 'text', 1)
718         unitValueColumn.set_clickable(True)
719         unitValueColumn.connect("clicked", click_unit_column)
720         unitsView.append_column(unitValueColumn)
721
722         unitSymbolColumn = gtk.TreeViewColumn(_('Units'), renderer)
723         unitSymbolColumn.set_property('resizable', 1)
724         unitSymbolColumn.add_attribute(renderer, 'text', 2)
725         unitSymbolColumn.set_clickable(True)
726         unitSymbolColumn.connect("clicked", click_unit_column)
727         unitsView.append_column(unitSymbolColumn)
728
729         #Insert a column into the category list even though the heading will not be seen
730         renderer = gtk.CellRendererText()
731         categoryColumn = gtk.TreeViewColumn('Title', renderer)
732         categoryColumn.set_property('resizable', 1)
733         categoryColumn.add_attribute(renderer, 'text', 0)
734         categoryView.append_column(categoryColumn)
735
736         categoryModel = gtk.ListStore(gobject.TYPE_STRING)
737         categoryView.set_model(categoryModel)
738         #colourize each row differently for easier reading
739         categoryView.set_property('rules_hint', 1)
740
741         #Populate the catagories list
742         keys = unit_data.list_dic.keys()
743         keys.sort()
744         for key in keys:
745                 iter = categoryModel.append()
746                 categoryModel.set(iter, 0, key)
747
748         ToolTips = gtk.Tooltips()
749         findButton = widgets.get_widget('findButton')
750         ToolTips.set_tip(findButton, _(u'Find unit (F6)'))
751
752         #Restore selections from previously saved settings if it exists and is valid.
753         historical_catergory_found = False
754         selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
755         if os.path.exists(selectionsDatPath):
756                 #Retrieving previous selections from ~/.gonvert/selections.dat
757                 selections = pickle.load(open(selectionsDatPath, 'r'))
758                 #Restoring previous selections.
759                 #
760                 #Make a list of categories to determine which one to select
761                 categories = unit_data.list_dic.keys()
762                 categories.sort()
763                 #
764                 #If the 'selected_unts' has been stored, then extract evil_globals.selected_units from selections.
765                 if 'evil_globals.selected_units' in selections:
766                         evil_globals.selected_units = selections['evil_globals.selected_units']
767                 #Make sure that the 'evil_globals.selected_category' has been stored.
768                 if 'evil_globals.selected_category' in selections:
769                         #Match an available category to the previously selected category.
770                         for counter in range(len(categories)):
771                                 if selections['evil_globals.selected_category'] == categories[counter]:
772                                         # Restore the previously selected category.
773                                         categoryView.set_cursor(counter, categoryColumn, False)
774                                         categoryView.grab_focus()
775                         historical_catergory_found = True
776
777         if not historical_catergory_found:
778                 print "Couldn't find saved category, using default."
779                 #If historical records were not kept then default to
780                 # put the focus on the first category
781                 categoryView.set_cursor(0, categoryColumn, False)
782                 categoryView.grab_focus()
783
784         restore_units()
785
786         gtk.main()
787
788
789 if __name__ == "__main__":
790         main()