From: v13 Date: Fri, 26 Feb 2010 15:04:39 +0000 (+0000) Subject: Added multi-girl support X-Git-Url: http://vcs.maemo.org/git/?p=maegirls;a=commitdiff_plain;h=2e7f895b13a59ea3f0dbae14b4970c2e8abbab78 Added multi-girl support --- diff --git a/trunk/src/config.py b/trunk/src/config.py index 30a3f50..64cb787 100755 --- a/trunk/src/config.py +++ b/trunk/src/config.py @@ -22,33 +22,101 @@ __version__ = "$Id: 0.py 2265 2010-02-21 19:16:26Z v13 $" +import os + import pickle import time import algo -fn="/home/user/.maedays" +try: + home=os.environ['HOME'] +except: + home="/home/user" + +fn="%s/.maegirls" % (home, ) +# Defaults for a girl defaults={ 'cycle': 28, 'day0': algo.today(), } -def store(name, cycle, day0): - # Load old - all=loadAll() - # Override - all[name]={ - 'cycle': cycle, - 'day0': day0, +# Default config +defaultcfg={ + 'ver': 1, # Configuration version + 'girls': { # List of configured girls + 'default': defaults + }, + 'cur': "default", # Current girl + } + +def loadConfig(): + try: + f=file(fn, "r") + st=f.read() + f.close() + ret=pickle.loads(st) + except: + ret={} + +# print "load:", ret + + return(ret) + +def sanitize_before_store(cfg0): + cfg={ + 'ver': cfg0['ver'], + 'cur': str(cfg0['cur']), + 'girls': {} } - st=pickle.dumps(all) + if cfg0.has_key('girls'): + for i in cfg0['girls']: + cfg['girls'][str(i)]=cfg0['girls'][i] + + return(cfg) + +def storeConfig(cfg0): + cfg0['ver']=1 + cfg=sanitize_before_store(cfg0) +# print "store:", cfg + st=pickle.dumps(cfg) f=file(fn, "w") f.write(st) f.close() -def loadOne(name): - all=loadAll() +def storeGirl(name, dt): + # Load old + cfg=loadConfig() + + # Ensure + if not cfg.has_key('girls'): + cfg['girls']={} + + # Override + cfg['girls'][name]={ + 'cycle': dt['cycle'], + 'day0': dt['day0'], + } + + storeConfig(cfg) + +def newGirl(name): + global defaults + + storeGirl(name, defaults) + +def loadGirls(): + cfg=loadConfig() + try: + ret=cfg['girls'] + except: + ret={} + + return(ret) + +def loadGirl(name): + all=loadGirls() if all.has_key(name): ret=all[name] else: @@ -56,16 +124,33 @@ def loadOne(name): return(ret) -def loadAll(): +def girlExists(name): + all=loadGirls() + if all.has_key(name): + ret=True + else: + ret=False + return(ret) + +def setCurrentGirl(name): + cfg=loadConfig() + cfg['cur']=name + storeConfig(cfg) + +def getCurrentGirl(): + cfg=loadConfig() try: - f=file(fn, "r") - st=f.read() - f.close() - ret=pickle.loads(st) + ret=cfg['cur'] except: - ret={} + ret='default' return(ret) +def removeGirl(name): + cfg=loadConfig() + if cfg['girls'].has_key(name): + cfg['girls'].pop(name) + storeConfig(cfg) + # vim: set ts=8 sts=4 sw=4 noet formatoptions=r ai nocindent: diff --git a/trunk/src/main.py b/trunk/src/main.py index 9e0b50f..f4bdcf5 100755 --- a/trunk/src/main.py +++ b/trunk/src/main.py @@ -32,8 +32,11 @@ def init(): al=algo.Algo() win.init(al) - dt=config.loadOne("default") - al.setReference(dt['day0'], dt['cycle']) + girl=config.getCurrentGirl() + win.setGirl(girl) + +# dt=config.loadCurrentGirl() +# al.setReference(dt['day0'], dt['cycle']) init() diff --git a/trunk/src/win.py b/trunk/src/win.py index 17dbca0..0f50111 100755 --- a/trunk/src/win.py +++ b/trunk/src/win.py @@ -39,6 +39,7 @@ class ConfigDialog(QDialog): def __init__(self, *args, **kwargs): QDialog.__init__(self, *args, **kwargs) + self.editName=QLineEdit(self) self.editCycle=QSpinBox(self) self.editCurrent=QSpinBox(self) self.editCycle.setRange(10,50) @@ -51,6 +52,7 @@ class ConfigDialog(QDialog): self.l0=QHBoxLayout(self) l1=QFormLayout() + l1.addRow("Name:", self.editName) l1.addRow("Cycle length:", self.editCycle) l1.addRow("Current day in cycle:", self.editCurrent) @@ -73,6 +75,7 @@ class ConfigDialog(QDialog): self.setWindowTitle("Configuration") def slotButOk(self): + self.name=str(self.editName.text()) self.cycle=self.editCycle.value() self.current=self.editCurrent.value()-1 @@ -82,11 +85,11 @@ class ConfigDialog(QDialog): self.editCurrent.setMaximum(value) # current starts from 0 - def initValues(self, cycle, current): - self.cycle=cycle - self.current=current - self.editCycle.setValue(cycle) - self.editCurrent.setValue(current+1) + def initValues(self, dt): + self.dt=dt + self.editName.setText(dt['name']) + self.editCycle.setValue(dt['cycle']) + self.editCurrent.setValue(dt['day0']+1) class MyMsgDialog(QDialog): """ @@ -127,70 +130,13 @@ class MyMsgDialog(QDialog): self._mm_q.setWidget(self.w) self._mm_l0.addWidget(self._mm_q) -class AboutDialog2(QDialog): - def __init__(self, *args, **kwargs): - QDialog.__init__(self, *args, **kwargs) - - txt=""" -

