Rename
[maegirls] / trunk / src / win.py
1 #!/usr/bin/env python
2 # coding=UTF-8
3
4 # Copyright (C) 2010 Stefanos Harhalakis
5 #
6 # This file is part of mydays.
7 #
8 # mydays is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # mydays is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with mydays.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 # $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
22
23 __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $"
24
25 from PyQt4.QtGui import *
26 from PyQt4.QtCore import *
27
28 import sys
29 import time
30
31 from graph import DaysGraph
32 import config
33 import algo
34
35 app=None
36 win=None
37
38 class ConfigDialog(QDialog):
39     def __init__(self, *args, **kwargs):
40         QDialog.__init__(self, *args, **kwargs)
41
42         self.editCycle=QSpinBox(self)
43         self.editCurrent=QSpinBox(self)
44         self.editCycle.setRange(10,50)
45         self.editCurrent.setRange(1,50)
46         self.editCurrent.setWrapping(True)
47         self.editCycle.setSuffix(" days")
48
49         self.editCycle.valueChanged.connect(self.slotEditCycleChanged)
50
51         self.l0=QHBoxLayout(self)
52
53         l1=QFormLayout()
54         l1.addRow("Cycle length:", self.editCycle)
55         l1.addRow("Current day in cycle:", self.editCurrent)
56
57         self.l0.addLayout(l1)
58
59         spacer=QSpacerItem(20, 20, QSizePolicy.Expanding)
60         self.l0.addItem(spacer)
61
62         l2=QVBoxLayout()
63         self.l0.addLayout(l2)
64
65         self.buttonOk=QPushButton(self)
66         self.buttonOk.setText("OK")
67         self.buttonOk.clicked.connect(self.slotButOk)
68         l2.addWidget(self.buttonOk)
69
70         spacer=QSpacerItem(20, 20, QSizePolicy.Minimum,QSizePolicy.Expanding)
71         l2.addItem(spacer)
72
73         self.setWindowTitle("Configuration")
74
75     def slotButOk(self):
76         self.cycle=self.editCycle.value()
77         self.current=self.editCurrent.value()-1
78
79         self.accept()
80
81     def slotEditCycleChanged(self, value):
82         self.editCurrent.setMaximum(value)
83
84     # current starts from 0
85     def initValues(self, cycle, current):
86         self.cycle=cycle
87         self.current=current
88         self.editCycle.setValue(cycle)
89         self.editCurrent.setValue(current+1)
90
91 class MyMsgDialog(QDialog):
92     """
93     A Dialog to show a finger-scrollable message
94
95     Typical usage:
96
97     class Koko(MyMsgDialog):
98         def __init__(....)
99             MyMsgDialog.__init__(....)
100
101
102             self.setWindowTitle("My title")
103     
104             l1=QLabel("koko", self.w)
105             self.l.addWidget(l1)
106             ...
107
108             self.l is a QVBoxLayout. Add everything there.
109             self.w is a QWidget. Use it as parent.
110
111     """
112     def __init__(self, *args, **kwargs):
113         QDialog.__init__(self, *args, **kwargs)
114
115         # This freaking thing is hard
116         # It needs two layouts, one extra widget, the fingerscrollable
117         # property set to true *and* setWidgetResizable(True)
118         self._mm_l0=QVBoxLayout(self)
119
120         self._mm_q=QScrollArea(self)
121         self._mm_q.setWidgetResizable(True)
122         self._mm_q.setProperty('FingerScrollable', True)
123
124         self.w=QWidget(self._mm_q)
125
126         self.l=QVBoxLayout(self.w)
127         self._mm_q.setWidget(self.w)
128         self._mm_l0.addWidget(self._mm_q)
129
130 class AboutDialog2(QDialog):
131     def __init__(self, *args, **kwargs):
132         QDialog.__init__(self, *args, **kwargs)
133
134         txt="""
135 <p> A program to monitor the women's cycle.  Good for planning (or acting ;-).
136 Inspired by "MyDays" app which is (was?) available for Java ME capable phones.
137
138 <p> WARNING!!! This is not accurate nor correct! You cannot trust
139 this program (or any other program) for accurate predictions!
140 (after all, this is about women... how can one be sure :-).
141
142 <p> Copyright &copy; 2010, Stefanos Harhalakis &lt;v13@v13.gr&gt;
143
144 <p> Send comments and bug reports to the above address.
145
146 <p> This program can be distributed under the terms of the GNU public
147 license, version 3 or any later.
148         """
149
150         self.setWindowTitle("About MaeDays")
151
152         # This freaking thing is hard
153         # It needs two layouts, one extra widget, the fingerscrollable
154         # property set to true *and* setWidgetResizable(True)
155         self.l0=QVBoxLayout(self)
156
157         self.q=QScrollArea(self)
158         self.q.setWidgetResizable(True)
159         self.q.setProperty('FingerScrollable', True)
160         self.w1=QWidget(self.q)
161
162         self.l=QVBoxLayout(self.w1)
163
164         self.ltitle=QLabel("MaeDays", self.w1)
165         self.ltitle.setObjectName("title")
166         self.ltitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
167         self.ltitle.setAlignment(Qt.AlignCenter)
168         self.l.addWidget(self.ltitle)
169
170         self.label=QLabel(txt, self.w1)
171         self.label.setWordWrap(True)
172         self.label.setTextFormat(Qt.RichText)
173         self.label.setAlignment(Qt.AlignJustify)
174
175         self.l.addWidget(self.label)
176         self.q.setWidget(self.w1)
177         self.l0.addWidget(self.q)
178
179         self.ltitle.setStyleSheet("""
180         QLabel {
181             font-size:      25pt;
182             color:          rgb(192,192,192);
183             margin-bottom:  0.5ex;
184             }
185         """)
186
187 class AboutDialog(MyMsgDialog):
188     def __init__(self, *args, **kwargs):
189         MyMsgDialog.__init__(self, *args, **kwargs)
190
191         txt="""
192 <p> A program to monitor the women's cycle.  Good for planning (or acting ;-).
193 Inspired by "MyDays" app which is (was?) available for Java ME capable phones.
194
195 <p style="color: orange;">
196 WARNING!!! This is not accurate nor correct! You cannot trust
197 this program (or any other program) for accurate predictions!
198 (after all, this is about women... how can one be sure :-).
199
200 <p> Copyright &copy; 2010, Stefanos Harhalakis &lt;v13@v13.gr&gt;
201
202 <p> Send comments and bug reports to the above address.
203
204 <p> This program can be distributed under the terms of the GNU public
205 license, version 3 or any later.
206         """
207
208         self.setWindowTitle("About MaeDays")
209
210         self.ltitle=QLabel("MaeDays", self.w)
211         self.ltitle.setObjectName("title")
212         self.ltitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
213         self.ltitle.setAlignment(Qt.AlignCenter)
214         self.l.addWidget(self.ltitle)
215
216         self.label=QLabel(txt, self.w)
217         self.label.setWordWrap(True)
218         self.label.setTextFormat(Qt.RichText)
219         self.label.setAlignment(Qt.AlignJustify)
220         self.l.addWidget(self.label)
221
222         self.ltitle.setStyleSheet("""
223         QLabel {
224             font-size:      25pt;
225             color:          rgb(192,192,192);
226             margin-bottom:  0.5ex;
227             }
228         """)
229
230 class HelpDialog(MyMsgDialog):
231     def __init__(self, *args, **kwargs):
232         MyMsgDialog.__init__(self, *args, **kwargs)
233
234         txt="""
235 <p> MaeDays shows information about women's cycle using some generic
236 guidelines.  It assumes that the ovolution happens 14 days before the start
237 of the next period and that the period cycle is constant. Also, it assumes
238 that sperm can live for 4 days, while an egg can live for 2 days.
239
240 <p style="color: orange;">
241 WARNING!!! This is not always correct. There are FAR TOO MANY exceptions
242 to the above rules!!!
243
244 <p> Assuming that you understand the risk of being wrong, you become
245 entitle to read the graph as follows:
246 <p> <span style="color: red">In red:</span> The days that menstruation
247 happens.
248 <p> <span style="color: green">In green:</span> The fertile days.
249 <p> <span style="color: blue">In blue:</span> The days of PMS
250 (Premenstrual Syndrome)
251
252 <p> Navigation is easy: Use left-right finger movement to move the calendar
253 view. Use up-down finger movement to zoom in/out.
254         """
255
256         self.setWindowTitle("Help")
257
258         self.label=QLabel(txt, self.w)
259         self.label.setWordWrap(True)
260         self.label.setTextFormat(Qt.RichText)
261         self.label.setAlignment(Qt.AlignJustify)
262         self.l.addWidget(self.label)
263
264 class MyDays(QMainWindow):
265     def __init__(self, algo):
266         QMainWindow.__init__(self)
267
268         self.setupUi(algo)
269
270         self.dlgConfig=ConfigDialog(self)
271         self.dlgAbout=AboutDialog(self)
272         self.dlgHelp=HelpDialog(self)
273
274         self.algo=algo
275
276     def setupUi(self, algo):
277         self.centralwidget=QWidget(self)
278         self.setCentralWidget(self.centralwidget)
279
280         self.l0=QVBoxLayout(self.centralwidget)
281
282         self.dg=DaysGraph(algo, self.centralwidget)
283         self.l0.addWidget(self.dg)
284
285         # Menu
286         self.menuconfig=QAction('Configure', self)
287         self.menuconfig.triggered.connect(self.menuConfig)
288
289         self.menureset=QAction('Go to today', self)
290         self.menureset.triggered.connect(self.menuReset)
291
292         self.menuabout=QAction('About', self)
293         self.menuabout.triggered.connect(self.menuAbout)
294
295         self.menuhelp=QAction('Help', self)
296         self.menuhelp.triggered.connect(self.menuHelp)
297
298         m=self.menuBar()
299         m.addAction(self.menuconfig)
300         m.addAction(self.menureset)
301         m.addAction(self.menuabout)
302         m.addAction(self.menuhelp)
303
304         self.setWindowTitle("MaeDays")
305
306     def setAlgo(self, algo):
307         self.dg.setAlgo(algo)
308
309     def menuConfig(self):
310         if self.dlgConfig==None:
311             self.dlgConfig=ConfigDialog(self)
312
313         self.dlgConfig.initValues(self.algo.cycleLength(),
314             self.algo.currentDayInCycle())
315
316         ret=self.dlgConfig.exec_()
317
318         if ret==self.dlgConfig.Accepted:
319             today=algo.today()
320             day0=today-self.dlgConfig.current
321             self.algo.setReference(day0, self.dlgConfig.cycle)
322             config.store("default", self.dlgConfig.cycle, day0)
323             self.repaint()
324
325     def menuAbout(self):
326         if self.dlgAbout==None:
327             self.dlgAbout=AboutDialog(self)
328
329         ret=self.dlgAbout.exec_()
330
331     def menuHelp(self):
332         if self.dlgHelp==None:
333             self.dlgHelp=HelpDialog(self)
334
335         ret=self.dlgHelp.exec_()
336
337     def menuReset(self):
338         self.dg.reset()
339
340 def init(algo):
341     global app
342     global win
343
344     app=QApplication(sys.argv)
345     #app.setAttribute(Qt.WA_Maemo5PortraitOrientation, True);
346     win=MyDays(algo)
347     win.show()
348
349 def setAlgo(algo):
350     global win
351     win.setAlgo(algo)
352
353 def doit():
354     global app
355     app.exec_()
356
357 # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent:
358