# coding: koi8-r #==================================================== # Cycle - calendar for women # Distributed under GNU Public License # Author: Oleg S. Gints (altgo@users.sourceforge.net) # Home page: http://cycle.sourceforge.net #=================================================== import warnings # deprecated since release 2.3 warnings.filterwarnings("ignore", category=RuntimeWarning, message='.*tempnam is a potential security risk to your program', module=__name__) import os import wx import wx.html import cPickle from cal_year import cycle , Val from save_load import Load_Cycle, get_f_name, set_color_default from set_dir import * #--------------------------------------------------------------------------- class Settings_Dlg(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self,parent,-1, _('Settings'), wx.DefaultPosition) self.Centre(wx.BOTH) #====================== box = wx.BoxSizer(wx.VERTICAL) b1=wx.StaticBoxSizer(wx.StaticBox(self,-1,_('Length of cycle')),wx.VERTICAL) i=wx.NewId() self.cb1 = wx.CheckBox(self, i, _(' by average'), style=wx.NO_BORDER) b1.Add(self.cb1, 0, wx.ALL, 5) self.Bind(wx.EVT_CHECKBOX, self.By_Average, id=i) self.cb1.SetValue(cycle.by_average) b2 = wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() self.sc = wx.SpinCtrl(self, i, "", size=wx.Size(50, -1)) self.sc.SetRange(21,35) self.sc.SetValue(cycle.period) self.sc.Enable(not self.cb1.GetValue()) b2.Add(self.sc, 0) b2.Add(wx.StaticText(self, -1, _(' days in cycle')), 0) b1.Add(b2, 0, wx.ALL, 5) box.Add(b1, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 10) #====================== self.rb = wx.RadioBox(self, -1, _('Display'), choices=[_('safe sex days'),_('fertile days'),_('both')], majorDimension=1, style=wx.RA_SPECIFY_COLS) box.Add(self.rb, 0, wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, 10) self.rb.SetSelection(cycle.disp) #====================== self.rb1 = wx.RadioBox(self, -1, _('First week day'), choices=[_('monday'),_('sunday')], majorDimension=1, style=wx.RA_SPECIFY_COLS) box.Add(self.rb1, 0, wx.EXPAND|wx.ALL, 10) self.rb1.SetSelection(cycle.first_week_day) #====================== i=wx.NewId() txt1=_('Colours') txt2=_('Change password') w1,h=self.GetTextExtent(txt1) w2,h=self.GetTextExtent(txt2) w = max(w1, w2) box.Add(wx.Button(self, i, txt1, size=wx.Size(w+10, -1)), 0, wx.ALIGN_CENTER) self.Bind(wx.EVT_BUTTON, self.OnColours, id=i) #====================== i=wx.NewId() box.Add(wx.Button(self, i, txt2, size=wx.Size(w+10, -1)), 0, wx.TOP|wx.ALIGN_CENTER,10) self.Bind(wx.EVT_BUTTON, self.OnChangePasswd, id=i) #====================== but_box=wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() but_box.Add(wx.Button(self, i, _('Ok')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) i=wx.NewId() but_box.Add(wx.Button(self, i, _('Cancel')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnCancel, id=i) box.Add(but_box, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) def By_Average(self, event): if event.Checked(): self.sc.Enable(False) else: self.sc.Enable(True) def OnOk(self, event): if not 21<=self.sc.GetValue()<=35: dlg = wx.MessageDialog(self, _('Period of cycle is invalid!'), _('Error!'), wx.OK |wx.ICON_ERROR ) dlg.ShowModal() dlg.Destroy() return cycle.period=self.sc.GetValue() cycle.by_average=self.cb1.GetValue() cycle.disp=self.rb.GetSelection() cycle.first_week_day=self.rb1.GetSelection() self.EndModal(wx.ID_OK) def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) def OnChangePasswd(self, event): dlg = Ask_Passwd_Dlg(self) dlg.ShowModal() dlg.Destroy() def OnColours(self, event): dlg = Colours_Dlg(self) dlg.ShowModal() dlg.Destroy() #--------------------------------------------------------------------------- class Ask_Passwd_Dlg(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self,parent,-1, _('Password')) #====================== box = wx.BoxSizer(wx.VERTICAL) box.Add(wx.StaticText(self, -1, _('Enter your password')), 0, wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.RIGHT, 10) self.pass1 = wx.TextCtrl(self, -1, "", wx.Point(10, 30), size=(130, -1), style=wx.TE_PASSWORD) box.Add(self.pass1, 0, wx.ALIGN_CENTER|wx.ALL, 10) box.Add(wx.StaticText(self, -1, _('Once more...')), 0, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 10) self.pass2 = wx.TextCtrl(self, -1, "", wx.Point(10, 80), size=(130, -1), style=wx.TE_PASSWORD) box.Add(self.pass2, 0, wx.ALIGN_CENTER|wx.ALL, 10) b1=wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() b1.Add(wx.Button(self, i, _('Ok')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('Cancel')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnCancel, id=i) self.pass1.SetFocus() box.Add(b1, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) def OnOk(self, event): err="" if self.pass1.GetValue()=="" or self.pass2.GetValue()=="": err=_('Password must be not EMPTY!') if self.pass1.GetValue() != self.pass2.GetValue(): err=_('Entering password don\'t match!') if err != "": dlg = wx.MessageDialog(self, err, _('Error!'), wx.OK |wx.ICON_ERROR ) dlg.ShowModal() dlg.Destroy() return cycle.passwd=self.pass1.GetValue() self.EndModal(wx.ID_OK) def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) #--------------------------------------------------------------------------- def get_users(): #Get list of users magic_str="UserName=" users=[] #array of (user, file) name p, f_name=get_f_name() if os.path.exists(p): files=os.listdir(p) for f in files: fd=open(os.path.join(p, f),"rb") tmp=fd.read(len(magic_str)) if tmp == magic_str: tmp=fd.read(100) n=tmp.find("===") #find end string if n <> -1: users.append((cPickle.loads(tmp[:n]), f)) else: # old format, user_name=file_name users.append((f,f)) # if not users: # users=[(_('empty'),"empty")] users.sort() return users #--------------------------------------------------------------------------- class Login_Dlg(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self,parent,-1, _('Login')) self.name="" self.file="" box = wx.BoxSizer(wx.VERTICAL) #Get list of users self.users = get_users() # p, f_name=get_f_name() # if os.path.exists(p): # users=os.listdir(p) # else: # users=[_('empty')] # users.sort() #======== List users ============== i = wx.NewId() self.il = wx.ImageList(16, 16,True) bmp=wx.Bitmap(os.path.join(bitmaps_dir, 'smiles.bmp'), wx.BITMAP_TYPE_BMP) mask = wx.Mask(bmp, wx.WHITE) bmp.SetMask(mask) idx1 = self.il.Add(bmp) self.list = wx.ListCtrl(self, i, size=wx.Size(200, 200), style=wx.LC_REPORT|wx.SUNKEN_BORDER|wx.LC_SINGLE_SEL) self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL) self.list.InsertColumn(0, _('Your name')) for k in range(len(self.users)): self.list.InsertImageStringItem(k, self.users[k][0], idx1) self.list.SetColumnWidth(0, 180) self.list.SetItemState(0, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) self.name=self.users[0][0] self.file=self.users[0][1] self.list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) self.list.Bind(wx.EVT_LIST_KEY_DOWN, self.OnKeyDown, self.list) box.Add(self.list, 0, wx.ALL, 10) #========= Add user ============= i=wx.NewId() box.Add(wx.Button(self, i, _('Add user')), 0, wx.ALIGN_CENTER) self.Bind(wx.EVT_BUTTON, self.OnAdd, id=i) #========= Ok - Cancel ============= b1=wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() b1.Add(wx.Button(self, i, _('Ok')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('Cancel')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnCancel, id=i) box.Add(b1, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) self.list.SetFocus() def OnItemSelected(self, event): self.name=self.users[event.GetIndex()][0] #self.list.GetItemText(event.GetIndex()) self.file=self.users[event.GetIndex()][1] def OnKeyDown(self, event): if event.GetKeyCode()==ord(" ") or event.GetKeyCode()==wx.WXK_RETURN: self.OnOk() else: event.Skip() def OnAdd(self, event=None): if ask_name(self): self.EndModal(wx.ID_OK) def OnOk(self, event=None): dlg = wx.TextEntryDialog(self, self.name+_(', enter you password:'),_('Password'),'', style=wx.OK | wx.CANCEL | wx.TE_PASSWORD) while dlg.ShowModal() == wx.ID_OK: cycle.passwd=dlg.GetValue() cycle.name=self.name cycle.file=self.file if Load_Cycle(cycle.name, cycle.passwd, cycle.file): dlg.Destroy() self.EndModal(wx.ID_OK) return else: dlg2 = wx.MessageDialog(self, _('Password is invalid!'), _('Error!'), wx.OK |wx.ICON_ERROR ) dlg2.ShowModal() dlg2.Destroy() dlg.Destroy() def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) #------------------------------------------------------- def first_login(): #Get list of users users = get_users() if users != []: return 'not_first' #user(s) already exists if ask_name(): return 'first' else: return 'bad_login' #------------------------------------------------------- def get_new_file_name(): while True: p, f = os.path.split( os.tempnam(None, "cycle") ) p, f_name=get_f_name(f) if not os.path.isfile(f_name): break return f #------------------------------------------------------- def ask_name(parent=None): # nobody, it is first login wx.MessageBox( _("This program is not a reliable contraceptive method. " "Neither does it help to prevent sexually transmitted diseases " "like HIV/AIDS.\n\nIt is just an electronic means of keeping track " "of some of your medical data and extracting some statistical " "conclusions from them. You cannot consider this program as a " "substitute for your gynecologist in any way.")) dlg = wx.TextEntryDialog(parent, _('Enter you name:'),_('New user'),'', style=wx.OK | wx.CANCEL) while dlg.ShowModal()==wx.ID_OK: name=dlg.GetValue() if name != "": users=get_users() exists=False for i in users: if name == i[0]: exists=True break if not exists: d=Ask_Passwd_Dlg(parent) if d.ShowModal()==wx.ID_OK: cycle.file=get_new_file_name() cycle.name=name d.Destroy() dlg.Destroy() #self.EndModal(wx.ID_OK) set_color_default() return True else: d.Destroy() continue else: err=name+_(' - already exists!') else: err=_('Name must be not EMPTY') d2 = wx.MessageDialog(dlg, err, _('Error!'), wx.OK |wx.ICON_ERROR ) d2.ShowModal() d2.Destroy() dlg.Destroy() return False #--------------------------------------------------------------------------- class Legend_Dlg(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self,parent,-1, _('Legend')) #====================== box = wx.BoxSizer(wx.VERTICAL) self._add(box, _('today'), wx.NullColour,wx.SIMPLE_BORDER) self._add(box, _('begin of cycle'), cycle.colour_set['begin']) self._add(box, _('prognosis of cycle begin'), cycle.colour_set['prog begin']) self._add(box, _('conception'), cycle.colour_set['conception']) self._add(box, _('safe sex'), cycle.colour_set['safe sex']) self._add(box, _('fertile'), cycle.colour_set['fertile']) self._add(box, _('ovule, birth'), cycle.colour_set['ovule']) self._add(box, _('1-st tablet'), cycle.colour_set['1-st tablet']) self._add(box, _('tablets N 22-28 or pause'), cycle.colour_set['pause']) self._add(box, _('next 1-st tablet'), cycle.colour_set['next 1-st tablet']) i=wx.NewId() box.Add(wx.Button(self, i, _('Ok')), 0, wx.ALIGN_CENTER|wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) def _add(self,box,txt,col,st=0): b=wx.BoxSizer(wx.HORIZONTAL) w=wx.Window(self,-1,size=wx.Size(15,15),style=st) w.SetBackgroundColour(col) b.Add(w, 0, wx.LEFT|wx.RIGHT,10) b.Add(wx.StaticText(self, -1, txt), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 10) box.Add(b, 0, wx.TOP, 10) def OnOk(self, event): self.EndModal(wx.ID_OK) #--------------------------------------------------------------------------- class Note_Dlg(wx.Dialog): def __init__(self, parent, title="",txt=""): wx.Dialog.__init__(self,parent,-1, title) self.CentreOnParent(wx.BOTH) #====================== box = wx.BoxSizer(wx.VERTICAL) self.txt=wx.TextCtrl(self, -1, txt, size=(-1, 100), style=wx.TE_MULTILINE) box.Add( self.txt, 0, wx.EXPAND|wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.RIGHT, 10) b1=wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() b1.Add(wx.Button(self, i, _('Ok')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('Cancel')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnCancel, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('Remove')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnRemove, id=i) box.Add(b1, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) self.txt.SetFocus() def OnOk(self, event): self.EndModal(wx.ID_OK) def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) def OnRemove(self, event): self.EndModal(False) def Get_Txt(self): return self.txt.GetValue() #--------------------------------------------------------------------------- class MyHtmlWindow(wx.html.HtmlWindow): def __init__(self, parent, id, pos = wx.DefaultPosition, size=wx.DefaultSize): wx.html.HtmlWindow.__init__(self, parent, id, pos, size) if "gtk2" in wx.PlatformInfo: self.SetStandardFonts() def OnLinkClicked(self, linkinfo): pass #--------------------------------------------------------------------------- class Help_Dlg(wx.Dialog): def __init__(self, parent, title="",txt=""): wx.Dialog.__init__(self,parent,-1, title) self.CentreOnParent(wx.BOTH) #====================== box = wx.BoxSizer(wx.VERTICAL) self.html=MyHtmlWindow(self, -1, size=(500, 350)) self.html.SetPage(txt) box.Add( self.html, 0, wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.RIGHT, 10) i=wx.NewId() box.Add(wx.Button(self, i, _('Ok')), 0, wx.ALIGN_CENTER|wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) def OnOk(self, event): self.EndModal(wx.ID_OK) #--------------------------------------------------------------------------- class Colours_Dlg(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self,parent,-1, _('Colours settings')) self.col_set = cycle.colour_set.copy() self.col_id = cycle.colour_set.keys() self.data = wx.ColourData() self.data.SetChooseFull(True) self.buttons = {} #====================== box = wx.BoxSizer(wx.VERTICAL) self._add(box, _('begin of cycle'), 'begin') self._add(box, _('prognosis of cycle begin'), 'prog begin') self._add(box, _('conception'), 'conception') self._add(box, _('safe sex'), 'safe sex') self._add(box, _('fertile'), 'fertile') self._add(box, _('ovule, birth'), 'ovule') self._add(box, _('1-st tablet'), '1-st tablet') self._add(box, _('tablets N 22-28 or pause'), 'pause') self._add(box, _('next 1-st tablet'), 'next 1-st tablet') b1=wx.BoxSizer(wx.HORIZONTAL) i=wx.NewId() b1.Add(wx.Button(self, i, _('Ok')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnOk, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('By default')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnDefault, id=i) i=wx.NewId() b1.Add(wx.Button(self, i, _('Cancel')), 0, wx.ALL, 10) self.Bind(wx.EVT_BUTTON, self.OnCancel, id=i) box.Add(b1, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) def _add(self, box, txt, col): b=wx.BoxSizer(wx.HORIZONTAL) i=self.col_id.index(col) bt=wx.Button(self, i, "", size=wx.Size(15,15)) self.Bind(wx.EVT_BUTTON, self.get_colour, id=i) bt.SetBackgroundColour(self.col_set[col]) self.buttons.update({i:bt}) b.Add(bt, 0, wx.LEFT|wx.RIGHT,10) b.Add(wx.StaticText(self, -1, txt), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 10) box.Add(b, 0, wx.TOP, 10) def get_colour(self, event): c = self.col_set[ self.col_id[event.GetId()] ] self.data.SetColour(c) dlg = wx.ColourDialog(self, self.data) if dlg.ShowModal() == wx.ID_OK: self.data = dlg.GetColourData() c = self.data.GetColour() self.buttons[event.GetId()].SetBackgroundColour(c) self.col_set[self.col_id[event.GetId()]] = c def OnOk(self, event): cycle.colour_set = self.col_set.copy() Val.Cal.Draw_Mark() self.EndModal(wx.ID_OK) def OnDefault(self, event): self.col_set = {'begin':wx.NamedColour('RED'), 'prog begin':wx.NamedColour('PINK'), 'conception':wx.NamedColour('MAGENTA'), 'safe sex':wx.NamedColour('WHEAT'), 'fertile':wx.NamedColour('GREEN YELLOW'), 'ovule':wx.NamedColour('SPRING GREEN'), '1-st tablet':wx.NamedColour('GOLD'), 'pause':wx.NamedColour('LIGHT BLUE'), 'next 1-st tablet':wx.NamedColour('PINK')} for item in self.col_id: self.buttons[self.col_id.index(item)].SetBackgroundColour(self.col_set[item]) def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) #---------------------------------------------------------------------------