813e8216c32d1536f2ea0139eac3809d21327f1b
[ejpi] / src / ejpi_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 simplejson
9 import logging
10
11 from PyQt4 import QtGui
12 from PyQt4 import QtCore
13
14 import constants
15 import maeqt
16 from util import misc as misc_utils
17
18 import qhistory
19
20
21 _moduleLogger = logging.getLogger(__name__)
22
23
24 IS_MAEMO = True
25
26
27 class Calculator(object):
28
29         def __init__(self, app):
30                 self._app = app
31                 self._recent = []
32                 self._hiddenCategories = set()
33                 self._hiddenUnits = {}
34                 self._clipboard = QtGui.QApplication.clipboard()
35
36                 self._mainWindow = None
37
38                 self._fullscreenAction = QtGui.QAction(None)
39                 self._fullscreenAction.setText("Fullscreen")
40                 self._fullscreenAction.setCheckable(True)
41                 self._fullscreenAction.setShortcut(QtGui.QKeySequence("CTRL+Enter"))
42                 self._fullscreenAction.toggled.connect(self._on_toggle_fullscreen)
43
44                 self._logAction = QtGui.QAction(None)
45                 self._logAction.setText("Log")
46                 self._logAction.setShortcut(QtGui.QKeySequence("CTRL+l"))
47                 self._logAction.triggered.connect(self._on_log)
48
49                 self._quitAction = QtGui.QAction(None)
50                 self._quitAction.setText("Quit")
51                 self._quitAction.setShortcut(QtGui.QKeySequence("CTRL+q"))
52                 self._quitAction.triggered.connect(self._on_quit)
53
54                 self._app.lastWindowClosed.connect(self._on_app_quit)
55                 self.load_settings()
56
57                 self._mainWindow = MainWindow(None, self)
58                 self._mainWindow.window.destroyed.connect(self._on_child_close)
59
60         def load_settings(self):
61                 try:
62                         with open(constants._user_settings_, "r") as settingsFile:
63                                 settings = simplejson.load(settingsFile)
64                 except IOError, e:
65                         _moduleLogger.info("No settings")
66                         settings = {}
67                 except ValueError:
68                         _moduleLogger.info("Settings were corrupt")
69                         settings = {}
70
71                 self._fullscreenAction.setChecked(settings.get("isFullScreen", False))
72
73         def save_settings(self):
74                 settings = {
75                         "isFullScreen": self._fullscreenAction.isChecked(),
76                 }
77                 with open(constants._user_settings_, "w") as settingsFile:
78                         simplejson.dump(settings, settingsFile)
79
80         @property
81         def fullscreenAction(self):
82                 return self._fullscreenAction
83
84         @property
85         def logAction(self):
86                 return self._logAction
87
88         @property
89         def quitAction(self):
90                 return self._quitAction
91
92         def _close_windows(self):
93                 if self._mainWindow is not None:
94                         self._mainWindow.window.destroyed.disconnect(self._on_child_close)
95                         self._mainWindow.close()
96                         self._mainWindow = None
97
98         @misc_utils.log_exception(_moduleLogger)
99         def _on_app_quit(self, checked = False):
100                 self.save_settings()
101
102         @misc_utils.log_exception(_moduleLogger)
103         def _on_child_close(self, obj = None):
104                 self._mainWindow = None
105
106         @misc_utils.log_exception(_moduleLogger)
107         def _on_toggle_fullscreen(self, checked = False):
108                 for window in self._walk_children():
109                         window.set_fullscreen(checked)
110
111         @misc_utils.log_exception(_moduleLogger)
112         def _on_log(self, checked = False):
113                 with open(constants._user_logpath_, "r") as f:
114                         logLines = f.xreadlines()
115                         log = "".join(logLines)
116                         self._clipboard.setText(log)
117
118         @misc_utils.log_exception(_moduleLogger)
119         def _on_quit(self, checked = False):
120                 self._close_windows()
121
122
123 class MainWindow(object):
124
125         def __init__(self, parent, app):
126                 self._app = app
127
128                 self._historyView = qhistory.QCalcHistory()
129
130                 self._layout = QtGui.QVBoxLayout()
131                 self._layout.addWidget(self._historyView.toplevel)
132
133                 centralWidget = QtGui.QWidget()
134                 centralWidget.setLayout(self._layout)
135
136                 self._window = QtGui.QMainWindow(parent)
137                 self._window.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
138                 maeqt.set_autorient(self._window, True)
139                 maeqt.set_stackable(self._window, True)
140                 self._window.setWindowTitle("%s" % constants.__pretty_app_name__)
141                 self._window.setCentralWidget(centralWidget)
142
143                 self._closeWindowAction = QtGui.QAction(None)
144                 self._closeWindowAction.setText("Close")
145                 self._closeWindowAction.setShortcut(QtGui.QKeySequence("CTRL+w"))
146                 self._closeWindowAction.triggered.connect(self._on_close_window)
147
148                 if IS_MAEMO:
149                         #fileMenu = self._window.menuBar().addMenu("&File")
150
151                         #viewMenu = self._window.menuBar().addMenu("&View")
152
153                         self._window.addAction(self._closeWindowAction)
154                         self._window.addAction(self._app.quitAction)
155                         self._window.addAction(self._app.fullscreenAction)
156                 else:
157                         fileMenu = self._window.menuBar().addMenu("&Units")
158                         fileMenu.addAction(self._closeWindowAction)
159                         fileMenu.addAction(self._app.quitAction)
160
161                         viewMenu = self._window.menuBar().addMenu("&View")
162                         viewMenu.addAction(self._app.fullscreenAction)
163
164                 self._window.addAction(self._app.logAction)
165
166                 self.set_fullscreen(self._app.fullscreenAction.isChecked())
167                 self._window.show()
168
169         @property
170         def window(self):
171                 return self._window
172
173         def walk_children(self):
174                 return ()
175
176         def show(self):
177                 self._window.show()
178                 for child in self.walk_children():
179                         child.show()
180
181         def hide(self):
182                 for child in self.walk_children():
183                         child.hide()
184                 self._window.hide()
185
186         def close(self):
187                 for child in self.walk_children():
188                         child.window.destroyed.disconnect(self._on_child_close)
189                         child.close()
190                 self._window.close()
191
192         def set_fullscreen(self, isFullscreen):
193                 if isFullscreen:
194                         self._window.showFullScreen()
195                 else:
196                         self._window.showNormal()
197                 for child in self.walk_children():
198                         child.set_fullscreen(isFullscreen)
199
200         @misc_utils.log_exception(_moduleLogger)
201         def _on_close_window(self, checked = True):
202                 self.close()
203
204
205 def run():
206         app = QtGui.QApplication([])
207         handle = Calculator(app)
208         return app.exec_()
209
210
211 if __name__ == "__main__":
212         logging.basicConfig(level = logging.DEBUG)
213         try:
214                 os.makedirs(constants._data_path_)
215         except OSError, e:
216                 if e.errno != 17:
217                         raise
218
219         val = run()
220         sys.exit(val)