Fixed icons.
[maegirls] / trunk / src / win.py
index 17dbca0..27a6fae 100755 (executable)
@@ -3,20 +3,20 @@
 # 
 # Copyright (C) 2010 Stefanos Harhalakis
 #
-# This file is part of mydays.
+# This file is part of maegirls.
 #
-# mydays is free software: you can redistribute it and/or modify
+# maegirls is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# mydays is distributed in the hope that it will be useful,
+# maegirls is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with mydays.  If not, see <http://www.gnu.org/licenses/>.
+# along with maegirls.  If not, see <http://www.gnu.org/licenses/>.
 #
 # $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $
 
@@ -39,20 +39,22 @@ 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)
        self.editCurrent.setRange(1,50)
        self.editCurrent.setWrapping(True)
-       self.editCycle.setSuffix(" days")
+       self.editCycle.setSuffix(self.tr(" days"))
 
        self.editCycle.valueChanged.connect(self.slotEditCycleChanged)
 
        self.l0=QHBoxLayout(self)
 
        l1=QFormLayout()
-       l1.addRow("Cycle length:", self.editCycle)
-       l1.addRow("Current day in cycle:", self.editCurrent)
+       l1.addRow(self.tr("Name:"), self.editName)
+       l1.addRow(self.tr("Cycle length:"), self.editCycle)
+       l1.addRow(self.tr("Current day in cycle:"), self.editCurrent)
 
        self.l0.addLayout(l1)
 
@@ -63,16 +65,17 @@ class ConfigDialog(QDialog):
        self.l0.addLayout(l2)
 
        self.buttonOk=QPushButton(self)
-       self.buttonOk.setText("OK")
+       self.buttonOk.setText(self.tr("OK"))
        self.buttonOk.clicked.connect(self.slotButOk)
        l2.addWidget(self.buttonOk)
 
        spacer=QSpacerItem(20, 20, QSizePolicy.Minimum,QSizePolicy.Expanding)
        l2.addItem(spacer)
 
-       self.setWindowTitle("Configuration")
+       self.setWindowTitle(self.tr("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="""
-<p> 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.
-
-<p> 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 :-).
-
-<p> Copyright &copy; 2010, Stefanos Harhalakis &lt;v13@v13.gr&gt;
-
-<p> Send comments and bug reports to the above address.
-
-<p> 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="""
+       txt=self.tr("""
 <p> 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.
 
 <p style="color: orange;">
 WARNING!!! This is not accurate nor correct! You cannot trust
@@ -203,11 +149,11 @@ this program (or any other program) for accurate predictions!
 
 <p> This program can be distributed under the terms of the GNU public
 license, version 3 or any later.
-       """
+       """)
 
-       self.setWindowTitle("About MaeDays")
+       self.setWindowTitle(self.tr("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)
@@ -231,9 +177,9 @@ class HelpDialog(MyMsgDialog):
     def __init__(self, *args, **kwargs):
        MyMsgDialog.__init__(self, *args, **kwargs)
 
-       txt="""
-<p> MaeDays shows information about women's cycle using some generic
-guidelines.  It assumes that the ovolution happens 14 days before the start
+       txt=self.tr("""
+<p> MaeGirls shows information about women's cycle using some generic
+guidelines.  It assumes that the ovulation 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,18 +188,18 @@ WARNING!!! This is not always correct. There are FAR TOO MANY exceptions
 to the above rules!!!
 
 <p> 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:
 <p> <span style="color: red">In red:</span> The days that menstruation
 happens.
 <p> <span style="color: green">In green:</span> The fertile days.
 <p> <span style="color: blue">In blue:</span> The days of PMS
-(Premenstrual Syndrome)
+(Premenstrual Syndrome).
 
 <p> Navigation is easy: Use left-right finger movement to move the calendar
 view. Use up-down finger movement to zoom in/out.
-       """
+       """)
 
-       self.setWindowTitle("Help")
+       self.setWindowTitle(self.tr("Help"))
 
        self.label=QLabel(txt, self.w)
        self.label.setWordWrap(True)
@@ -261,15 +207,103 @@ 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.lst.setProperty("FingerScrollable", True)
+
+       self.l0.addWidget(self.lst)
+
+       self.buttonNew=QPushButton(self)
+       self.buttonNew.setText(self.tr("New"))
+
+       self.buttonSelect=QPushButton(self)
+       self.buttonSelect.setText(self.tr("Select"))
+
+       self.buttonDelete=QPushButton(self)
+       self.buttonDelete.setText(self.tr("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)
+
+    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)
+
+       self.what=""
+       self.which=None
+
+       # Set current selection
+       idx=dt.index(current)
+
+       # Either I'm doing something stupid, or this is a QT bug
+       # The selection works but isn't shown
+       idx2=self.lstm.index(idx, 0)
+       self.lst.setCurrentIndex(idx2)
+       # Give if focus to show the current selection - is this normal?
+       self.lst.setFocus(Qt.OtherFocusReason)
+
+       # 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)
 
        self.setupUi(algo)
 
-       self.dlgConfig=ConfigDialog(self)
-       self.dlgAbout=AboutDialog(self)
-       self.dlgHelp=HelpDialog(self)
+#      self.dlgConfig=ConfigDialog(self)
+#      self.dlgAbout=AboutDialog(self)
+#      self.dlgHelp=HelpDialog(self)
+       self.dlgConfig=None
+       self.dlgAbout=None
+       self.dlgHelp=None
+       self.dlgGirls=None
 
        self.algo=algo
 
@@ -283,45 +317,109 @@ class MyDays(QMainWindow):
        self.l0.addWidget(self.dg)
 
        # Menu
-       self.menuconfig=QAction('Configure', self)
+       self.menuconfig=QAction(self.tr('Configure'), self)
        self.menuconfig.triggered.connect(self.menuConfig)
 
-       self.menureset=QAction('Go to today', self)
+       self.menureset=QAction(self.tr('Go to today'), self)
        self.menureset.triggered.connect(self.menuReset)
 
-       self.menuabout=QAction('About', self)
+       self.menugirls=QAction(self.tr('Girls'), self)
+       self.menugirls.triggered.connect(self.menuGirls)
+
+       self.menuabout=QAction(self.tr('About'), self)
        self.menuabout.triggered.connect(self.menuAbout)
 
-       self.menuhelp=QAction('Help', self)
+       self.menuhelp=QAction(self.tr('Help'), self)
        self.menuhelp.triggered.connect(self.menuHelp)
 
        m=self.menuBar()
-       m.addAction(self.menuconfig)
        m.addAction(self.menureset)
-       m.addAction(self.menuabout)
+       m.addAction(self.menuconfig)
+       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(self.tr('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)
@@ -340,16 +438,39 @@ class MyDays(QMainWindow):
 def init(algo):
     global app
     global win
+    global qttr, maetr
 
+    # Create the application
     app=QApplication(sys.argv)
+
+    # Load translations
+    qttr=QTranslator()
+    qttr.load("qt_" + QLocale.system().name(),
+       QLibraryInfo.location(QLibraryInfo.TranslationsPath))
+    app.installTranslator(qttr)
+
+    maetr=QTranslator()
+    maetr.load("maegirls_" + QLocale.system().name(),
+       "/usr/share/maegirls/translations")
+
+    # Install the translation
+    app.installTranslator(maetr)
+
+    # One day support portrait mode
     #app.setAttribute(Qt.WA_Maemo5PortraitOrientation, True);
-    win=MyDays(algo)
+
+    # Create the main window
+    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_()