11ffc453a51aef40c2342efe45c043de3411074a
[gonvert] / src / gonvert_qt.py
1 #!/usr/bin/env python
2 # -*- coding: UTF8 -*-
3
4 from __future__ import with_statement
5
6 import sys
7 import os
8 import math
9 import pickle
10 import logging
11
12 from PyQt4 import QtGui
13 from PyQt4 import QtCore
14
15 import constants
16 import unit_data
17
18 try:
19         import gettext
20 except ImportError:
21         _ = lambda x: x
22         gettext = None
23 else:
24         _ = gettext.gettext
25
26
27 _moduleLogger = logging.getLogger("gonvert_glade")
28
29 if gettext is not None:
30         gettext.bindtextdomain('gonvert', '/usr/share/locale')
31         gettext.textdomain('gonvert')
32
33
34 def change_menu_label(widgets, labelname, newtext):
35         item_label = widgets.get_widget(labelname).get_children()[0]
36         item_label.set_text(newtext)
37
38
39 def split_number(number):
40         try:
41                 fractional, integer = math.modf(number)
42         except TypeError:
43                 integerDisplay = number
44                 fractionalDisplay = ""
45         else:
46                 integerDisplay = str(integer)
47                 fractionalDisplay = str(fractional)
48                 if "e+" in integerDisplay:
49                         integerDisplay = number
50                         fractionalDisplay = ""
51                 elif "e-" in fractionalDisplay and 0.0 < integer:
52                         integerDisplay = number
53                         fractionalDisplay = ""
54                 elif "e-" in fractionalDisplay:
55                         integerDisplay = ""
56                         fractionalDisplay = number
57                 else:
58                         integerDisplay = integerDisplay.split(".", 1)[0] + "."
59                         fractionalDisplay = fractionalDisplay.rsplit(".", 1)[-1]
60
61         return integerDisplay, fractionalDisplay
62
63
64 class Gonvert(object):
65
66         ORIENTATION_HORIZONTAL = "ORIENTATION_HORIZONTAL"
67         ORIENTATION_VERTICAL = "ORIENTATION_VERTICAL"
68
69         _DATA_PATHS = [
70                 os.path.dirname(__file__),
71                 os.path.join(os.path.dirname(__file__), "../data"),
72                 os.path.join(os.path.dirname(__file__), "../lib"),
73                 '/usr/share/gonvert',
74                 '/usr/lib/gonvert',
75         ]
76
77         def __init__(self):
78                 self.__isPortrait = False
79                 self._dataPath = ""
80                 for dataPath in self._DATA_PATHS:
81                         appIconPath = os.path.join(dataPath, "pixmaps", "gonvert.png")
82                         if os.path.isfile(appIconPath):
83                                 self._dataPath = dataPath
84                                 break
85                 else:
86                         raise RuntimeError("UI Descriptor not found!")
87
88                 self._unitCategory = QtGui.QPushButton()
89
90                 self._selectedUnitName = QtGui.QLabel()
91                 self._selectedUnitValue = QtGui.QLineEdit()
92                 self._selectedUnitSymbol = QtGui.QLabel()
93
94                 self._selectedUnitLayout = QtGui.QHBoxLayout()
95                 self._selectedUnitLayout.addWidget(self._selectedUnitName)
96                 self._selectedUnitLayout.addWidget(self._selectedUnitValue)
97                 self._selectedUnitLayout.addWidget(self._selectedUnitSymbol)
98
99                 self._units = QtGui.QTreeWidget()
100
101                 self._searchButton = QtGui.QPushButton()
102                 self._searchEntry = QtGui.QLineEdit()
103                 self._searchCloseButton = QtGui.QPushButton()
104
105                 self._searchLayout = QtGui.QHBoxLayout()
106                 self._searchLayout.addWidget(self._searchButton)
107                 self._searchLayout.addWidget(self._searchEntry)
108                 self._searchLayout.addWidget(self._searchCloseButton)
109
110                 self._layout = QtGui.QVBoxLayout()
111                 self._layout.addWidget(self._unitCategory)
112                 self._layout.addLayout(self._selectedUnitLayout)
113                 self._layout.addWidget(self._units)
114                 self._layout.addLayout(self._searchLayout)
115
116                 centralWidget = QtGui.QWidget()
117                 centralWidget.setLayout(self._layout)
118
119                 self._window = QtGui.QMainWindow()
120                 self._window.setWindowTitle("%s - Unit Conversion Utility" % constants.__pretty_app_name__)
121                 self._window.setWindowIcon(QtGui.QIcon(appIconPath))
122                 self._window.setCentralWidget(centralWidget)
123                 self._load_settings()
124
125                 self._window.show()
126                 self._hide_search()
127
128         def _load_settings(self):
129                 #Restore window size from previously saved settings if it exists and is valid.
130                 windowDatPath = "/".join((constants._data_path_, "window.dat"))
131                 if os.path.exists(windowDatPath):
132                         saved_window = pickle.load(open(windowDatPath, "r"))
133                         try:
134                                 a, b = saved_window['size']
135                         except KeyError:
136                                 pass
137                         else:
138                                 self._window.resize(a, b)
139                         try:
140                                 isFullscreen = saved_window["isFullscreen"]
141                         except KeyError:
142                                 pass
143                         else:
144                                 if isFullscreen:
145                                         self._window.fullscreen()
146                         try:
147                                 isPortrait = saved_window["isPortrait"]
148                         except KeyError:
149                                 pass
150                         else:
151                                 if isPortrait ^ self.__isPortrait:
152                                         if isPortrait:
153                                                 orientation = self.ORIENTATION_VERTICAL
154                                         else:
155                                                 orientation = self.ORIENTATION_HORIZONTAL
156                                         self.set_orientation(orientation)
157
158                 #Restore selections from previously saved settings if it exists and is valid.
159                 categoryIndex = 0
160                 selectedCategoryName = unit_data.UNIT_CATEGORIES[0]
161                 selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
162                 if os.path.exists(selectionsDatPath):
163                         selections = pickle.load(open(selectionsDatPath, 'r'))
164                         try:
165                                 self._defaultUnitForCategory = selections['selected_units']
166                         except KeyError:
167                                 pass
168
169                         try:
170                                 selectedCategoryName = selections['selected_category']
171                         except KeyError:
172                                 pass
173                         else:
174                                 try:
175                                         categoryIndex = unit_data.UNIT_CATEGORIES.index(selectedCategoryName)
176                                 except ValueError:
177                                         _moduleLogger.warn("Unknown category: %s" % selectedCategoryName)
178
179                 if False:
180                         self._categorySelectionButton.get_child().set_markup("<big>%s</big>" % selectedCategoryName)
181                         self._categoryView.set_cursor(categoryIndex, self._categoryColumn, False)
182                         self._categoryView.grab_focus()
183
184                         self._select_default_unit()
185
186         def _save_settings(self):
187                 """
188                 This routine saves the selections to a file, and
189                 should therefore only be called when exiting the program.
190
191                 Update selections dictionary which consists of the following keys:
192                 'self._selectedCategoryName': full name of selected category
193                 'self._defaultUnitForCategory': self._defaultUnitForCategory dictionary which contains:
194                 [categoryname: #1 displayed unit, #2 displayed unit]
195                 """
196                 if False:
197                         #Determine the contents of the selected category row
198                         selected, iter = self._categoryView.get_selection().get_selected()
199                         self._selectedCategoryName = self._categoryModel.get_value(iter, 0)
200
201                         selections = {
202                                 'selected_category': self._selectedCategoryName,
203                                 'selected_units': self._defaultUnitForCategory
204                         }
205                         selectionsDatPath = "/".join((constants._data_path_, "selections.dat"))
206                         pickle.dump(selections, open(selectionsDatPath, 'w'))
207
208                 #Get last size of app and save it
209                 window_settings = {
210                         'size': self._window.get_size(),
211                         "isFullscreen": self._isFullScreen,
212                         "isPortrait": self.__isPortrait,
213                 }
214                 windowDatPath = "/".join((constants._data_path_, "window.dat"))
215                 pickle.dump(window_settings, open(windowDatPath, 'w'))
216
217         def set_orientation(self, orientation):
218                 pass
219
220         def _hide_search(self):
221                 self._searchButton.hide()
222                 self._searchEntry.hide()
223                 self._searchCloseButton.hide()
224
225
226 def run_gonvert():
227         app = QtGui.QApplication([])
228         handle = Gonvert()
229         return app.exec_()
230
231
232 if __name__ == "__main__":
233         logging.basicConfig(level = logging.DEBUG)
234         try:
235                 os.makedirs(constants._data_path_)
236         except OSError, e:
237                 if e.errno != 17:
238                         raise
239
240         val = run_gonvert()
241         sys.exit(val)