A program to monitor the women's cycle. Good for planning (or acting ;-). -Inspired by "MyDays" app which is (was?) available for Java ME capable phones. - -

WARNING!!! This is not accurate nor correct! You cannot trust -this program (or any other program) for accurate predictions! -(after all, this is about women... how can one be sure :-). - -

Copyright © 2010, Stefanos Harhalakis <v13@v13.gr> - -

Send comments and bug reports to the above address. - -

This program can be distributed under the terms of the GNU public -license, version 3 or any later. - """ - - self.setWindowTitle("About MaeDays") - - # This freaking thing is hard - # It needs two layouts, one extra widget, the fingerscrollable - # property set to true *and* setWidgetResizable(True) - self.l0=QVBoxLayout(self) - - self.q=QScrollArea(self) - self.q.setWidgetResizable(True) - self.q.setProperty('FingerScrollable', True) - self.w1=QWidget(self.q) - - self.l=QVBoxLayout(self.w1) - - self.ltitle=QLabel("MaeDays", self.w1) - self.ltitle.setObjectName("title") - self.ltitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) - self.ltitle.setAlignment(Qt.AlignCenter) - self.l.addWidget(self.ltitle) - - self.label=QLabel(txt, self.w1) - self.label.setWordWrap(True) - self.label.setTextFormat(Qt.RichText) - self.label.setAlignment(Qt.AlignJustify) - - self.l.addWidget(self.label) - self.q.setWidget(self.w1) - self.l0.addWidget(self.q) - - self.ltitle.setStyleSheet(""" - QLabel { - font-size: 25pt; - color: rgb(192,192,192); - margin-bottom: 0.5ex; - } - """) - class AboutDialog(MyMsgDialog): def __init__(self, *args, **kwargs): MyMsgDialog.__init__(self, *args, **kwargs) txt="""

A program to monitor the women's cycle. Good for planning (or acting ;-). -Inspired by "MyDays" app which is (was?) available for Java ME capable phones. +Inspired by "MyGirls" app which is (was?) available for Java ME capable phones.

WARNING!!! This is not accurate nor correct! You cannot trust @@ -205,9 +151,9 @@ this program (or any other program) for accurate predictions! license, version 3 or any later. """ - self.setWindowTitle("About MaeDays") + self.setWindowTitle("About MaeGirls") - self.ltitle=QLabel("MaeDays", self.w) + self.ltitle=QLabel("MaeGirls", self.w) self.ltitle.setObjectName("title") self.ltitle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.ltitle.setAlignment(Qt.AlignCenter) @@ -232,7 +178,7 @@ class HelpDialog(MyMsgDialog): MyMsgDialog.__init__(self, *args, **kwargs) txt=""" -

MaeDays shows information about women's cycle using some generic +

MaeGirls shows information about women's cycle using some generic guidelines. It assumes that the ovolution happens 14 days before the start of the next period and that the period cycle is constant. Also, it assumes that sperm can live for 4 days, while an egg can live for 2 days. @@ -242,12 +188,12 @@ WARNING!!! This is not always correct. There are FAR TOO MANY exceptions to the above rules!!!

Assuming that you understand the risk of being wrong, you become -entitle to read the graph as follows: +entitled to read the graph as follows:

In red: The days that menstruation happens.

In green: The fertile days.

In blue: The days of PMS -(Premenstrual Syndrome) +(Premenstrual Syndrome).

Navigation is easy: Use left-right finger movement to move the calendar view. Use up-down finger movement to zoom in/out. @@ -261,7 +207,83 @@ view. Use up-down finger movement to zoom in/out. self.label.setAlignment(Qt.AlignJustify) self.l.addWidget(self.label) -class MyDays(QMainWindow): +class GirlsDialog(QDialog): + def __init__(self, *args, **kwargs): + QDialog.__init__(self, *args, **kwargs) + + self.l0=QHBoxLayout(self) + + self.lstm=QStringListModel() + self.lst=QListView(self) + self.lst.setModel(self.lstm) + + self.l0.addWidget(self.lst) + + self.buttonNew=QPushButton(self) + self.buttonNew.setText("New") + + self.buttonSelect=QPushButton(self) + self.buttonSelect.setText("Select") + + self.buttonDelete=QPushButton(self) + self.buttonDelete.setText("Delete") + + spacer=QSpacerItem(20, 20, QSizePolicy.Minimum,QSizePolicy.Expanding) + + self.l1=QVBoxLayout() + self.l0.addLayout(self.l1) + self.l1.addWidget(self.buttonNew) + self.l1.addWidget(self.buttonSelect) + self.l1.addWidget(self.buttonDelete) + self.l1.addItem(spacer) + + self.buttonNew.clicked.connect(self.slotNew) + self.buttonDelete.clicked.connect(self.slotDelete) + self.buttonSelect.clicked.connect(self.slotSelect) + + self.what="" + self.which=None + + def _get_selection(self): + sel=self.lst.selectedIndexes() + if len(sel)==1: + d=sel[0] + ret=str(d.data().toString()) + else: + ret=None + + return(ret) + + def exec_(self, current): + # Set data + girls=config.loadGirls() + dt=girls.keys() + dt.sort() + self.lstm.setStringList(dt) + + # Set current selection + idx=dt.index(current) + self.lst.setCurrentIndex(self.lstm.index(idx)) + + # Run + QDialog.exec_(self) + + def slotNew(self): + self.what="new" + self.which=None + self.accept() + + def slotDelete(self): + self.what="delete" + self.which=self._get_selection() + self.accept() + + def slotSelect(self): + self.what="select" + self.which=self._get_selection() + self.accept() + +class MaeGirls(QMainWindow): def __init__(self, algo): QMainWindow.__init__(self) @@ -270,6 +292,7 @@ class MyDays(QMainWindow): self.dlgConfig=ConfigDialog(self) self.dlgAbout=AboutDialog(self) self.dlgHelp=HelpDialog(self) + self.dlgGirls=None self.algo=algo @@ -289,6 +312,9 @@ class MyDays(QMainWindow): self.menureset=QAction('Go to today', self) self.menureset.triggered.connect(self.menuReset) + self.menugirls=QAction('Girls', self) + self.menugirls.triggered.connect(self.menuGirls) + self.menuabout=QAction('About', self) self.menuabout.triggered.connect(self.menuAbout) @@ -298,30 +324,91 @@ class MyDays(QMainWindow): m=self.menuBar() m.addAction(self.menuconfig) m.addAction(self.menureset) - m.addAction(self.menuabout) + m.addAction(self.menugirls) m.addAction(self.menuhelp) + m.addAction(self.menuabout) - self.setWindowTitle("MaeDays") + self.setWindowTitle("MaeGirls") def setAlgo(self, algo): self.dg.setAlgo(algo) + def setGirl(self, name): + cfg=config.loadGirl(name) + self.girl=name + self.algo.setReference(cfg['day0'], cfg['cycle']) + self.repaint() + def menuConfig(self): if self.dlgConfig==None: self.dlgConfig=ConfigDialog(self) - self.dlgConfig.initValues(self.algo.cycleLength(), - self.algo.currentDayInCycle()) + dt={ + 'name': self.girl, + 'cycle': self.algo.cycleLength(), + 'day0': self.algo.currentDayInCycle() + } + + self.dlgConfig.initValues(dt) ret=self.dlgConfig.exec_() if ret==self.dlgConfig.Accepted: today=algo.today() + + name=self.dlgConfig.name day0=today-self.dlgConfig.current - self.algo.setReference(day0, self.dlgConfig.cycle) - config.store("default", self.dlgConfig.cycle, day0) + + dt={ + 'cycle': self.dlgConfig.cycle, + 'day0': day0, + } + + config.storeGirl(name, dt) + config.setCurrentGirl(name) + + # If this is a rename, remove the old one + if self.girl!=name: + config.removeGirl(self.girl) + + self.setGirl(name) + self.repaint() + def menuGirls(self): + if self.dlgGirls==None: + self.dlgGirls=GirlsDialog(self) + + ret=self.dlgGirls.exec_(self.girl) + + what=self.dlgGirls.what + which=self.dlgGirls.which + if what=='new': + # Determine a unique name + base="newgirl" + idx=0 + name=base + while config.girlExists(name): + idx+=1 + name="%s%d" % (base, idx) + # Store this + config.newGirl(name) + # Set it as current + config.setCurrentGirl(name) + self.setGirl(name) + # Edit it + self.menuConfig() + elif what=='delete' and which!=None: + if self.girl==which: + msg=QMessageBox(self) + msg.setText("You cannot delete the current girl") + msg.exec_() + else: + config.removeGirl(which) + elif what=='select' and which!=None: + config.setCurrentGirl(which) + self.setGirl(which) + def menuAbout(self): if self.dlgAbout==None: self.dlgAbout=AboutDialog(self) @@ -343,13 +430,17 @@ def init(algo): app=QApplication(sys.argv) #app.setAttribute(Qt.WA_Maemo5PortraitOrientation, True); - win=MyDays(algo) + win=MaeGirls(algo) win.show() def setAlgo(algo): global win win.setAlgo(algo) +def setGirl(name): + global win + win.setGirl(name) + def doit(): global app app.exec_()