pax_global_header00006660000000000000000000000064144356676070014534gustar00rootroot0000000000000052 comment=b9671a71dce312913d1f98bf221417e128b1b85a cycle-0.3.3/000077500000000000000000000000001443566760700126365ustar00rootroot00000000000000cycle-0.3.3/.gitignore000066400000000000000000000000771443566760700146320ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] cycle-0.3.3/BUGS000066400000000000000000000000001443566760700133070ustar00rootroot00000000000000cycle-0.3.3/CHANGELOG000066400000000000000000000073711443566760700140600ustar00rootroot00000000000000#====================================================================== # Cycle - calendar for women # Distributed under GNU General Public License # Original Author: Oleg S. Gints (altgo@users.sourceforge.net) # Adopted by: Konstantin L. Metlov (metlov@donfti.ru, metlov@fti.dn.ua) # Other contributors are listed alongside their changes # Home page: https://github.com/metlov/cycle #====================================================================== 0.3.3 (31.05.2023) - fixed the Note dialog - merged the actions of LMB and RMB on calendar to make it easier to operate on it from touchscreen devices - fixed some more integer divisions - compatibility with old saves after "sip"->"wx.siplib" module rename 0.3.2 (13.10.2022) - removed outdated Readme.Debian - converted README files to Markdown - fix heading syntax in README.ru.md - readded forgotten export.png bitmap from Ana Guerrero López - added gitignore file from Ana Guerrero López : - Fix diaglogs - Line breaks in dialog message (with Miriam Ruiz) - Enhance dialog strings - Fix calendar string format - Report as ical - Export to ical from Miriam Ruiz : - Use hashlib when saving / loading - Fix spelling from Olly Betts (as per https://bugs.debian.org/758955) - Update for wxPython 3.0 - Fix initial size of main window from Konstantin L. Metlov - ported to Python 3 using the 2to3 script - reformatted the sources using autopep8 - ported to wxGTK 4 - fixed the encryption (to stay compatible with Python 2 version) #==================================================== # Cycle - calendar for women # Distributed under GNU Public License # Author: Oleg S. Gints (altgo@users.sourceforge.net) # Home page: http://cycle.sourceforge.net #=================================================== 0.3.1 (15.09.2005) - change to Python 2.4 - repleace rotor module - restore old default color scheme - The description of the program in English from Marco Papa Manzillo is corrected - Now the name of the user is stored in a file with data. from Miriam Ruiz : - fixed colors not initialized the first time a user was created. - Added code to use wx 2.5.3 or higher if multiple versions are installed. - Added es, ca and gl translations, and solved some bugs in locale subsystem. - Added note alerting that this is not a reliable contraceptive method every time a new user is created. - Added man page - fixed Cycle for unicode version of wx 0.3.0 (21.12.2004) - Add translation to the german language from Christian Weiske - change to wxPython = 2.5.X 0.2.1 (06.06.2004) - Add colours settings 0.2.0 (28.04.2004) - Add translation for czech and slovak language from Jozef Riha - change to Python 2.3 - Add description for english language from Marco Papa Manzillo 0.0.5 (30.12.2002) - fix PopupMenu for new wxPythonGTK-2.3.3.1 - fix exception from LANGUAGE=lang1:lang2 0.0.4 (24.10.2002) - add setup.py and MANIFEST.in, now make new release so: python setup.py sdist - add check reception of hormonal contraceptive tablets 0.0.3 (16.05.2002) - Add icons - Convert README* in *.html 0.0.2 (05.05.2002) - Add line under toolbar - Change color legend "today" - Change BackgroundColour = LIGHT BLUE - clean up code - Add Note - Add calc birthday - encode messages to locale - Add method "by average" - Add cycle.spec 0.0.1 (22.04.2002) - First release cycle-0.3.3/COPYRIGHT000066400000000000000000000015501443566760700141320ustar00rootroot00000000000000 CYCLE - calendar for women Copyright (C) 2002-2005 Oleg S. Gints Copyright (C) 2002-2005 "CONERO lab", http://conero.lrn.ru Copyright (C) 2022-2023 Konstantin L. Metlov This program 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; version 2 dated June, 1991, or any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. cycle-0.3.3/INSTALL000066400000000000000000000005561443566760700136750ustar00rootroot00000000000000#==================================================== # Cycle - calendar for women # Distributed under GNU Public License # Author: Oleg S. Gints (altgo@users.sourceforge.net) # Home page: http://cycle.sourceforge.net #=================================================== 1. Install Python, wxPythonGTK-2.5.x first. 3. Unpack cycle-X.X.X.tar.gz 3. Run cycle.py cycle-0.3.3/MANIFEST.in000066400000000000000000000004301443566760700143710ustar00rootroot00000000000000include *.py include bitmaps/*.* include cycle.spec include README* include MANIFEST.in include INSTALL include CHANGELOG include COPYRIGHT include THANKS include BUGS include cycle.1 recursive-include msg *.* recursive-include icons *.* prune */.xvpics prune */*/.xvpics cycle-0.3.3/PKG-INFO000066400000000000000000000003521443566760700137330ustar00rootroot00000000000000Metadata-Version: 1.0 Name: cycle Version: 0.3.1 Summary: Calendar for women Home-page: http://cycle.sourceforge.net Author: Oleg Gints Author-email: altgo@users.sourceforge.net License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN cycle-0.3.3/README.de.md000066400000000000000000000074721443566760700145160ustar00rootroot00000000000000[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![de](https://img.shields.io/badge/lang-de-green.svg)](README.de.md) [![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) # CYCLE - Ein Kalender für Frauen **DD.MM.YYYY Version 0.3.3** 2002-2005 (c) Oleg Gints (altgo@users.sourceforge.net) 2002-2005 (c) "CONERO lab", http://conero.lrn.ru 2023 (c) Konstantin L. Metlov (metlov@donfti.ru , metlov@fti.dn.ua) ### PROGRAMMFEATURES * Berechnung der Menstruationstage basierend auf der Länge des Zyklus oder der letzten Perioden * Berechnung der Tage des "sicheren" Sex, erhöhter Fruchtbarkeit und Eisprungs * Voraussage des Tages der Empfängnis eines Kindes * Notizfunktion * Hilft bei der Einnahme von hormonellen Empfängnispillen ### WIE ES FUNKTIONIERT Das Programm verwendet die _Kalendermethode_ für die Berechnung der fruchtbaren Tage. Dafür ist es notwendig, die Dauer von mindestens sechs vergangenen Perioden zu kennen. Für die Berechnung wird folgender Algorithmus verwendet: * Erster Tag: Dauer des kürzesten Zyklus minus 18 * Letzter Tag: Dauer des längsten Zyklus minus 11 * Eisprung: Wird in der Mitte der fruchtbaren Tage vermutet (Mit der Kalendermethode ist die exakte Berechnung nicht möglich) Mehr Informationen über die Kalendermethode sind unter [http://www.mama.ru/gynecolog/STA/st18.htm](http://www.mama.ru/gynecolog/STA/st18.htm) (in russisch) verfügbar. Der Tag der Empfängnis (Geburt) eines Kindes wird vom Beginn der letzten Menstruation gezählt. Dieses Datum wird mit der Dauer eines Zyklus korrigiert (Es wird die Anzahl der Tage addiert/subtrahiert, die die Zyklusdauer von 28 Tagen abweicht). Es ist möglich, das Ergebnis unter folgender Adresse zu überprüfen: [http://cir.msk.ru/sroki.shtml](http://cir.msk.ru/sroki.shtml) (in russisch) ### PROGRAMMNUTZUNG Es ist notwendig, den Beginn der letzten Menstruationen per Hand zu markieren. Dies geschieht durch einen Klick mit der rechten Maustaste auf einen Tag im Kalender und der Auswahl von "Zyklusbeginn". Auf dieselbe Art kann die Markierung entfernt werden. Mit Hilfe der Dauer der letzten sechs Zyklen wird das Programm folgendes berechnen: * Fruchtbare Tage - grüne Zellen * Eisprung (Mitte der fruchtbaren Tage) - hellgrüne Zelle * Beginn der nächsten Menstruation - pinke Zelle Die Zyklusdauer kann in den Einstellungen festgelegt werden oder über den Durchschnitt der Dauer der letzten 6 Zyklen berechnet werden. Um den voraussichtlichen Tag der Geburt des Kindes zu berechnen ist es nötig, den ersten Tag des letzten Zyklus zusätzlich als "Schwanger" zu markieren. Abhängig von Ihren Absichten können sowohl Tage des "sicheren" Sex als auch nur fruchtbare Tage angezeigt werden. Informationen über interessante Tage können mit einem Linksklick auf den entsprechenden Tag aufgerufen werden. Es ist möglich, Notizen zu einem Tag hinzuzufügen. Tage mit Notiz werden unterstrichen dargestellt. _Hinweis:_ Die Fehlerrate der Kalendermethod liegt bei ca. 10 Prozent. Sie ist nur für Frauen mit einer regelmäßigen Periode zu empfehlen. Wenn Ihnen Ihr Arzt die Pille verschrieben hat, wird Ihnen das Programm bei der Einhaltung der regelmäßigen Einnahme helfen. Machen Sie sich aber trotzdem mit den Hinweisen auf der Packungsbeilage vertraut! Eine Packung kann 21 Tabletten (Der Zyklus dauert 21 Tage, danach 7 Tage Pause) oder 28 Tabletten enthalten - diese werden dann jeden Tag eingenommen. Im Programm wird nur der Tag markiert, an dem die erste Tablette eingenommen werden muss. ### VERTEILUNGSBESTIMMUNGEN Das Programm "Cycle" wird unter der **GNU General Public License** verteilt in der Hoffnung, dass es nützlich sein wird. Es gibt aber keine Garantie, dass es korrekt oder überhaupt funktioniert. (Siehe Datei "COPYRIGHT") Übersetzung: Christian Weiske (cweiske@users.sourceforge.net) cycle-0.3.3/README.md000066400000000000000000000066701443566760700141260ustar00rootroot00000000000000[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![de](https://img.shields.io/badge/lang-de-green.svg)](README.de.md) [![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) # CYCLE - menstrual cycle tracker for women **DD.MM.YYYY Version 0.3.3** 2002-2005 (c) Oleg Gints (altgo@users.sourceforge.net) 2002-2005 (c) "CONERO lab", http://conero.lrn.ru 2023 (c) Konstantin L. Metlov (metlov@donfti.ru , metlov@fti.dn.ua) ### PROGRAM FEATURES * Calculation of days of menstruation, based on length of cycle or period statistics * Calculation of "safe" sex days, fertile period and days to ovulation * Calculation of D.O.B. (Date Of Birth) of a child * Allows you to write notes * Helps you decide when to take the pill. ### HOW IT WORKS It uses the _calendar (or rhythm) method_ for the definition of fertile days. For this you need to determine the duration, of last six cycles at least. To determine the fertile days it uses this algorithm: * First day: duration of shortest cycle minus 18 * Last day: duration of longest cycle minus 11 * Ovulation: is considered to be in the middle of fertile period (To determine the exact day isn't possible with the calendar method) More information about the calendar method is available at: [http://www.mama.ru/gynecolog/STA/st18.htm](http://www.mama.ru/gynecolog/STA/st18.htm) (in Russian) Date of birth of the child is counted from the beginning of last menstruation (in obstetrics 40 weeks is normally used). This date is corrected with the duration of a cycle (the number of days that the cycle differs from 28 days is added or subtracted). It is possible to check the results at: [http://cir.msk.ru/sroki.shtml](http://cir.msk.ru/sroki.shtml) (in Russian) ### HOW TO USE THE PROGRAM Mark the beginning of menstruation. This is done by clicking with the right button on the date and chosing "beginning of cycle". Similarly the mark can be removed. Using duration of the last six cycles, the program will calculate and display the: * Fertile period - green cells * Ovulation day (the middle of the fertile period) - brightly green cell * Beginning of following menstruation - pink cells Cycle duration is set in options or is calculated as an average of last six periods. To determine the likely date of birth of the child, it is necessary to mark the first day of the last cycle as "Pregnancy". Depending on your preferences, you can display only "Safe" sex days or only fertile days. Information about a day can be seen at the bottom, by left clicking on the day. It is possible to add a note to any date using a right click. Days with a note are underlined. There is a 10 percent failure rate of the calendar contraception method This method is suitable only for women with a regular enough cycle. If your doctor has recommended oral contraceptive pills this program can help you take them at the right date. Familiarize yourself thorougly with the instructions that come with the strip of tablets. The strip can contain 21 tablets (a tablet a day for 21 days, then 7 days pause) or 28 tablets (in this case a table a day without interuption, over 28 days). In the program, only the day when you first start on a strip is noted. ### CONDITIONS OF DISTRIBUTION Program "Cycle" is distributed under **GNU General Public License**, in the hope that it will be useful, but **WITHOUT ANY WARRANTY** (see file COPYRIGHT). Translation - Marco Papa Manzillo (mpapamanz@users.sourceforge.net) cycle-0.3.3/README.ru.md000066400000000000000000000153641443566760700145530ustar00rootroot00000000000000[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![de](https://img.shields.io/badge/lang-de-green.svg)](README.de.md) [![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) # ЦИКЛ - календарь для женщин **DD.MM.YYYY Версия 0.3.3* 2002-2005 (c) Олег Гинц (altgo@users.sourceforge.net) 2002-2005 (c) "CONERO lab", http://conero.lrn.ru 2023 (c) Константин Л. Метлов (metlov@donfti.ru , metlov@fti.dn.ua) ### Возможности программы: * по заданной продолжительности цикла или по набранной статистике за несколько периодов спрогнозировать дни начала менструаций * рассчитать дни "безопасного" секса, фертильный период и день овуляции * определить дату рождения ребенка * позволяет вести заметки * помогает контролировать прием противозачаточных гормональных таблеток ### Принцип работы. Для определения фертильных дней использован _календарный метод_. По этому методу необходимо определить длительность как минимум шести последних циклов. От количества дней в самом длинном цикле отнимается 11, это будет последний фертильный день. От продолжительности самого короткого цикла вычитается 18, это будет первый фертильный день. Условно день овуляции определяется как середина фертильного периода. Точно определить день овуляции расчетным путем на основании только продолжительности цикла не представляется возможным. Более подробно с календарным методом можно ознакомиться здесь: [http://www.mama.ru/gynecolog/STA/st18.htm](http://www.mama.ru/gynecolog/STA/st18.htm) Дата рождения ребенка определяется (как принято в акушерстве) 40 недель от начала последней менструации. Эта дата корректируется в зависимости от продолжительности цикла - вычитается или добавляется количество дней, насколько цикл отличается от 28 дней. Проверить работу программы можно здесь: [http://cir.msk.ru/sroki.shtml](http://cir.msk.ru/sroki.shtml) ### Как пользоваться программой. Вам необходимо отмечать в календаре дни начала менструаций. Для этого на выбранной дате нажмите правую кнопку мышки, и появившемся меню выберете пункт "Начало цикла". Аналогичным образом отметку можно удалить. На основании длительности шести последних циклов программа рассчитает фертильный период (клетки светло-зеленого цвета). Ярко зеленым цветом выделяется предполагаемый день овуляции (середина фертильного периода). Розовый цвет - предполагаемая дата начала следующей менструации. Продолжительность цикла устанавливается в настройках программы. Здесь Вы можете задать длительность цикла непосредственно в днях, либо включить расчет по среднему. В таком случае программа использует среднюю продолжительность цикла за шесть последних периодов. Чтобы определить предполагаемую дату рождения ребенка, необходимо последнее начало цикла пометить дополнительно как "Беременность". В зависимости от Ваших целей вы можете включить отображение только дней "безопасного" секса или только фертильных дней. Информацию по интересующей дате можно получить, щелкнув по ней левой кнопкой мышки. Для удобства к любой дате можно добавить заметку, выбрав соответствующий пункт меню. Дата с заметкой помечается подчеркнутым шрифтом. Необходимо отметить, что коэффициент неудач у календарного метода контрацепции около 10 процентов. Пользоваться таким методом могут женщины с достаточно регулярным менструальным циклом. Если врач порекомендовал и подобрал для Вас гормональные противозачаточные средства, то программа поможет контролировать их прием. Внимательно ознакомьтесь с инструкцией, прилагаемой к выбранному препарату. Упаковка может содержать 21 таблетку - схема приема 21 день по одной таблетке, затем 7 дней перерыв, либо 28 таблеток - в таком случае таблетки принимаются по одной без перерыва все 28 дней. В программе отмечается только день приема каждой 1-ой таблетки упаковки. ### Условия распространения. Программа Cycle распространяется под лицензией **GNU General Public License**, без каких либо гарантий (см. файл COPYRIGHT). Автор не несет никакой ответственности за последствия использования этой программы. cycle-0.3.3/THANKS000066400000000000000000000006641443566760700135570ustar00rootroot00000000000000Sergey Kalinin (aka BanZaj) banzaj@lrn.ru (pogramm tester) Jozef Riha translation for czech and slovak language Marco Papa Manzillo - translation description for english language Christian Weiske translation to the german language Miriam Ruiz for greater work on improvement and correction of the program (see CHANGELOG) cycle-0.3.3/bitmaps/000077500000000000000000000000001443566760700142755ustar00rootroot00000000000000cycle-0.3.3/bitmaps/curr.png000066400000000000000000000006311443566760700157560ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGDAT pHYs ,tIME))tOIDATx=n1F !e)i%m8 -51rn2)H"Ca7aA[ 24oycQUڌN ""aNEL.jIN8jhQ"Av]L~dxK@Q4ۺ ~@pfx *;ЙT:cWg5'5lmAvЁB "oNSkN/ZqT:5AljoiQ7xb`U.!gs?q6lBIENDB`cycle-0.3.3/bitmaps/dec.png000066400000000000000000000006551443566760700155440ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs ,tIME *IDATx͕1N1E@C(SӦ&p@8'!UD%AJHOaބY)_ʚ^&!u2̐;&|$]ܽ \ ]M )|9Ru]^B0q̀l,}`z yM#dO3==x=yx>H߃cu>:fmcmة3a b,AYHjF &",<*Q9NF*If<$=IU@awCՄ-w8>uQ@LIENDB`cycle-0.3.3/bitmaps/exit.png000066400000000000000000000006031443566760700157530ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs ?@"tIME. IDATx1 0:u',::tF^#ݼ 8BO(Hjj[k~"^-u_J TBTW0@ i`Y@`?1]kgmk),g)%#ӱ1uU5^A[,Z$# 401QjNawav7 o~$^7n^6.f!ycl3^7BuRZIENDB`cycle-0.3.3/bitmaps/exit.xcf000066400000000000000000000043271443566760700157560ustar00rootroot00000000000000gimp xcf fileBBgxarrow     %5@~88.8.%g]TK8.% g]TK8.% g]TK8.% g]TK8.% g]TK8.% g]TK8.% g]TK8.% 8.%8.%8.%8.8nM oM odoor     -="                     "                     "                           M   PM 88 8.8.8.%8.%g]TK8.%8.%g]TK8.%8.%g]TK8.%.%g]TK8.%.%g]TK8.%.%g]TK8.%8.%g]TK8.% 8.% 8.%8.%8.%8.%8.%8.%%8.88.. 888 Pj      Ptcycle-0.3.3/bitmaps/export.png000066400000000000000000000005211443566760700163220ustar00rootroot00000000000000PNG  IHDRw=bKGDAT pHYs ?@"tIME84ikIDATH=@km\΄pAHb2;H$&:0{. `r53 #Y{/'x 1Z'$$dHy %Ck&T$7DF C ;s8'-o{vFN@+}R=0QJC?B=Y=B߰}|7g5 sn׀[TsGD"H!|ޯM .Ko4xj{;vp61C Nrs,,p-sg6(vIg8D!Jc )~Ac,Ye|Ʌd ֋ڋX7U%tl~x{yFIENDB`cycle-0.3.3/bitmaps/help.xcf000066400000000000000000000045271443566760700157370ustar00rootroot00000000000000gimp xcf fileBBk?      - " "@iEring     r@@7  O7E۞E  44  0000  44  E۞EN     VjzP    PP8 88. .88.%%.88.%%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz %.8KT]gpz%.88.%%.88.%%.88.%.88. 88 Pj     PP33l i}7E۞E  44  0000  44  E۞ENcycle-0.3.3/bitmaps/inc.png000066400000000000000000000006731443566760700155620ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs ,tIME5u8IDATx͕N0D2XHHgbeAJ$$3I[D,nsjVHmMb +;E@|ٙL33^fYHoF;1izĨ ]ihXw&vO>NEV ?`m]s89.۰0M~`9I +jPK% ڱV3%2h aU"E>$U "pF.H@|͓ndK.o<`~p.O>GnzVCIENDB`cycle-0.3.3/bitmaps/legend.png000066400000000000000000000003011443566760700162330ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs ?@"tIME5S^ğ>IDATxc| L$&Z0jFJ"&$A4jcA?IENDB`cycle-0.3.3/bitmaps/set.png000066400000000000000000000005541443566760700156020ustar00rootroot00000000000000PNG  IHDRw=gAMA abKGD pHYs ?@"tIME)KxDIDATx핽 03}VHR0DlR*m6g,I'ـgκ3b qѺge H4`ή / <0[Sh *EZ$G_Zƨp+ CbI0kl1L-cܽ\^v'NB ifݼFvLf`d@ۋBۋm7 "&GnW܁&IENDB`cycle-0.3.3/bitmaps/set.xcf000066400000000000000000000040761443566760700156010ustar00rootroot00000000000000gimp xcf fileBB(g?      !1              @nring     @@7  O7E۞E  44  0000  44  E۞EN     P    PP8 88. .88.%%.88.%%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz%.8KT]gpz %.8KT]gpz%.88.%%.88.%%.88.%.88. 88 Pj     PP33lcycle-0.3.3/bitmaps/smiles.bmp000066400000000000000000000003661443566760700162760ustar00rootroot00000000000000BMv( 𻻐 𻻻 𻻻cycle-0.3.3/cal_year.py000066400000000000000000000551551443566760700150020ustar00rootroot00000000000000# 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 wx import wx.adv import calendar import operator from functools import reduce import dialogs class Val: pass MARK_BEGIN = 1 MARK_FERT = 1 << 1 MARK_OVUL = 1 << 2 MARK_SAFESEX = 1 << 3 MARK_TODAY = 1 << 4 MARK_NOTE = 1 << 5 MARK_PROG = 1 << 6 MARK_LAST = 1 << 7 # last cycle, conception begin MARK_BIRTH = 1 << 8 MARK_TABLET = 1 << 9 # 1-st hormonal tablet MARK_T22_28 = 1 << 10 # tablets 22-28 or pause 7 days MARK_NEXT_TABLET = 1 << 11 # -------------------- class Month_Cal ------------------- class Month_Cal(wx.adv.GenericCalendarCtrl): def __init__(self, parent, id, dt, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): style = wx.adv.CAL_NO_MONTH_CHANGE | wx.NO_BORDER if cycle.first_week_day == 0: style = style | wx.adv.CAL_MONDAY_FIRST else: style = style | wx.adv.CAL_SUNDAY_FIRST try: style = style | wx.adv.CAL_SEQUENTIAL_MONTH_SELECTION except NameError: pass wx.adv.GenericCalendarCtrl.__init__( self, parent, id, dt, pos, size, style) self.SetBackgroundColour(wx.WHITE) self.SetHeaderColours(wx.BLACK, wx.WHITE) if '__WXMSW__' in wx.PlatformInfo: font = self.GetFont() font.SetFaceName("MS Sans Serif") self.SetFont(font) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_KEY_UP, self.OnKey) self.Bind(wx.EVT_KEY_DOWN, self.OnKey) self.d_click = wx.DateTime() # FromDMY(1, 0,2002) def OnLeftDown(self, event): self.OnRightDown(event) def OnRightDown(self, event): # HitTest(Point pos) -> (result, date, weekday) res, d, w = self.HitTest(event.GetPosition()) if res == wx.adv.CAL_HITTEST_DAY: # now d contain clicked day Val.frame.SetStatusText(info(d)) self.d_click = d menu = wx.Menu() menu.Append(1, d.Format('%d %B')) menu.AppendSeparator() menu.AppendCheckItem(2, _('Beginning of cycle')) menu.Check(2, is_set_mark(d, MARK_BEGIN, d.GetYear())) menu.AppendCheckItem(5, _('1-st tablet')) menu.Check(5, is_set_mark(d, MARK_TABLET, d.GetYear())) if is_set_mark(d, MARK_BEGIN, d.GetYear()): menu.AppendCheckItem(3, _('Conception')) menu.Check(3, is_set_mark(d, MARK_LAST, d.GetYear())) menu.AppendCheckItem(4, _('Note')) menu.Check(4, is_set_mark(d, MARK_NOTE, d.GetYear())) self.Bind(wx.EVT_MENU, self.OnBegin, id=2) self.Bind(wx.EVT_MENU, self.OnLast, id=3) self.Bind(wx.EVT_MENU, self.OnNote, id=4) self.Bind(wx.EVT_MENU, self.OnTablet, id=5) self.PopupMenu(menu, event.GetPosition()) menu.Destroy() def OnBegin(self, event): if self.d_click in cycle.begin: cycle.begin.remove(self.d_click) if self.d_click in cycle.last: cycle.last.remove(self.d_click) remove_mark(self.d_click, MARK_BEGIN, self.d_click.GetYear()) remove_mark(self.d_click, MARK_LAST, self.d_click.GetYear()) else: cycle.begin.append(self.d_click) cycle.begin.sort() add_mark(self.d_click, MARK_BEGIN, self.d_click.GetYear()) Val.Cal.Draw_Mark() def OnLast(self, event): if self.d_click in cycle.begin: if self.d_click in cycle.last: cycle.last.remove(self.d_click) remove_mark(self.d_click, MARK_LAST, self.d_click.GetYear()) else: cycle.last.append(self.d_click) cycle.last.sort() add_mark(self.d_click, MARK_LAST, self.d_click.GetYear()) Val.Cal.Draw_Mark() def OnNote(self, event): txt = get_note(self.d_click) dlg = dialogs.Note_Dlg(self, self.d_click.Format('%d %B'), txt) ret = dlg.ShowModal() t = dlg.Get_Txt() dlg.Destroy() if ret == wx.ID_OK: add_note(self.d_click, t) add_mark(self.d_click, MARK_NOTE, self.d_click.GetYear()) elif ret == False: remove_note(self.d_click) remove_mark(self.d_click, MARK_NOTE, self.d_click.GetYear()) elif ret == wx.ID_CANCEL: return Val.Cal.Draw_Mark() def OnTablet(self, event): if self.d_click in cycle.tablet: cycle.tablet.remove(self.d_click) remove_mark(self.d_click, MARK_TABLET, self.d_click.GetYear()) else: cycle.tablet.append(self.d_click) cycle.tablet.sort() add_mark(self.d_click, MARK_TABLET, self.d_click.GetYear()) Val.Cal.Draw_Mark() def OnKey(self, event): k = event.GetKeyCode() if k == wx.WXK_LEFT or k == wx.WXK_RIGHT or \ k == wx.WXK_UP or k == wx.WXK_DOWN: pass else: event.Skip() # -------------------- class Cal_Year ------------------- class Cal_Year(wx.ScrolledWindow): def __init__(self, parent): wx.ScrolledWindow.__init__(self, parent, -1) # self.SetScrollbars(20, 20, 39, 40) self.SetBackgroundColour('LIGHT BLUE') dt = wx.DateTime.Today() self.year = dt.GetYear() self.day_of_year = [] self.month = [] Val.Cal = self self.Init_Year() # self.Draw_Mark() def Inc_Year(self): self.year += 1 self.Draw_Year() reset_mark(self.year) self.Draw_Mark() def Dec_Year(self): self.year -= 1 self.Draw_Year() reset_mark(self.year) self.Draw_Mark() def Set_Year(self, year): self.year = year self.Draw_Year() reset_mark(self.year) self.Draw_Mark() def Init_Year(self): m = 0 box = wx.BoxSizer(wx.VERTICAL) box.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL), 0, wx.EXPAND) for y in range(3): row_box = wx.BoxSizer(wx.HORIZONTAL) for x in range(4): t = wx.DateTime.FromDMY(1, m, self.year) id = wx.NewId() self.month.append(Month_Cal(self, id, t, )) row_box.Add(self.month[m], 0, wx.ALL, 5) m += 1 box.Add(row_box, 0, wx.LEFT | wx.RIGHT, 10) self.SetAutoLayout(True) self.SetSizer(box) box.Fit(self) w = box.GetSize().GetWidth() h = box.GetSize().GetHeight() Val.frame.SetClientSize(wx.Size(w+10, h+90)) self.SetScrollbars(20, 20, w//20, h//20) def Draw_Year(self): Val.frame.SetTitle(cycle.name+" - "+str(self.year)) for m in range(12): t = wx.DateTime.FromDMY(1, m, self.year) self.month[m].EnableMonthChange(True) self.month[m].SetDate(t) self.month[m].EnableMonthChange(False) self.month[m].Refresh() def Draw_Mark(self): f_norm = self.month[1].GetFont() f_norm.SetUnderlined(False) f_ul = self.month[1].GetFont() f_ul.SetUnderlined(True) dt = wx.DateTime.Today() if self.year == dt.GetYear(): add_mark(dt, MARK_TODAY, self.year) calc_fert(self.year) calc_tablet(self.year) k = 1 for m in range(12): sel_hide = True # need hide selection for d in range(1, wx.DateTime.GetNumberOfDays(m, self.year)+1): can_hide = True lab = cycle.mark.get(k, 0) at = wx.adv.CalendarDateAttr(wx.BLACK) at.SetBackgroundColour(wx.WHITE) at.SetFont(f_norm) dt = wx.DateTime.FromDMY(d, m, self.year) if not dt.IsWorkDay(): # mark weekend at.SetTextColour('firebrick') if lab & MARK_BEGIN: at.SetBackgroundColour(cycle.colour_set['begin']) at.SetTextColour(wx.WHITE) if lab & MARK_PROG: at.SetBackgroundColour(cycle.colour_set['prog begin']) at.SetTextColour(wx.BLACK) if lab & MARK_SAFESEX and (cycle.disp == 0 or cycle.disp == 2): at.SetBackgroundColour(cycle.colour_set['safe sex']) if lab & MARK_FERT and (cycle.disp == 1 or cycle.disp == 2): at.SetBackgroundColour(cycle.colour_set['fertile']) if lab & MARK_OVUL and (cycle.disp == 1 or cycle.disp == 2): at.SetBackgroundColour(cycle.colour_set['ovule']) if lab & MARK_TODAY: at.SetBorderColour('NAVY') at.SetBorder(wx.adv.CAL_BORDER_SQUARE) can_hide = False if lab & MARK_LAST: at.SetBackgroundColour(cycle.colour_set['conception']) if lab & MARK_NOTE: at.SetFont(f_ul) can_hide = False if lab & MARK_BIRTH: at.SetBackgroundColour(cycle.colour_set['ovule']) if lab & MARK_TABLET: at.SetBackgroundColour(cycle.colour_set['1-st tablet']) if lab & MARK_T22_28: at.SetBackgroundColour(cycle.colour_set['pause']) if lab & MARK_NEXT_TABLET: at.SetBackgroundColour( cycle.colour_set['next 1-st tablet']) if sel_hide and can_hide: # we can hide selection when don't use border and underlined sel_hide = False self.month[m].SetDate(dt) self.month[m].SetHighlightColours(at.GetTextColour(), at.GetBackgroundColour()) self.month[m].SetAttr(d, at) k += 1 # so visual refresh is more fast for m in range(12): self.month[m].Refresh() # -------------------- work with cycle ------------------- class cycle: begin = [] last = [] tablet = [] period = 28 mark = {} passwd = "123" name = "empty" file = "empty" by_average = False disp = 0 first_week_day = 0 note = {} colour_set = {} # colour_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')} def min_max(i): """Return length max and min of 6 last cycles from i item cycle.begin""" if len(cycle.begin) < 2 or i == 0: return cycle.period, cycle.period last_6 = [] for k in range(i, 0, -1): span = (cycle.begin[k]-cycle.begin[k-1]+wx.TimeSpan.Hours(1)).GetDays() # wx.TimeSpan.Hours(1) - if 20 < span < 36: # last_6.append(span) if len(last_6) >= 6: break if cycle.by_average and len(last_6) != 0: s = float(reduce(operator.add, last_6)) # sum of last_6 cycle.period = int(round(s/len(last_6), 0)) if last_6 == []: return cycle.period, cycle.period return min(last_6), max(last_6) def calc_fert(year): """ year""" for k in list(cycle.mark.keys()): cycle.mark[k] = cycle.mark[k] & ~MARK_FERT &\ ~MARK_OVUL & ~MARK_PROG & ~MARK_SAFESEX & ~MARK_BIRTH &\ ~MARK_T22_28 & ~MARK_NEXT_TABLET # if cycle.begin == []: return year_b = wx.DateTime.FromDMY(1, 0, year) year_e = wx.DateTime.FromDMY(31, 11, year) for d in cycle.begin: i = cycle.begin.index(d) if i < len(cycle.begin)-1: if (cycle.begin[i+1]-cycle.begin[i]+wx.TimeSpan.Hours(1)).GetDays() < 21: # wx.TimeSpan.Hours(1) - # continue min, max = min_max(i) begin = d+wx.DateSpan.Days(min-18) # begin fertile end = d+wx.DateSpan.Days(max-11) # end fertile ovul = end-wx.DateSpan.Days(((max-11)-(min-18))//2) # day of ovul if year_b <= ovul <= year_e: add_mark(ovul, MARK_OVUL, year) start = d+wx.DateSpan.Day() if i < len(cycle.begin)-1: last_cycle = (cycle.begin[i+1]-cycle.begin[i] + wx.TimeSpan.Hours(1)).GetDays() if last_cycle > 35: stop = d+wx.DateSpan.Days(35) else: stop = cycle.begin[i+1]-wx.DateSpan.Day() else: stop = d+wx.DateSpan.Days(cycle.period-1) if (stop < year_b or start > year_e) and (d not in cycle.last): continue f = start while f.IsBetween(start, stop): if f.IsBetween(begin, end): add_mark(f, MARK_FERT, year) else: add_mark(f, MARK_SAFESEX, year) f = f+wx.DateSpan.Day() if d in cycle.last: # calc birthday birth = d+wx.DateSpan.Days(280+cycle.period-28) if i < len(cycle.begin)-1: # not last item if birth < cycle.begin[i+1]: add_mark(birth, MARK_BIRTH, year) else: # last item add_mark(birth, MARK_BIRTH, year) return # prognosis to future cycles cycle.prog_begin = [] d = d+wx.DateSpan.Days(cycle.period) while d.GetYear() <= year: if cycle.tablet != [] and cycle.tablet[-1] <= d and \ cycle.begin[-1] <= cycle.tablet[-1]: return if d.GetYear() == year: # cycle.prog_begin.append(d) add_mark(d, MARK_PROG, year) begin = d+wx.DateSpan.Days(min-18) # end = d+wx.DateSpan.Days(max-11) # ovul = end-wx.DateSpan.Days(((max-11)-(min-18))//2) # day of ovul if year_b <= ovul <= year_e: add_mark(ovul, MARK_OVUL, year) start = d+wx.DateSpan.Day() stop = d+wx.DateSpan.Days(cycle.period-1) d = d+wx.DateSpan.Days(cycle.period) if stop < year_b or start > year_e: continue f = start while f.IsBetween(start, stop): if f.IsBetween(begin, end): add_mark(f, MARK_FERT, year) else: add_mark(f, MARK_SAFESEX, year) f = f+wx.DateSpan.Day() def calc_tablet(year): """calculation result of using hormonal tablets""" if cycle.tablet == []: return year_b = wx.DateTime.FromDMY(1, 0, year) year_e = wx.DateTime.FromDMY(31, 11, year) for d in cycle.tablet: i = cycle.tablet.index(d) if i < len(cycle.tablet)-1: if (cycle.tablet[i+1]-cycle.tablet[i]+wx.TimeSpan.Hours(1)).GetDays() < 28: # incorrect using - must more 28 days continue for k in range(28): remove_mark(d+wx.DateSpan.Days(k), MARK_PROG | MARK_FERT | MARK_NEXT_TABLET | MARK_OVUL | MARK_SAFESEX | MARK_BIRTH, year) for k in range(21, 28): add_mark(d+wx.DateSpan.Days(k), MARK_T22_28, year) add_mark(d+wx.DateSpan.Days(28), MARK_NEXT_TABLET, year) def add_mark(date, mark, year): if date.GetYear() == year: k = date.GetDayOfYear() cycle.mark[k] = cycle.mark.get(k, 0) | mark def remove_mark(date, mark, year): if date.GetYear() == year: k = date.GetDayOfYear() cycle.mark[k] = cycle.mark.get(k, 0) & ~mark def is_set_mark(date, mark, year): if date.GetYear() == year: k = date.GetDayOfYear() return cycle.mark.get(k, 0) & mark else: return False def reset_mark(year): cycle.mark.clear() for k in cycle.begin: if k.GetYear() == year: add_mark(k, MARK_BEGIN, year) for k in cycle.last: if k.GetYear() == year: add_mark(k, MARK_LAST, year) for k in cycle.tablet: if k.GetYear() == year: add_mark(k, MARK_TABLET, year) for k in list(cycle.note.keys()): if str(year) == k[0:4]: d = wx.DateTime.FromDMY(int(k[6:8]), int(k[4:6])-1, int(k[0:4])) add_mark(d, MARK_NOTE, year) def info(day): """ .""" s = day.Format('%d %B') if cycle.tablet != []: for d in cycle.tablet: if day.IsBetween(d, d+wx.DateSpan.Days(28)): t = (day-d+wx.TimeSpan.Hours(1)).GetDays()+1 s += " - " if t <= 28: s += _('tablet N ')+str(t) if 22 <= t <= 28: s += _(' or pause') if t == 29: s += _('next 1-st tablet') return s if cycle.begin == []: return s if day < cycle.begin[0]: return s # find = 0 gestation = 0 for d in cycle.begin: if day < d: find = 1 break if find == 0: if d in cycle.last: gestation = 1 d2 = d else: # while d <= day: if cycle.tablet != [] and cycle.tablet[-1] <= d and \ cycle.begin[-1] <= cycle.tablet[-1]: return s d = d+wx.DateSpan.Days(cycle.period) find = 2 # if find == 1: i = cycle.begin.index(d) d2 = cycle.begin[i-1] if d2 in cycle.last: gestation = 1 elif find == 2: d2 = d-wx.DateSpan.Days(cycle.period) if gestation: k = (day-d2+wx.TimeSpan.Hours(1)).GetDays()+1 w = (k-1)/7 s += " - "+str(k)+_('% day of gestation, ')+str(w) if w == 1: s += _('1 week') else: s += _('% weeks') s += ' + '+str(k-w*7) if (k-w*7) == 1: s += _('1 day') else: s += _('% days') else: p = (d-d2+wx.TimeSpan.Hours(1)).GetDays() k = (day-d2+wx.TimeSpan.Hours(1)).GetDays()+1 d = d-wx.DateSpan.Day() s += " - "+_('%s day of period from %s to %s') % (str(k), d2.Format('%d %b'), d.Format('%d %b')) + ' ' + _('length %s days') % (str(p)) return s # -------------------- Note -------------------- def add_note(date, txt): d = date.Format('%Y%m%d') cycle.note[d] = txt def get_note(date): d = date.Format('%Y%m%d') return cycle.note.get(d, "") def remove_note(date): d = date.Format('%Y%m%d') if d in cycle.note: del cycle.note[d] # -------------------- Report -------------------- def report_year(year): if cycle.first_week_day == 0: calendar.setfirstweekday(calendar.MONDAY) days = list(range(1, 7)) + [0] else: calendar.setfirstweekday(calendar.SUNDAY) days = list(range(7)) #sp=' ' s = '

%s

' % year
    dn = ''
    for i in days:
        dn += '%.2s ' % wx.DateTime_GetWeekDayName(i, wx.DateTime.Name_Abbr)
    dn = dn[:-1]
    dn = '%s  %s  %s
\n' % (dn, dn, dn) # week days names for m in range(0, 12, 3): s += '
\n%s %s %s
\n' % ( wx.DateTime_GetMonthName(m).center(20), wx.DateTime_GetMonthName(m+1).center(20), wx.DateTime_GetMonthName(m+2).center(20)) s += dn data = [] h = 0 for k in range(m+1, m+4): cal = calendar.monthcalendar(year, k) data.append(calendar.monthcalendar(year, k)) if h < len(cal): h = len(cal) for i in range(h): d_str = '' for n in range(3): for k in range(7): if i < len(data[n]): day_of_month = data[n][i][k] if day_of_month: d = wx.DateTime.FromDMY(day_of_month, m+n, year) if is_set_mark(d, MARK_BEGIN, d.GetYear()): d_str += '%2s ' % day_of_month else: d_str += '%2s ' % day_of_month else: d_str += ' ' else: d_str += ' ' d_str += ' ' s += d_str[:-2] + '
\n' s += '
' print(s) return s def report_year_ical(year, fileobj): import socket hostname = socket.gethostname() def get_string(mark): if mark & MARK_LAST: return _("Conception") elif mark & MARK_BEGIN: return _("Beginning of cycle") elif mark & MARK_PROG: return _("Probable beginning of cycle") elif mark & MARK_TABLET: return _("1-st tablet") elif mark & MARK_OVUL: return _("Ovulation") elif mark & MARK_BIRTH: return _("Birth") else: return "" def make_event(description, mark, date): date2 = date + wx.TimeSpan.Days(1) datestr = "%04d%02d%02d" % ( date.GetYear(), date.GetMonth() + 1, date.GetDay()) datestr2 = "%04d%02d%02d" % ( date2.GetYear(), date2.GetMonth() + 1, date2.GetDay()) uid = "UID:cycle-%d-%sZ@%s" % (mark, datestr, hostname) return ["BEGIN:VEVENT", uid, "DTSTART;VALUE=DATE:" + datestr, "DTEND;VALUE=DATE:" + datestr2, "SUMMARY:" + description, "DESCRIPTION:" + description, "CLASS:PUBLIC", "END:VEVENT"] s = ["BEGIN:VCALENDAR", "CALSCALE:GREGORIAN", "PRODID:-//Cycle//NONSGML Cycle//EN", "VERSION:2.0"] days = list(cycle.mark.items()) days.sort() for day, marks in days: if get_string(marks): d = wx.DateTime() d.SetYear(year) d.SetToYearDay(day) s.extend(make_event(get_string(marks), marks, d)) s.append("END:VCALENDAR") print("\n".join(s), file=fileobj) # -------------------- Add import -------------------- cycle-0.3.3/cycle.1000066400000000000000000000102271443566760700140210ustar00rootroot00000000000000.\" .ig .\" cycle manual page. .\" .\" Miriam Ruiz , 2005. .\" .\" This next line loads the www macro package so that the .URL macro can be used. .\" .. .\" .mso www.tmac .TH "cycle" "1" "6 April 2005" "Miriam Ruiz" "Utils" .SH "NAME" . cycle \- a calendar for women . .SH "SYNOPSIS" . .B cycle . .SH "DESCRIPTION" . Cycle is a calendar program for women. Given a cycle length or statistics for several periods, it can calculate the days until menstruation, the days of "safe" sex, the fertile period, and the days to ovulations, and define the d.o.b. (date of birth) of a child. It allows the user to write notes and helps to supervise the reception of hormonal contraceptive tablets. . .SH "FEATURES" The program is capable of: .P \- Calculate of the days of menstruation, based on length of the cycle or on statistics of a period. \- Calculate the "safe" sex days, fertile period and day to ovulations \- Definition of D.O.B . (Date Of Birth) of a child \- Allows to write notes \- Helps to supervise reception of hormonal contraceptive tablets .P .SH "HOW DOES IT WORK" It uses the calendar method for the definition of fertile days. For this is necessary to determine duration, at least, of last six cycles. For determine the fertile days it uses this algoritm: .P \- First day: duration of shortest cycle minus 18 \- Last day: duration of longest cycle minus 11 \- Ovulation: is considered in the middle of fertile period (Determine the exact day isn't possible with the calendar method) .P Date of a birth of the child is counted from the beginning of last menstruation (in obstetrics are accepted 40 weeks). This date is corrected with the duration of a cycle (are subtracted or added same number of days that a cycle differs from 28 days). Is possible check the results at: http://cir.msk.ru/sroki.shtml (in Russian) .SH "USAGE" . It is necessary to mark the beginning of menstruation. This is possible clicking with the right button on the date and chosing "The beginning of a cycle". Similarly the mark can be removed. Using duration of last six cycles, the program will calculate .P \- Fertile period \- green cells \- Ovulation day (the middle fertile period) \- brightly green cell \- Beginning of following menstruation \- pink cells .P Cycle duration is set in options or is calculated an average of last six periods. To determine prospective date of a birth of the child, it is necessary first day of last cycle to mark in addition as "Pregnancy". Depending on your purposes, you can display only "Safe" sex days or only fertile days. Information about interesting day can be received clicking with left button. Is possible adding a note to any date using corresponding item of the menu. Day with a note are underlined. It is necessary to note that factor of failures of calendar contraception method is about 10 percent. This method is suitable only for women with enough regular cycle. If your doctor has recommended hormonal contraceptive this program will help to supervise their reception. Closely familiarize with the instruction applied to the chosen preparation. Packing can contain 21 tablet (the circuit of reception 21 day on one tablet, then 7 days pause) or 28 tablets in this case all tablets are accepted without interruption every day of 28. In the program, is marked only day of reception of each first tablet of packing. NOTE: This program is not a reliable contraceptive method. It does neither help to prevent sexual transmision diseases like AIDS. It is just an electronic means of keeping track of some of your medical data and extract some statistical conclusions from them. You cannot consider this program as a substitute for your gynecologist in any way. . .SH "FILES" . .TP .I ~/.cycle This is the directory where cycle stores the data. . .SH "AUTHOR" . cycle was written by Oleg S. Gints. .P This manual page was written for Debian by Miriam Ruiz . . .SH "SEE ALSO" . You can find cycle's home page at: .URL http://cycle.sourceforge.net/ http://cycle.sourceforge.net/ .P More information about calendar method are available at: .URL http://www.mama.ru/gynecolog/STA/st18.htm http://www.mama.ru/gynecolog/STA/st18.htm (in Russian) . cycle-0.3.3/cycle.py000077500000000000000000000157001443566760700143150ustar00rootroot00000000000000#!/usr/bin/env python3 # 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 builtins import gettext from set_dir import * from dialogs import * from save_load import * from cal_year import * import wx.lib.colourdb import wx.html import wx import os import sys import gettext import locale #from prn import * lang_find = False if not '__WXMSW__' in wx.PlatformInfo: for lang_env_var in ('LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG'): if lang_find: break if lang_env_var in os.environ: env_language = os.environ[lang_env_var] for s_lang in env_language.split(':'): # if set more languages os.environ[lang_env_var] = s_lang try: dl = locale.getdefaultlocale() lang = [dl[0][0:2]] l = gettext.translation('cycle', msg_dir, lang) if wx.USE_UNICODE: builtins.__dict__['_'] = lambda s: l.ugettext(s) else: builtins.__dict__['_'] = lambda s: l.ugettext( s).encode(dl[1]) _('try decode this string') lang_find = True break # language was found except: pass else: # for MS Windows try: dl = locale.getdefaultlocale() lang = [dl[0][0:2]] l = gettext.translation('cycle', msg_dir, lang) if wx.USE_UNICODE: builtins.__dict__['_'] = lambda s: l.ugettext(s) else: builtins.__dict__['_'] = lambda s: l.ugettext(s).encode(dl[1]) _('try decode this string') lang_find = True except: pass if not lang_find: builtins.__dict__['_'] = lambda s: s lang = [""] class MyFrame(wx.Frame): def __init__(self, parent, ID, title): wx.Frame.__init__(self, parent, ID, title, wx.DefaultPosition, wx.Size(800, 600)) # self.printer = wx.HtmlEasyPrinting() icon = wx.Icon(os.path.join( icons_dir, 'mini/cycle.xpm'), wx.BITMAP_TYPE_XPM) self.SetIcon(icon) Val.frame = self self.CreateStatusBar() self.MakeToolMenu() # toolbar self.cal = Cal_Year(self) self.OnCurrent(self) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) def OnCloseWindow(self, event): Save_Cycle(cycle.name, cycle.passwd, cycle.file) self.Destroy() def TimeToQuit(self, event): self.Close(True) def MakeToolMenu(self): tb = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER) tb.SetToolBitmapSize(wx.Size(24, 24)) qDec=SetToolPath(self, tb, 10, os.path.join( bitmaps_dir, 'dec.png'), _('Dec Year')) self.Bind(wx.EVT_TOOL, self.OnDecYear, qDec) qCurr=SetToolPath(self, tb, 20, os.path.join( bitmaps_dir, 'curr.png'), _('Current Year')) self.Bind(wx.EVT_TOOL, self.OnCurrent, qCurr) qInc=SetToolPath(self, tb, 30, os.path.join( bitmaps_dir, 'inc.png'), _('Inc Year')) self.Bind(wx.EVT_TOOL, self.OnIncYear, qInc) tb.SetToolSeparation(50) tb.AddSeparator() qLeg=SetToolPath(self, tb, 40, os.path.join( bitmaps_dir, 'legend.png'), _('Legend')) self.Bind(wx.EVT_TOOL, self.Legend, qLeg) qExp=SetToolPath(self, tb, 45, os.path.join( bitmaps_dir, 'export.png'), _('Export to iCal')) self.Bind(wx.EVT_TOOL, self.Export, qExp) qSett=SetToolPath(self, tb, 50, os.path.join( bitmaps_dir, 'set.png'), _('Settings')) self.Bind(wx.EVT_TOOL, self.Settings, qSett) qHelp=SetToolPath(self, tb, 55, os.path.join( bitmaps_dir, 'help.png'), _('Help')) self.Bind(wx.EVT_TOOL, self.Info, qHelp) # SetToolPath(self, tb, 57, os.path.join(bitmaps_dir,'help.png'), _('Print')) # wx.EVT_TOOL(self, 57, self.test) tb.AddSeparator() qExit=SetToolPath(self, tb, 60, os.path.join( bitmaps_dir, 'exit.png'), _('Exit')) self.Bind(wx.EVT_TOOL, self.TimeToQuit, qExit) tb.Realize() def test(self, event): #rpt = report_year(self.cal.year) # self.printer.PreviewText(rpt) # self.printer.PreviewFile('2.html') dlg = Colour_Dlg(self) dlg.ShowModal() dlg.Destroy() def Legend(self, event): dlg = Legend_Dlg(self) dlg.ShowModal() dlg.Destroy() def Export(self, event): dlg = wx.FileDialog(self, _("Export to iCal"), style=wx.FD_SAVE) if dlg.ShowModal() == wx.ID_OK: try: fileobj = file(dlg.GetPath(), "w") report_year_ical(self.cal.year, fileobj) except (IOError, OSError) as err: wx.MessageDialog( self, str(err), _("Unable to export"), style=wx.OK).ShowModal() def Settings(self, event): dlg = Settings_Dlg(self) if dlg.ShowModal() == wx.ID_OK: self.cal.Set_Year(wx.DateTime.Today().GetYear()) dlg.Destroy() def Info(self, event): global lang f_name = os.path.join(doc_dir, "README_"+lang[0]+".html") if not os.path.isfile(f_name): f_name = os.path.join(doc_dir, "README.html") f = open(f_name, "r") msg = f.read() dlg = Help_Dlg(self, _('Help'), msg) dlg.ShowModal() # increment and decrement toolbar controls def OnIncYear(self, event): self.cal.Inc_Year() def OnDecYear(self, event): self.cal.Dec_Year() def OnCurrent(self, event): self.cal.Set_Year(wx.DateTime.Today().GetYear()) # ---------------------------------------------- def SetToolPath(self, tb, id, bmp, title): global dir_path # tb.AddSimpleTool(id, wx.Bitmap(os.path.join(dir_path, bmp), wx.BITMAP_TYPE_PNG), # title, title) return tb.AddTool(id, "", wx.Bitmap(os.path.join(dir_path, bmp), wx.BITMAP_TYPE_PNG), wx.NullBitmap, wx.ITEM_NORMAL, title, title) class MyApp(wx.App): def OnInit(self): wx.lib.colourdb.updateColourDB() ret = first_login() if ret == 'bad_login': return True elif ret == 'not_first': dlg = Login_Dlg(None) if dlg.ShowModal() == wx.ID_CANCEL: dlg.Destroy() return True dlg.Destroy() self.frame_init() return True def frame_init(self): frame = MyFrame(None, -1, "") frame.Show(True) self.SetTopWindow(frame) if __name__ == '__main__': locale.setlocale(locale.LC_ALL, "") dir_path = os.getcwd() app = MyApp(0) app.MainLoop() cycle-0.3.3/dialogs.py000066400000000000000000000515221443566760700146370ustar00rootroot00000000000000# 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 # =================================================== from cal_year import cycle, Val from set_dir import * from save_load import Load_Cycle, get_f_name, set_color_default import pickle import wx.html import wx import os import random, string import warnings # deprecated since release 2.3 warnings.filterwarnings("ignore", category=RuntimeWarning, message='.*tempnam is a potential security risk to your program', module=__name__) # --------------------------------------------------------------------------- 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 = b"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(b"===") # find end string if n != -1: users.append((pickle.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.InsertItem(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.list.GetItemText(event.GetIndex()) self.name = self.users[event.GetIndex()][0] 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 randomword(length): letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" return ''.join(random.choice(letters) for i in range(length)) def get_new_file_name(): while True: f = "cycle"+randomword(6) 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.\n" "Neither does it help to prevent sexually transmitted diseases\n" "like HIV/AIDS.\n\nIt is just an electronic means of keeping track\n" "of some of your medical data and extracting some statistical\n" "conclusions from them. You cannot consider this program as a\n" "substitute for your gynecologist in any way.")) dlg = wx.TextEntryDialog(parent, _('Enter your 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, _('ovulation, birth'), cycle.colour_set['ovule']) self._add(box, _('1-st tablet'), cycle.colour_set['1-st tablet']) self._add(box, _('tablets no. 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 = list(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, _('ovulation, birth'), 'ovule') self._add(box, _('1-st tablet'), '1-st tablet') self._add(box, _('tablets no. 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) # --------------------------------------------------------------------------- cycle-0.3.3/icons/000077500000000000000000000000001443566760700137515ustar00rootroot00000000000000cycle-0.3.3/icons/cycle.xcf000066400000000000000000000077021443566760700155600ustar00rootroot00000000000000gimp xcf file BB/ gimp-commentCreated with The GIMPH I metka     D X hPqUƪU9qU99qqq99Uq9qqUP cetka       E                        JE                        JE                        JE UUUUUUUUUU UUU UUU UUU UUU UUU UƪU UUU UUU UUU UUU UUU UUU UƪU UUU UUU UUU UUU UUU UƪU UUU UUU U UUUUUUUUU9 9I list       %                           +%                           +%                           +UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUqU U U U U        cycle-0.3.3/icons/cycle.xpm000066400000000000000000000032621443566760700156010ustar00rootroot00000000000000/* XPM */ static char * cycle_xpm[] = { "32 32 34 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #F8F8F8", "# c #C0C0C0", "$ c #EAEAEA", "% c #CECECE", "& c #DBDBDB", "* c #D5D5D5", "= c #F02A2A", "- c #ECD0D0", "; c #FF8E8E", "> c #FF0000", ", c #F19C9C", "' c #FFE3E3", ") c #FF3939", "! c #EA4040", "~ c #C6C6C6", "{ c #E38E8E", "] c #CE9595", "^ c #FFAAAA", "/ c #FF5555", "( c #FF1C1C", "_ c #FFC6C6", ": c #DEA5A5", "< c #EC5E5E", "[ c #E77676", "} c #F52F2F", "| c #FF7171", "1 c #FA1717", "2 c #F14747", "3 c #151515", "4 c #808080", "5 c #2A2A2A", " ...................... ", " .++++++++++++++++++++. ", " .@##################@. ", " .$#$$$%$$$$%$$$#&$$#$. ", " .$#+++*++++*+++#$++#$. ", " .$#+++*++++*+++#$++#$. ", " .$#+++*++++*+++=-++#$. ", " .$#+++*++++*++;>,++#$. ", " .$#+++*++++*+')!$++#$. ", " .$#***~****~*{>]%**#$. ", " .$#+++*++++*+>)#$++#$. ", " .$#+++*++++*;>^#$++#$. ", " .$#+++*++++*/(_#$++#$. ", " .$#+++*++++:(/+#$++#$. ", " .$#+++*++++<>;+#$++#$. ", " .$#+;;*++++>>++#$++#$. ", " .$#*[>>:**:>}**#%**#$. ", " .$#++|>(/+/>^++#$++#$. ", " .$#+++[>>>>1_++#$++#$. ", " .$#+++*|>>>2+++#$++#$. ", " .$#+++*+;>>[+++#$++#$. ", " .$#+++*++^^*+++#$++#$. ", " .$#***~****~***#%**#$. ", " .$#+++*++++*+++#$++#$. ", " .$#+++*++++*+++#$++#$. ", " .$#+++*++++*+++33..33. ", " .$#+++*++++*+++.4###. ", " .$#+++*++++*+++.4##.. ", " .$#$$$%$$$$%$$$54#.. ", " .@#############54.. ", " .++++++++++++++... ", " ................. "}; cycle-0.3.3/icons/large/000077500000000000000000000000001443566760700150435ustar00rootroot00000000000000cycle-0.3.3/icons/large/cycle.xcf000066400000000000000000000127241443566760700166520ustar00rootroot00000000000000gimp xcf file00BB/ gimp-commentCreated with The GIMP^00metka     L00`00p-,,,,,,,,,,,+""#%&')*+  -,,,,,,,,,,,+""#%&')*+00cetka     0000$   00list       00400D7 &7 &7 &! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 00     0000    cycle-0.3.3/icons/large/cycle.xpm000066400000000000000000000050761443566760700167000ustar00rootroot00000000000000/* XPM */ static char * cycle_xpm[] = { "48 48 5 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #C0C0C0", "# c #FF0000", " .................................. ", " .++++++++++++++++++++++++++++++++. ", " .++++++++++++++++++++++++++++++++. ", " .++++++++++++++++++++++++++++++++. ", " .++@@@@@@@@@@@@@@@@@@@@@@@@@@@@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@+++++#@+++++@++. ", " .++@++++++@++++++@+++++##+++++@++. ", " .++@++++++@++++++@++++###+++++@++. ", " .++@++++++@++++++@++++##@+++++@++. ", " .++@++++++@++++++@+++###@+++++@++. ", " .++@@@@@@@@@@@@@@@@@@##@@@@@@@@++. ", " .++@++++++@++++++@++###+@+++++@++. ", " .++@++++++@++++++@++##++@+++++@++. ", " .++@++++++@++++++@+###++@+++++@++. ", " .++@++++++@++++++@+###++@+++++@++. ", " .++@++++++@++++++@+##+++@+++++@++. ", " .++@++++++@++++++@###+++@+++++@++. ", " .++@++++++@++++++@###+++@+++++@++. ", " .++@++++++@++++++###++++@+++++@++. ", " .++@+++##+@++++++###++++@+++++@++. ", " .++@@@@####@@@@@@###@@@@@@@@@@@++. ", " .++@++++####++++###+++++@+++++@++. ", " .++@+++++#####++###+++++@+++++@++. ", " .++@++++++#########+++++@+++++@++. ", " .++@++++++@#######++++++@+++++@++. ", " .++@++++++@+######++++++@+++++@++. ", " .++@++++++@++#####++++++@+++++@++. ", " .++@++++++@+++###@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@@@@@@@@@@@@@@@@@@@@@@@@@@@@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++@+++++@++. ", " .++@++++++@++++++@++++++.......... ", " .++@++++++@++++++@++++++.@@@@@@@. ", " .++@++++++@++++++@++++++.@@@@@@. ", " .++@++++++@++++++@++++++.@@@@@. ", " .++@++++++@++++++@++++++.@@@@. ", " .++@@@@@@@@@@@@@@@@@@@@@.@@@. ", " .+++++++++++++++++++++++.@@. ", " .+++++++++++++++++++++++.@. ", " .+++++++++++++++++++++++.. ", " ......................... "}; cycle-0.3.3/icons/mini/000077500000000000000000000000001443566760700147055ustar00rootroot00000000000000cycle-0.3.3/icons/mini/cycle.xcf000066400000000000000000000036661443566760700165210ustar00rootroot00000000000000gimp xcf fileBB#/ gimp-commentCreated with The GIMPmetka     L`p)        V)  9   r r Ucetka                 ƪƪ㪜UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUccUUƪƪlist                                                      @@     cycle-0.3.3/icons/mini/cycle.xpm000066400000000000000000000012401443566760700165270ustar00rootroot00000000000000/* XPM */ static char * cycle_xpm[] = { "16 16 20 1", " c None", ". c #000000", "+ c #D8D8D8", "@ c #D5D5D5", "# c #CECECE", "$ c #C6C6C6", "% c #FFFFFF", "& c #EAEAEA", "* c #FF0000", "= c #FFE3E3", "- c #DBDBDB", "; c #D89F9F", "> c #ECD0D0", ", c #FF3939", "' c #FC1919", ") c #F38181", "! c #F63030", "~ c #4A4A4A", "{ c #C0C0C0", "] c #151515", " ............ ", " .+@#@@#@$@+. ", " .@%&%%&%*%@. ", " .@%&%%&=*%@. ", " .@&-&&-*;&@. ", " .@%&%%>,@%@. ", " .@%&%%**@%@. ", " .@*>%%'=@%@. ", " .@>*)*!&#&@. ", " .@%>**)%@%@. ", " .@%&=*>%@%@. ", " .@&-&&-&#&@. ", " .@%&%%&%~.~. ", " .@%&%%&%.{. ", " .+@#@@#@]. ", " ......... "}; cycle-0.3.3/msg/000077500000000000000000000000001443566760700134245ustar00rootroot00000000000000cycle-0.3.3/msg/ca.po000066400000000000000000000116071443566760700143540ustar00rootroot00000000000000# translation of messages.po to catalan # Copyright (C) 2005 Beln Albeza # Beln Albeza , 2005. # msgid "" msgstr "" "Project-Id-Version: ca\n" "POT-Creation-Date: Thu Oct 24 09:07:06 2002\n" "PO-Revision-Date: 2005-04-11 14:00+1\n" "Last-Translator: Belén Albeza \n" "Language-Team:\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 7-bit\n" "Generated-By: pygettext.py 1.4\n" #: ../cal_year.py:70 msgid "Begin of cycle" msgstr "Començament de cicle" #: ../cal_year.py:72 ../dialogs.py:313 msgid "1-st tablet" msgstr "1a píndola" #: ../cal_year.py:75 msgid "Conception" msgstr "Concepció" #: ../cal_year.py:77 msgid "Note" msgstr "Nota" #: ../cal_year.py:505 msgid "tablet N " msgstr "píndola N" #: ../cal_year.py:507 msgid " or pause" msgstr " o pausa" #: ../cal_year.py:509 ../dialogs.py:315 msgid "next 1-st tablet" msgstr "següent 1a píndola" #: ../cal_year.py:547 msgid " day of gestation, " msgstr " dia de gestació, " #: ../cal_year.py:548 msgid " week" msgstr " setmana" #: ../cal_year.py:549 msgid " weeks" msgstr " setmanes" #: ../cal_year.py:551 msgid " day" msgstr " dia" #: ../cal_year.py:552 ../cal_year.py:559 msgid " days" msgstr " dies" #: ../cal_year.py:558 msgid " day of period from " msgstr " dia del periode des de " #: ../cal_year.py:558 msgid " to " msgstr " fins " #: ../cal_year.py:559 msgid " length " msgstr " longitud " #: ../cycle.py:64 msgid "Dec Year" msgstr "Any precedent" #: ../cycle.py:67 msgid "Current Year" msgstr "Enguany" #: ../cycle.py:70 msgid "Inc Year" msgstr "Any següent" #: ../cycle.py:76 ../dialogs.py:301 msgid "Legend" msgstr "Llegenda" #: ../cycle.py:79 ../dialogs.py:16 msgid "Settings" msgstr "Configura" #: ../cycle.py:82 ../cycle.py:118 msgid "Help" msgstr "Ajuda" #: ../cycle.py:90 msgid "Exit" msgstr "Surt" #: ../dialogs.py:21 msgid "Length of cycle" msgstr "Longitud del cicle" #: ../dialogs.py:23 msgid " by average" msgstr " de mitjana" #: ../dialogs.py:35 msgid " days in cycle" msgstr " dies al cicle" #: ../dialogs.py:39 msgid "Display" msgstr "Visualitza" #: ../dialogs.py:40 msgid "both" msgstr "ambdós" #: ../dialogs.py:40 msgid "fertile days" msgstr "dies fèrtils" #: ../dialogs.py:40 msgid "safe sex days" msgstr "dies de sexe més segur" #: ../dialogs.py:46 msgid "First week day" msgstr "Primer dia de la setmana" #: ../dialogs.py:47 msgid "monday" msgstr "dilluns" #: ../dialogs.py:47 msgid "sunday" msgstr "diumenge" #: ../dialogs.py:54 msgid "Change password" msgstr "Canvia la contrasenya" #: ../dialogs.py:62 ../dialogs.py:125 ../dialogs.py:205 ../dialogs.py:318 #: ../dialogs.py:352 ../dialogs.py:403 msgid "Ok" msgstr "D' acord" #: ../dialogs.py:66 ../dialogs.py:129 ../dialogs.py:209 ../dialogs.py:356 msgid "Cancel" msgstr "Cancel·lar" #: ../dialogs.py:83 msgid "Period of cycle is invalid!" msgstr "El periode del cicle no és vàlid!" #: ../dialogs.py:84 ../dialogs.py:147 ../dialogs.py:245 ../dialogs.py:290 msgid "Error!" msgstr "Error!" #: ../dialogs.py:105 ../dialogs.py:234 msgid "Password" msgstr "Contrasenya" #: ../dialogs.py:110 msgid "Enter your password" msgstr "Introduïu la contrasenya" #: ../dialogs.py:116 msgid "Once more..." msgstr "Una altra vegada..." #: ../dialogs.py:142 msgid "Password must be not EMPTY!" msgstr "La contrasenya no ha d' estar BUIDA!" #: ../dialogs.py:144 msgid "Entering password don't match!" msgstr "Les contrasenyes introduïes no coincideixen" #: ../dialogs.py:160 msgid "Login" msgstr "Entrada" #: ../dialogs.py:170 msgid "empty" msgstr "buit" #: ../dialogs.py:185 msgid "Your name" msgstr "El teu nom" #: ../dialogs.py:199 msgid "Add user" msgstr "Afegeix una usuària" #: ../dialogs.py:234 msgid ", enter you password:" msgstr ", introduïu la vostra contrasenya:" #: ../dialogs.py:244 msgid "Password is invalid!" msgstr "La contrasenya no és vàlida!" #: ../dialogs.py:269 msgid "Enter you name:" msgstr "Introduïu el vostre nom:" #: ../dialogs.py:269 msgid "New user" msgstr "Nova usuària" #: ../dialogs.py:287 msgid " - already exists!" msgstr " - ja existeix!" #: ../dialogs.py:289 msgid "Name must be not EMPTY" msgstr "El nom no ha d' estar BUIT" #: ../dialogs.py:306 msgid "today" msgstr "avuí" #: ../dialogs.py:307 msgid "begin of cycle" msgstr "començament del cicle" #: ../dialogs.py:308 msgid "prognosis of cycle begin" msgstr "prognosi del cicle, començament" #: ../dialogs.py:309 msgid "conception" msgstr "concepció" #: ../dialogs.py:310 msgid "safe sex" msgstr "sexe més segur" #: ../dialogs.py:311 msgid "fertile" msgstr "fèrtil" #: ../dialogs.py:312 msgid "ovule, birth" msgstr "òvul, naixement" #: ../dialogs.py:314 msgid "tablets N 22-28 or pause" msgstr "píndoles N 22-28 o pausa" #: ../dialogs.py:360 msgid "Remove" msgstr "Suprimeix" msgid "Colours" msgstr "Colors" msgid "Colours settings" msgstr "Configuració dels colors" msgid "By default" msgstr "Per defecte" cycle-0.3.3/msg/ca/000077500000000000000000000000001443566760700140075ustar00rootroot00000000000000cycle-0.3.3/msg/ca/LC_MESSAGES/000077500000000000000000000000001443566760700155745ustar00rootroot00000000000000cycle-0.3.3/msg/ca/LC_MESSAGES/cycle.mo000066400000000000000000000061301443566760700172300ustar00rootroot00000000000000A$,- @LQez    ) 4AJRbv .Jfm v      9&?f v  #  ' < R ^ j      , . 5 : S Y f o       $ #% I S ] h         $ - 8 R - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleBy defaultCancelChange passwordColoursColours settingsConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsYour namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: ca POT-Creation-Date: Thu Oct 24 09:07:06 2002 PO-Revision-Date: 2005-04-11 14:00+1 Last-Translator: Belén Albeza Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7-bit Generated-By: pygettext.py 1.4 - ja existeix! de mitjana dia dia de gestació, dia del periode des de dies dies al cicle longitud o pausa fins setmana setmanes, introduïu la vostra contrasenya:1a píndolaAfegeix una usuàriaComençament de ciclePer defecteCancel·larCanvia la contrasenyaColorsConfiguració dels colorsConcepcióEnguanyAny precedentVisualitzaIntroduïu el vostre nom:Introduïu la contrasenyaLes contrasenyes introduïes no coincideixenError!SurtPrimer dia de la setmanaAjudaAny següentLlegendaLongitud del cicleEntradaEl nom no ha d' estar BUITNova usuàriaNotaD' acordUna altra vegada...ContrasenyaLa contrasenya no és vàlida!La contrasenya no ha d' estar BUIDA!El periode del cicle no és vàlid!SuprimeixConfiguraEl teu nomcomençament del cicleambdósconcepcióbuitfèrtildies fèrtilsdillunssegüent 1a píndolaòvul, naixementprognosi del cicle, començamentsexe més segurdies de sexe més segurdiumengepíndola Npíndoles N 22-28 o pausaavuícycle-0.3.3/msg/cs.po000066400000000000000000000112041443566760700143670ustar00rootroot00000000000000# translation of messages.po to czech # Jozef Riha , 2004. # msgid "" msgstr "" "Project-Id-Version: cs_CZ\n" "POT-Creation-Date: Thu Oct 24 09:07:06 2002\n" "PO-Revision-Date: 2004-03-14 16:41+0100\n" "Last-Translator: Jozef Riha \n" "Language-Team:\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.4\n" "X-Generator: KBabel 1.0.2\n" #: ../cal_year.py:70 msgid "Begin of cycle" msgstr "Začátek cyklu" #: ../cal_year.py:72 ../dialogs.py:313 msgid "1-st tablet" msgstr "První tableta" #: ../cal_year.py:75 msgid "Conception" msgstr "Početí" #: ../cal_year.py:77 msgid "Note" msgstr "Poznámka" #: ../cal_year.py:505 msgid "tablet N " msgstr "Tableta N " #: ../cal_year.py:507 msgid " or pause" msgstr " nebo přestávka" #: ../cal_year.py:509 ../dialogs.py:315 msgid "next 1-st tablet" msgstr "další první tableta" #: ../cal_year.py:547 msgid " day of gestation, " msgstr " den těhotenství, " #: ../cal_year.py:548 msgid " week" msgstr " týden" #: ../cal_year.py:549 msgid " weeks" msgstr " týdny" #: ../cal_year.py:551 msgid " day" msgstr " den" #: ../cal_year.py:552 ../cal_year.py:559 msgid " days" msgstr " dny" #: ../cal_year.py:558 msgid " day of period from " msgstr " den periody od " #: ../cal_year.py:558 msgid " to " msgstr " do " #: ../cal_year.py:559 msgid " length " msgstr " délka " #: ../cycle.py:64 msgid "Dec Year" msgstr "Min. Rok" #: ../cycle.py:67 msgid "Current Year" msgstr "Aktuální Rok" #: ../cycle.py:70 msgid "Inc Year" msgstr "Příští rok" #: ../cycle.py:76 ../dialogs.py:301 msgid "Legend" msgstr "Legenda" #: ../cycle.py:79 ../dialogs.py:16 msgid "Settings" msgstr "Nastavení" #: ../cycle.py:82 ../cycle.py:118 msgid "Help" msgstr "Pomoc" #: ../cycle.py:90 msgid "Exit" msgstr "Konec" #: ../dialogs.py:21 msgid "Length of cycle" msgstr "Délka cyklu" #: ../dialogs.py:23 msgid " by average" msgstr " v průměru" #: ../dialogs.py:35 msgid " days in cycle" msgstr " dnů v cyklu" #: ../dialogs.py:39 msgid "Display" msgstr "Zobraz" #: ../dialogs.py:40 msgid "both" msgstr "oba" #: ../dialogs.py:40 msgid "fertile days" msgstr "plodné dny" #: ../dialogs.py:40 msgid "safe sex days" msgstr "dny bezpečného sexu" #: ../dialogs.py:46 msgid "First week day" msgstr "První den v týdnu" #: ../dialogs.py:47 msgid "monday" msgstr "pondělí" #: ../dialogs.py:47 msgid "sunday" msgstr "neděle" #: ../dialogs.py:54 msgid "Change password" msgstr "Změnit heslo" #: ../dialogs.py:62 ../dialogs.py:125 ../dialogs.py:205 ../dialogs.py:318 #: ../dialogs.py:352 ../dialogs.py:403 msgid "Ok" msgstr "Ok" #: ../dialogs.py:66 ../dialogs.py:129 ../dialogs.py:209 ../dialogs.py:356 msgid "Cancel" msgstr "Zrušit" #: ../dialogs.py:83 msgid "Period of cycle is invalid!" msgstr "Perioda cyklu je chybně zadaná!" #: ../dialogs.py:84 ../dialogs.py:147 ../dialogs.py:245 ../dialogs.py:290 msgid "Error!" msgstr "Chyba!" #: ../dialogs.py:105 ../dialogs.py:234 msgid "Password" msgstr "Heslo" #: ../dialogs.py:110 msgid "Enter your password" msgstr "Zadejte vaše heslo" #: ../dialogs.py:116 msgid "Once more..." msgstr "Ještě jednou..." #: ../dialogs.py:142 msgid "Password must be not EMPTY!" msgstr "Heslo nesmí být PRÁZDNÉ!" #: ../dialogs.py:144 msgid "Entering password don't match!" msgstr "Hesla nejsou stejné!" #: ../dialogs.py:160 msgid "Login" msgstr "Přihlášení" #: ../dialogs.py:170 msgid "empty" msgstr "prázdné" #: ../dialogs.py:185 msgid "Your name" msgstr "Vaše jméno" #: ../dialogs.py:199 msgid "Add user" msgstr "Přidat uživatele" #: ../dialogs.py:234 msgid ", enter you password:" msgstr ", zadejte vaše heslo:" #: ../dialogs.py:244 msgid "Password is invalid!" msgstr "Chybné heslo!" #: ../dialogs.py:269 msgid "Enter you name:" msgstr "Zadejte vaše jméno:" #: ../dialogs.py:269 msgid "New user" msgstr "Nový uživatel" #: ../dialogs.py:287 msgid " - already exists!" msgstr " - už existuje!" #: ../dialogs.py:289 msgid "Name must be not EMPTY" msgstr "Jméno nesmí být PRÁZDNÉ" #: ../dialogs.py:306 msgid "today" msgstr "dnes" #: ../dialogs.py:307 msgid "begin of cycle" msgstr "začátek cyklu" #: ../dialogs.py:308 msgid "prognosis of cycle begin" msgstr "prognóza začátku cyklu" #: ../dialogs.py:309 msgid "conception" msgstr "početí" #: ../dialogs.py:310 msgid "safe sex" msgstr "bezpečný sex" #: ../dialogs.py:311 msgid "fertile" msgstr "plodnost" #: ../dialogs.py:312 msgid "ovule, birth" msgstr "vajíčko, narození" #: ../dialogs.py:314 msgid "tablets N 22-28 or pause" msgstr "tablety N 22-28 nebo přestávka" #: ../dialogs.py:360 msgid "Remove" msgstr "Odstranit" cycle-0.3.3/msg/cs/000077500000000000000000000000001443566760700140315ustar00rootroot00000000000000cycle-0.3.3/msg/cs/LC_MESSAGES/000077500000000000000000000000001443566760700156165ustar00rootroot00000000000000cycle-0.3.3/msg/cs/LC_MESSAGES/cycle.mo000066400000000000000000000056021443566760700172550ustar00rootroot00000000000000>  !5JP_ hrw}   "AHM\ajq  ",; @KQ Yfm ~  =) :GLar w    , 5 < R f |            " ( 7 !T v        $ 3 I Q \ } - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleCancelChange passwordConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsYour namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: cs_CZ POT-Creation-Date: Thu Oct 24 09:07:06 2002 PO-Revision-Date: 2004-03-14 16:41+0100 Last-Translator: Jozef Riha Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated-By: pygettext.py 1.4 X-Generator: KBabel 1.0.2 - už existuje! v průměru den den těhotenství, den periody od dny dnů v cyklu délka nebo přestávka do týden týdny, zadejte vaše heslo:První tabletaPřidat uživateleZačátek cykluZrušitZměnit hesloPočetíAktuální RokMin. RokZobrazZadejte vaše jméno:Zadejte vaše hesloHesla nejsou stejné!Chyba!KonecPrvní den v týdnuPomocPříští rokLegendaDélka cykluPřihlášeníJméno nesmí být PRÁZDNÉNový uživatelPoznámkaOkJeště jednou...HesloChybné heslo!Heslo nesmí být PRÁZDNÉ!Perioda cyklu je chybně zadaná!OdstranitNastaveníVaše jménozačátek cykluobapočetíprázdnéplodnostplodné dnypondělídalší první tabletavajíčko, narozeníprognóza začátku cyklubezpečný sexdny bezpečného sexuneděleTableta N tablety N 22-28 nebo přestávkadnescycle-0.3.3/msg/de.po000066400000000000000000000111531443566760700143550ustar00rootroot00000000000000# translation of messages.po to german # Christian Weiske , 2004. # msgid "" msgstr "" "Project-Id-Version: de\n" "POT-Creation-Date: Thu Oct 24 09:07:06 2002\n" "PO-Revision-Date: 2004-10-01 22:43+0200\n" "Last-Translator: Christian Weiske \n" "Language-Team:\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" "Generated-By: pygettext.py 1.4\n" #: ../cal_year.py:70 msgid "Begin of cycle" msgstr "Zyklusbeginn" #: ../cal_year.py:72 ../dialogs.py:313 msgid "1-st tablet" msgstr "Erste Pille" #: ../cal_year.py:75 msgid "Conception" msgstr "Empfngnis" #: ../cal_year.py:77 msgid "Note" msgstr "Notiz" #: ../cal_year.py:505 msgid "tablet N " msgstr "Pille N " #: ../cal_year.py:507 msgid " or pause" msgstr " oder Pause" #: ../cal_year.py:509 ../dialogs.py:315 msgid "next 1-st tablet" msgstr "Nchste erste Pille" #: ../cal_year.py:547 msgid " day of gestation, " msgstr " Tag der Schwangerschaft" #: ../cal_year.py:548 msgid " week" msgstr " Woche" #: ../cal_year.py:549 msgid " weeks" msgstr " Wochen" #: ../cal_year.py:551 msgid " day" msgstr " Tag" #: ../cal_year.py:552 ../cal_year.py:559 msgid " days" msgstr " Tage" #: ../cal_year.py:558 msgid " day of period from " msgstr " Tag der Periode von " #: ../cal_year.py:558 msgid " to " msgstr " bis " #: ../cal_year.py:559 msgid " length " msgstr " Lnge " #: ../cycle.py:64 msgid "Dec Year" msgstr "Vorheriges Jahr" #: ../cycle.py:67 msgid "Current Year" msgstr "Aktuelles Jahr" #: ../cycle.py:70 msgid "Inc Year" msgstr "Nchstes Jahr" #: ../cycle.py:76 ../dialogs.py:301 msgid "Legend" msgstr "Legende" #: ../cycle.py:79 ../dialogs.py:16 msgid "Settings" msgstr "Einstellungen" #: ../cycle.py:82 ../cycle.py:118 msgid "Help" msgstr "Hilfe" #: ../cycle.py:90 msgid "Exit" msgstr "Beenden" #: ../dialogs.py:21 msgid "Length of cycle" msgstr "Zykluslnge" #: ../dialogs.py:23 msgid " by average" msgstr " durchschnittlich" #: ../dialogs.py:35 msgid " days in cycle" msgstr " Tage im Zyklus" #: ../dialogs.py:39 msgid "Display" msgstr "Anzeige" #: ../dialogs.py:40 msgid "both" msgstr "beides" #: ../dialogs.py:40 msgid "fertile days" msgstr "Fruchtbare Tage" #: ../dialogs.py:40 msgid "safe sex days" msgstr "Tage des sicheren Sex" #: ../dialogs.py:46 msgid "First week day" msgstr "Erster Wochentag" #: ../dialogs.py:47 msgid "monday" msgstr "Montag" #: ../dialogs.py:47 msgid "sunday" msgstr "Sonntag" #: ../dialogs.py:54 msgid "Change password" msgstr "Passwort ndern" #: ../dialogs.py:62 ../dialogs.py:125 ../dialogs.py:205 ../dialogs.py:318 #: ../dialogs.py:352 ../dialogs.py:403 msgid "Ok" msgstr "Ok" #: ../dialogs.py:66 ../dialogs.py:129 ../dialogs.py:209 ../dialogs.py:356 msgid "Cancel" msgstr "Abbrechen" #: ../dialogs.py:83 msgid "Period of cycle is invalid!" msgstr "Zyklusperiode ist ungltig!" #: ../dialogs.py:84 ../dialogs.py:147 ../dialogs.py:245 ../dialogs.py:290 msgid "Error!" msgstr "Fehler!" #: ../dialogs.py:105 ../dialogs.py:234 msgid "Password" msgstr "Passwort" #: ../dialogs.py:110 msgid "Enter your password" msgstr "Passwort eingeben" #: ../dialogs.py:116 msgid "Once more..." msgstr "Noch einmal..." #: ../dialogs.py:142 msgid "Password must be not EMPTY!" msgstr "Passwort darf nicht leer sein!" #: ../dialogs.py:144 msgid "Entering password don't match!" msgstr "Passwrter stimmen nicht berein!" #: ../dialogs.py:160 msgid "Login" msgstr "Login" #: ../dialogs.py:170 msgid "empty" msgstr "leer" #: ../dialogs.py:185 msgid "Your name" msgstr "Ihr name" #: ../dialogs.py:199 msgid "Add user" msgstr "Benutzer hinzufgen" #: ../dialogs.py:234 msgid ", enter you password:" msgstr ", bitte Passwort eingeben" #: ../dialogs.py:244 msgid "Password is invalid!" msgstr "Ungltiges Passwort" #: ../dialogs.py:269 msgid "Enter you name:" msgstr "Name eingeben:" #: ../dialogs.py:269 msgid "New user" msgstr "Neuer Benutzer" #: ../dialogs.py:287 msgid " - already exists!" msgstr " - existiert schon" #: ../dialogs.py:289 msgid "Name must be not EMPTY" msgstr "Name darf nicht leer sein" #: ../dialogs.py:306 msgid "today" msgstr "Heute" #: ../dialogs.py:307 msgid "begin of cycle" msgstr "Zyklusbeginn" #: ../dialogs.py:308 msgid "prognosis of cycle begin" msgstr "Vorhergesagter Zyklusbeginn" #: ../dialogs.py:309 msgid "conception" msgstr "Empfngnis" #: ../dialogs.py:310 msgid "safe sex" msgstr "Sicherer Sex" #: ../dialogs.py:311 msgid "fertile" msgstr "fruchtbar" #: ../dialogs.py:312 msgid "ovule, birth" msgstr "Geburt" #: ../dialogs.py:314 msgid "tablets N 22-28 or pause" msgstr "Pillen 22-28 oder Pause" #: ../dialogs.py:360 msgid "Remove" msgstr "Entfernen" cycle-0.3.3/msg/de/000077500000000000000000000000001443566760700140145ustar00rootroot00000000000000cycle-0.3.3/msg/de/LC_MESSAGES/000077500000000000000000000000001443566760700156015ustar00rootroot00000000000000cycle-0.3.3/msg/de/LC_MESSAGES/cycle.mo000066400000000000000000000055411443566760700172420ustar00rootroot00000000000000>  !5JP_ hrw}   "AHM\ajq  ",; @KQ Yfm ~  0/AF_u{       / ? G V !h             # 7 V r |           2 : C [ - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleCancelChange passwordConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsYour namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: de POT-Creation-Date: Thu Oct 24 09:07:06 2002 PO-Revision-Date: 2004-10-01 22:43+0200 Last-Translator: Christian Weiske Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8-bit Generated-By: pygettext.py 1.4 - existiert schon durchschnittlich Tag Tag der Schwangerschaft Tag der Periode von Tage Tage im Zyklus Lnge oder Pause bis Woche Wochen, bitte Passwort eingebenErste PilleBenutzer hinzufgenZyklusbeginnAbbrechenPasswort ndernEmpfngnisAktuelles JahrVorheriges JahrAnzeigeName eingeben:Passwort eingebenPasswrter stimmen nicht berein!Fehler!BeendenErster WochentagHilfeNchstes JahrLegendeZykluslngeLoginName darf nicht leer seinNeuer BenutzerNotizOkNoch einmal...PasswortUngltiges PasswortPasswort darf nicht leer sein!Zyklusperiode ist ungltig!EntfernenEinstellungenIhr nameZyklusbeginnbeidesEmpfngnisleerfruchtbarFruchtbare TageMontagNchste erste PilleGeburtVorhergesagter ZyklusbeginnSicherer SexTage des sicheren SexSonntagPille N Pillen 22-28 oder PauseHeutecycle-0.3.3/msg/es.po000066400000000000000000000133031443566760700143730ustar00rootroot00000000000000# translation of messages.po to spanish # Copyright (C) 2005 Miriam Ruiz # Miriam Ruiz , 2005. # msgid "" msgstr "" "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: Miriam Ruiz \n" "POT-Creation-Date: 2005-04-08 14:37+0200\n" "PO-Revision-Date: 2005-04-13 23:04+0100\n" "Last-Translator: Miriam Ruiz \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Language-Team: \n" #: cal_year.py:73 msgid "Begin of cycle" msgstr "Comienzo del ciclo" #: cal_year.py:75 #: dialogs.py:330 #: dialogs.py:451 msgid "1-st tablet" msgstr "1 pldora" #: cal_year.py:78 msgid "Conception" msgstr "Concepcin" #: cal_year.py:80 msgid "Note" msgstr "Nota" #: cal_year.py:509 msgid "tablet N " msgstr "pldora N" #: cal_year.py:511 msgid " or pause" msgstr " o pausa" #: cal_year.py:513 #: dialogs.py:332 #: dialogs.py:453 msgid "next 1-st tablet" msgstr "siguiente 1 pldora" #: cal_year.py:551 msgid " day of gestation, " msgstr " da de gestacin, " #: cal_year.py:552 msgid " week" msgstr " semana" #: cal_year.py:553 msgid " weeks" msgstr " semanas" #: cal_year.py:555 msgid " day" msgstr " da" #: cal_year.py:556 #: cal_year.py:563 msgid " days" msgstr " das" #: cal_year.py:562 msgid " day of period from " msgstr " da del periodo desde " #: cal_year.py:562 msgid " to " msgstr " hasta " #: cal_year.py:563 msgid " length " msgstr " longitud " #: cycle.py:91 msgid "Dec Year" msgstr "Ao anterior" #: cycle.py:94 msgid "Current Year" msgstr "Ao actual" #: cycle.py:97 msgid "Inc Year" msgstr "Ao siguiente" #: cycle.py:103 #: dialogs.py:318 msgid "Legend" msgstr "Leyenda" #: cycle.py:106 #: dialogs.py:17 msgid "Settings" msgstr "Configuracin" #: cycle.py:109 #: cycle.py:148 msgid "Help" msgstr "Ayuda" #: cycle.py:117 msgid "Exit" msgstr "Salir" #: dialogs.py:22 msgid "Length of cycle" msgstr "Longitud del ciclo" #: dialogs.py:24 msgid " by average" msgstr " de media" #: dialogs.py:36 msgid " days in cycle" msgstr " das en el ciclo" #: dialogs.py:40 msgid "Display" msgstr "Mostrar" #: dialogs.py:41 msgid "safe sex days" msgstr "das de sexo ms seguros" #: dialogs.py:41 msgid "fertile days" msgstr "das frtiles" #: dialogs.py:41 msgid "both" msgstr "ambos" #: dialogs.py:47 msgid "First week day" msgstr "Primer da de la semana" #: dialogs.py:48 msgid "monday" msgstr "lunes" #: dialogs.py:48 msgid "sunday" msgstr "domingo" #: dialogs.py:55 msgid "Colours" msgstr "Colores" #: dialogs.py:56 msgid "Change password" msgstr "Cambiar la contrasea" #: dialogs.py:70 #: dialogs.py:137 #: dialogs.py:217 #: dialogs.py:335 #: dialogs.py:369 #: dialogs.py:422 #: dialogs.py:457 msgid "Ok" msgstr "Aceptar" #: dialogs.py:74 #: dialogs.py:141 #: dialogs.py:221 #: dialogs.py:373 #: dialogs.py:465 msgid "Cancel" msgstr "Cancelar" #: dialogs.py:91 msgid "Period of cycle is invalid!" msgstr "El periodo del ciclo no es vlido!" #: dialogs.py:92 #: dialogs.py:159 #: dialogs.py:255 #: dialogs.py:307 msgid "Error!" msgstr "Error!" #: dialogs.py:117 #: dialogs.py:244 msgid "Password" msgstr "Contrasea" #: dialogs.py:122 msgid "Enter your password" msgstr "Introducir contrasea" #: dialogs.py:128 msgid "Once more..." msgstr "Una vez ms..." #: dialogs.py:154 msgid "Password must be not EMPTY!" msgstr "La contrasea no debe estar VACA!" #: dialogs.py:156 msgid "Entering password don't match!" msgstr "Las contraseas introducidas no coinciden!" #: dialogs.py:172 msgid "Login" msgstr "Login" #: dialogs.py:182 msgid "empty" msgstr "vaco" #: dialogs.py:197 msgid "Your name" msgstr "Tu nombre" #: dialogs.py:211 msgid "Add user" msgstr "Aadir usuaria" #: dialogs.py:244 msgid ", enter you password:" msgstr ", introduce tu contrasea:" #: dialogs.py:254 msgid "Password is invalid!" msgstr "La contrasea no es vlida!" #: dialogs.py:280 msgid "" "This program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS.\n" "\n" "It 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." msgstr "" "Este programa no es un mtodo anticonceptivo fiable. Tampoco puede ayudar a prevenir enfermedades de transmisin sexual como el SIDA.\n" "\n" "Es unicamente un asistente electrnico para llevar un seguimiento de algunos de tus datos mdicos y extraer algunas conclusiones estadsticas a partir de ellos. En ningun caso se puede considerar este programa como un sustituto de tu gineclogo." #: dialogs.py:286 msgid "Enter you name:" msgstr "Introduce tu nombre:" #: dialogs.py:286 msgid "New user" msgstr "Nueva usuaria" #: dialogs.py:304 msgid " - already exists!" msgstr " - ya existe!" #: dialogs.py:306 msgid "Name must be not EMPTY" msgstr "El nombre no debe estar VACO" #: dialogs.py:323 msgid "today" msgstr "hoy" #: dialogs.py:324 #: dialogs.py:445 msgid "begin of cycle" msgstr "comienzo del ciclo" #: dialogs.py:325 #: dialogs.py:446 msgid "prognosis of cycle begin" msgstr "prognosis del ciclo, comienzo" #: dialogs.py:326 #: dialogs.py:447 msgid "conception" msgstr "concepcin" #: dialogs.py:327 #: dialogs.py:448 msgid "safe sex" msgstr "sexo ms seguro" #: dialogs.py:328 #: dialogs.py:449 msgid "fertile" msgstr "frtil" #: dialogs.py:329 #: dialogs.py:450 msgid "ovule, birth" msgstr "vulo, nacimiento" #: dialogs.py:331 #: dialogs.py:452 msgid "tablets N 22-28 or pause" msgstr "pldoras N 22-28 o pausa" #: dialogs.py:377 msgid "Remove" msgstr "Eliminar" #: dialogs.py:435 msgid "Colours settings" msgstr "Configuracin de colores" #: dialogs.py:461 msgid "By default" msgstr "Por defecto" cycle-0.3.3/msg/es/000077500000000000000000000000001443566760700140335ustar00rootroot00000000000000cycle-0.3.3/msg/es/LC_MESSAGES/000077500000000000000000000000001443566760700156205ustar00rootroot00000000000000cycle-0.3.3/msg/es/LC_MESSAGES/cycle.mo000066400000000000000000000074461443566760700172670ustar00rootroot00000000000000B,<= P\au     ( 9 DQZbr   )>Zv}Y    $+ <Ib ky D    8 > P [ d l t }         ' 4 < Q +g           ' 6 A #^ #  | :DW ]hn u  " - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleBy defaultCancelChange passwordColoursColours settingsConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsThis program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS. It 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.Your namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: es Report-Msgid-Bugs-To: Miriam Ruiz POT-Creation-Date: 2005-04-08 14:37+0200 PO-Revision-Date: 2005-04-13 23:04+0100 Last-Translator: Miriam Ruiz MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Language-Team: - ya existe! de media da da de gestacin, da del periodo desde das das en el ciclo longitud o pausa hasta semana semanas, introduce tu contrasea:1 pldoraAadir usuariaComienzo del cicloPor defectoCancelarCambiar la contraseaColoresConfiguracin de coloresConcepcinAo actualAo anteriorMostrarIntroduce tu nombre:Introducir contraseaLas contraseas introducidas no coinciden!Error!SalirPrimer da de la semanaAyudaAo siguienteLeyendaLongitud del cicloLoginEl nombre no debe estar VACONueva usuariaNotaAceptarUna vez ms...ContraseaLa contrasea no es vlida!La contrasea no debe estar VACA!El periodo del ciclo no es vlido!EliminarConfiguracinEste programa no es un mtodo anticonceptivo fiable. Tampoco puede ayudar a prevenir enfermedades de transmisin sexual como el SIDA. Es unicamente un asistente electrnico para llevar un seguimiento de algunos de tus datos mdicos y extraer algunas conclusiones estadsticas a partir de ellos. En ningun caso se puede considerar este programa como un sustituto de tu gineclogo.Tu nombrecomienzo del cicloambosconcepcinvacofrtildas frtileslunessiguiente 1 pldoravulo, nacimientoprognosis del ciclo, comienzosexo ms segurodas de sexo ms segurosdomingopldora Npldoras N 22-28 o pausahoycycle-0.3.3/msg/gl.po000066400000000000000000000132441443566760700143720ustar00rootroot00000000000000# Galician translation of cycle # msgid "" msgstr "" "Project-Id-Version: cycle-0.3.0-1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2005-04-13 22:11+0000\n" "PO-Revision-Date: 2005-04-18 21:29+0200\n" "Last-Translator: Susana Sotelo Doco \n" "Language-Team: Galician\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" "Generated-By: pygettext.py 1.4\n" #: cal_year.py:73 msgid "Begin of cycle" msgstr "Comezo de cycle" #: cal_year.py:75 dialogs.py:331 dialogs.py:452 msgid "1-st tablet" msgstr "1 plula" #: cal_year.py:78 msgid "Conception" msgstr "Concepcin" #: cal_year.py:80 msgid "Note" msgstr "Nota" #: cal_year.py:509 msgid "tablet N " msgstr "plula N " #: cal_year.py:511 msgid " or pause" msgstr " ou pausa" #: cal_year.py:513 dialogs.py:333 dialogs.py:454 msgid "next 1-st tablet" msgstr "seguinte primeira plula" #: cal_year.py:551 msgid " day of gestation, " msgstr " da de xestacin, " #: cal_year.py:552 msgid " week" msgstr " semana" #: cal_year.py:553 msgid " weeks" msgstr " semanas" #: cal_year.py:555 msgid " day" msgstr "da" #: cal_year.py:556 cal_year.py:563 msgid " days" msgstr "das" #: cal_year.py:562 msgid " day of period from " msgstr " da do perodo dende " #: cal_year.py:562 msgid " to " msgstr " ata " #: cal_year.py:563 #, fuzzy msgid " length " msgstr " lonxitude " #: cycle.py:37 cycle.py:49 msgid "try decode this string" msgstr "intenta descodificar esta cadea" #: cycle.py:91 msgid "Dec Year" msgstr "Ano anterior" #: cycle.py:94 msgid "Current Year" msgstr "Ano actual" #: cycle.py:97 msgid "Inc Year" msgstr "Ano seguinte" #: cycle.py:103 dialogs.py:319 msgid "Legend" msgstr "Lenda" #: cycle.py:106 dialogs.py:17 msgid "Settings" msgstr "Configuracin" #: cycle.py:109 cycle.py:148 msgid "Help" msgstr "Axuda" #: cycle.py:117 msgid "Exit" msgstr "Sar" #: dialogs.py:22 msgid "Length of cycle" msgstr "Lonxitude do ciclo" #: dialogs.py:24 msgid " by average" msgstr " de media" #: dialogs.py:36 msgid " days in cycle" msgstr " das no ciclo" #: dialogs.py:40 msgid "Display" msgstr "Amosar" #: dialogs.py:41 msgid "safe sex days" msgstr "das de sexo seguro" #: dialogs.py:41 msgid "fertile days" msgstr "das frtiles" #: dialogs.py:41 msgid "both" msgstr "ambos" #: dialogs.py:47 msgid "First week day" msgstr "Primeiro da da semana" #: dialogs.py:48 msgid "monday" msgstr "luns" #: dialogs.py:48 msgid "sunday" msgstr "domingo" #: dialogs.py:55 msgid "Colours" msgstr "Cores" #: dialogs.py:56 msgid "Change password" msgstr "Cambiar o contrasinal" #: dialogs.py:70 dialogs.py:137 dialogs.py:217 dialogs.py:336 dialogs.py:370 #: dialogs.py:423 dialogs.py:458 msgid "Ok" msgstr "Aceptar" #: dialogs.py:74 dialogs.py:141 dialogs.py:221 dialogs.py:374 dialogs.py:466 msgid "Cancel" msgstr "Cancelar" #: dialogs.py:91 msgid "Period of cycle is invalid!" msgstr "O perodo do ciclo non vlido!" #: dialogs.py:92 dialogs.py:159 dialogs.py:255 dialogs.py:308 msgid "Error!" msgstr "Erro!" #: dialogs.py:117 dialogs.py:244 msgid "Password" msgstr "Contrasinal" #: dialogs.py:122 msgid "Enter your password" msgstr "Introduce o contrasinal" #: dialogs.py:128 msgid "Once more..." msgstr "Unha vez mis..." #: dialogs.py:154 msgid "Password must be not EMPTY!" msgstr "O contrasinal non pode estar BALEIRO!" #: dialogs.py:156 msgid "Entering password don't match!" msgstr "Os contrasinais introducidos non coinciden!" #: dialogs.py:172 msgid "Login" msgstr "Nome de usuaria" #: dialogs.py:182 msgid "empty" msgstr "baleiro" #: dialogs.py:197 msgid "Your name" msgstr "Nome" #: dialogs.py:211 msgid "Add user" msgstr "Engadir usuaria" #: dialogs.py:244 msgid ", enter you password:" msgstr ", introduce o teu contrasinal:" #: dialogs.py:254 msgid "Password is invalid!" msgstr "O contrasinal non vlido!" #: dialogs.py:280 msgid "" "This program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS.\n" "\n" "It 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." msgstr "" "Este programa non un mtodo contraceptivo fibel. Tampouco pode servir de axuda na prevencin de enfermidades de transmisin sexual coma a SIDA.\n" "\n" "Tan s un medio electrnico que permite realizar un seguemento dalgns dos teus datos mdicos e extraer algunhas conclusins estatsticas a partires deles. De ningunha maneira podes considerar este programa como un substituto do teu xineclogo." #: dialogs.py:286 msgid "Enter you name:" msgstr "Introduce o teu nome:" #: dialogs.py:286 msgid "New user" msgstr "Nova usuaria" #: dialogs.py:305 #, fuzzy msgid " - already exists!" msgstr " - xa existe!" #: dialogs.py:307 msgid "Name must be not EMPTY" msgstr "O nome non pode estar BALEIRO" #: dialogs.py:324 msgid "today" msgstr "hoxe" #: dialogs.py:325 dialogs.py:446 msgid "begin of cycle" msgstr "comezo do ciclo" #: dialogs.py:326 dialogs.py:447 msgid "prognosis of cycle begin" msgstr "comezo da prognose do ciclo" #: dialogs.py:327 dialogs.py:448 msgid "conception" msgstr "concepcin" #: dialogs.py:328 dialogs.py:449 msgid "safe sex" msgstr "sexo seguro" #: dialogs.py:329 dialogs.py:450 msgid "fertile" msgstr "frtil" #: dialogs.py:330 dialogs.py:451 msgid "ovule, birth" msgstr "vulo, nacemento" #: dialogs.py:332 dialogs.py:453 msgid "tablets N 22-28 or pause" msgstr "plulas N 22-28 ou pausa" #: dialogs.py:378 msgid "Remove" msgstr "Eliminar" #: dialogs.py:436 msgid "Colours settings" msgstr "Configuracin das cores" #: dialogs.py:462 msgid "By default" msgstr "Por defecto" cycle-0.3.3/msg/gl/000077500000000000000000000000001443566760700140265ustar00rootroot00000000000000cycle-0.3.3/msg/gl/LC_MESSAGES/000077500000000000000000000000001443566760700156135ustar00rootroot00000000000000cycle-0.3.3/msg/gl/LC_MESSAGES/cycle.mo000066400000000000000000000074501443566760700172550ustar00rootroot00000000000000A$, -9>Rgm |    %.6FZy .JQYZ    6 ?M T^w}Y    ' , ; E K S \ {          . +F r x }          % %A g   */? EPX _mr   by average day day of gestation, day of period from days days in cycle or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleBy defaultCancelChange passwordColoursColours settingsConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsThis program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS. It 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.Your namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodaytry decode this stringProject-Id-Version: cycle-0.3.0-1 Report-Msgid-Bugs-To: POT-Creation-Date: 2005-04-13 22:11+0000 PO-Revision-Date: 2005-04-18 21:29+0200 Last-Translator: Susana Sotelo Doco Language-Team: Galician MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8-bit Generated-By: pygettext.py 1.4 de mediada da de xestacin, da do perodo dende das das no ciclo ou pausa ata semana semanas, introduce o teu contrasinal:1 plulaEngadir usuariaComezo de cyclePor defectoCancelarCambiar o contrasinalCoresConfiguracin das coresConcepcinAno actualAno anteriorAmosarIntroduce o teu nome:Introduce o contrasinalOs contrasinais introducidos non coinciden!Erro!SarPrimeiro da da semanaAxudaAno seguinteLendaLonxitude do cicloNome de usuariaO nome non pode estar BALEIRONova usuariaNotaAceptarUnha vez mis...ContrasinalO contrasinal non vlido!O contrasinal non pode estar BALEIRO!O perodo do ciclo non vlido!EliminarConfiguracinEste programa non un mtodo contraceptivo fibel. Tampouco pode servir de axuda na prevencin de enfermidades de transmisin sexual coma a SIDA. Tan s un medio electrnico que permite realizar un seguemento dalgns dos teus datos mdicos e extraer algunhas conclusins estatsticas a partires deles. De ningunha maneira podes considerar este programa como un substituto do teu xineclogo.Nomecomezo do cicloambosconcepcinbaleirofrtildas frtileslunsseguinte primeira plulavulo, nacementocomezo da prognose do ciclosexo segurodas de sexo segurodomingoplula N plulas N 22-28 ou pausahoxeintenta descodificar esta cadeacycle-0.3.3/msg/messages.pot000066400000000000000000000113061443566760700157600ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: Sat Apr 30 22:33:29 2005\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: ENCODING\n" "Generated-By: pygettext.py 1.5\n" #: ../cal_year.py:73 msgid "Begin of cycle" msgstr "" #: ../cal_year.py:75 ../dialogs.py:331 ../dialogs.py:452 msgid "1-st tablet" msgstr "" #: ../cal_year.py:78 msgid "Conception" msgstr "" #: ../cal_year.py:80 msgid "Note" msgstr "" #: ../cal_year.py:509 msgid "tablet N " msgstr "" #: ../cal_year.py:511 msgid " or pause" msgstr "" #: ../cal_year.py:513 ../dialogs.py:333 ../dialogs.py:454 msgid "next 1-st tablet" msgstr "" #: ../cal_year.py:551 msgid " day of gestation, " msgstr "" #: ../cal_year.py:552 msgid " week" msgstr "" #: ../cal_year.py:553 msgid " weeks" msgstr "" #: ../cal_year.py:555 msgid " day" msgstr "" #: ../cal_year.py:556 ../cal_year.py:563 msgid " days" msgstr "" #: ../cal_year.py:562 msgid " day of period from " msgstr "" #: ../cal_year.py:562 msgid " to " msgstr "" #: ../cal_year.py:563 msgid " length " msgstr "" #: ../cycle.py:43 ../cycle.py:57 msgid "try decode this string" msgstr "" #: ../cycle.py:96 msgid "Dec Year" msgstr "" #: ../cycle.py:99 msgid "Current Year" msgstr "" #: ../cycle.py:102 msgid "Inc Year" msgstr "" #: ../cycle.py:108 ../dialogs.py:319 msgid "Legend" msgstr "" #: ../cycle.py:111 ../dialogs.py:17 msgid "Settings" msgstr "" #: ../cycle.py:114 ../cycle.py:153 msgid "Help" msgstr "" #: ../cycle.py:122 msgid "Exit" msgstr "" #: ../dialogs.py:22 msgid "Length of cycle" msgstr "" #: ../dialogs.py:24 msgid " by average" msgstr "" #: ../dialogs.py:36 msgid " days in cycle" msgstr "" #: ../dialogs.py:40 msgid "Display" msgstr "" #: ../dialogs.py:41 msgid "both" msgstr "" #: ../dialogs.py:41 msgid "fertile days" msgstr "" #: ../dialogs.py:41 msgid "safe sex days" msgstr "" #: ../dialogs.py:47 msgid "First week day" msgstr "" #: ../dialogs.py:48 msgid "monday" msgstr "" #: ../dialogs.py:48 msgid "sunday" msgstr "" #: ../dialogs.py:55 msgid "Colours" msgstr "" #: ../dialogs.py:56 msgid "Change password" msgstr "" #: ../dialogs.py:70 ../dialogs.py:137 ../dialogs.py:217 ../dialogs.py:336 #: ../dialogs.py:370 ../dialogs.py:423 ../dialogs.py:458 msgid "Ok" msgstr "" #: ../dialogs.py:74 ../dialogs.py:141 ../dialogs.py:221 ../dialogs.py:374 #: ../dialogs.py:466 msgid "Cancel" msgstr "" #: ../dialogs.py:91 msgid "Period of cycle is invalid!" msgstr "" #: ../dialogs.py:92 ../dialogs.py:159 ../dialogs.py:255 ../dialogs.py:308 msgid "Error!" msgstr "" #: ../dialogs.py:117 ../dialogs.py:244 msgid "Password" msgstr "" #: ../dialogs.py:122 msgid "Enter your password" msgstr "" #: ../dialogs.py:128 msgid "Once more..." msgstr "" #: ../dialogs.py:154 msgid "Password must be not EMPTY!" msgstr "" #: ../dialogs.py:156 msgid "Entering password don't match!" msgstr "" #: ../dialogs.py:172 msgid "Login" msgstr "" #: ../dialogs.py:182 msgid "empty" msgstr "" #: ../dialogs.py:197 msgid "Your name" msgstr "" #: ../dialogs.py:211 msgid "Add user" msgstr "" #: ../dialogs.py:244 msgid ", enter you password:" msgstr "" #: ../dialogs.py:254 msgid "Password is invalid!" msgstr "" #: ../dialogs.py:280 msgid "" "This program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS.\n" "\n" "It 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." msgstr "" #: ../dialogs.py:286 msgid "Enter you name:" msgstr "" #: ../dialogs.py:286 msgid "New user" msgstr "" #: ../dialogs.py:305 msgid " - already exists!" msgstr "" #: ../dialogs.py:307 msgid "Name must be not EMPTY" msgstr "" #: ../dialogs.py:324 msgid "today" msgstr "" #: ../dialogs.py:325 ../dialogs.py:446 msgid "begin of cycle" msgstr "" #: ../dialogs.py:326 ../dialogs.py:447 msgid "prognosis of cycle begin" msgstr "" #: ../dialogs.py:327 ../dialogs.py:448 msgid "conception" msgstr "" #: ../dialogs.py:328 ../dialogs.py:449 msgid "safe sex" msgstr "" #: ../dialogs.py:329 ../dialogs.py:450 msgid "fertile" msgstr "" #: ../dialogs.py:330 ../dialogs.py:451 msgid "ovule, birth" msgstr "" #: ../dialogs.py:332 ../dialogs.py:453 msgid "tablets N 22-28 or pause" msgstr "" #: ../dialogs.py:378 msgid "Remove" msgstr "" #: ../dialogs.py:436 msgid "Colours settings" msgstr "" #: ../dialogs.py:462 msgid "By default" msgstr "" cycle-0.3.3/msg/msgfmt.py000077500000000000000000000126321443566760700153020ustar00rootroot00000000000000#! /usr/bin/env python # -*- coding: iso-8859-1 -*- # Written by Martin v. Lwis """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po Options: -o file --output-file=file Specify the output file to write to. If omitted, output will go to a file named filename.mo (based off the input file name). -h --help Print this message and exit. -V --version Display version information and exit. """ import sys import os import getopt import struct import array __version__ = "1.1" MESSAGES = {} def usage(code, msg=''): print >> sys.stderr, __doc__ if msg: print >> sys.stderr, msg sys.exit(code) def add(id, str, fuzzy): "Add a non-fuzzy translation to the dictionary." global MESSAGES if not fuzzy and str: MESSAGES[id] = str def generate(): "Return the generated output." global MESSAGES keys = MESSAGES.keys() # the keys are sorted in the .mo file keys.sort() offsets = [] ids = strs = '' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) ids += id + '\0' strs += MESSAGES[id] + '\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. # translated string. keystart = 7*4+16*len(keys) # and the values start after the keys valuestart = keystart + len(ids) koffsets = [] voffsets = [] # The string table first has the list of keys, then the list of values. # Each entry has first the size of the string, then the file offset. for o1, l1, o2, l2 in offsets: koffsets += [l1, o1+keystart] voffsets += [l2, o2+valuestart] offsets = koffsets + voffsets output = struct.pack("Iiiiiii", 0x950412deL, # Magic 0, # Version len(keys), # # of entries 7*4, # start of key index 7*4+len(keys)*8, # start of value index 0, 0) # size and offset of hash table output += array.array("i", offsets).tostring() output += ids output += strs return output def make(filename, outfile): ID = 1 STR = 2 # Compute .mo name from .po name and arguments if filename.endswith('.po'): infile = filename else: infile = filename + '.po' if outfile is None: outfile = os.path.splitext(infile)[0] + '.mo' try: lines = open(infile).readlines() except IOError, msg: print >> sys.stderr, msg sys.exit(1) section = None fuzzy = 0 # Parse the catalog lno = 0 for l in lines: lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: add(msgid, msgstr, fuzzy) section = None fuzzy = 0 # Record a fuzzy mark if l[:2] == '#,' and l.find('fuzzy'): fuzzy = 1 # Skip comments if l[0] == '#': continue # Now we are in a msgid section, output previous section if l.startswith('msgid'): if section == STR: add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR l = l[6:] # Skip empty lines l = l.strip() if not l: continue # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: msgid += l elif section == STR: msgstr += l else: print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ 'before:' print >> sys.stderr, l sys.exit(1) # Add last entry if section == STR: add(msgid, msgstr, fuzzy) # Compute output output = generate() try: open(outfile,"wb").write(output) except IOError,msg: print >> sys.stderr, msg def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'hVo:', ['help', 'version', 'output-file=']) except getopt.error, msg: usage(1, msg) outfile = None # parse options for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-V', '--version'): print >> sys.stderr, "msgfmt.py", __version__ sys.exit(0) elif opt in ('-o', '--output-file'): outfile = arg # do it if not args: print >> sys.stderr, 'No input file given' print >> sys.stderr, "Try `msgfmt --help' for more information." return for filename in args: make(filename, outfile) if __name__ == '__main__': main() cycle-0.3.3/msg/pygettext.py000077500000000000000000000531151443566760700160430ustar00rootroot00000000000000#! /usr/bin/env python # -*- coding: iso-8859-1 -*- # Originally written by Barry Warsaw # # Minimally patched to make it even more xgettext compatible # by Peter Funk # # 2002-11-22 Jrgen Hermann # Added checks that _() only contains string literals, and # command line args are resolved to module lists, i.e. you # can now pass a filename, a module or package name, or a # directory (including globbing chars, important for Win32). # Made docstring fit in 80 chars wide displays using pydoc. # # for selftesting try: import fintl _ = fintl.gettext except ImportError: _ = lambda s: s __doc__ = _("""pygettext -- Python equivalent of xgettext(1) Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the internationalization of C programs. Most of these tools are independent of the programming language and can be used from within Python programs. Martin von Loewis' work[1] helps considerably in this regard. There's one problem though; xgettext is the program that scans source code looking for message strings, but it groks only C (or C++). Python introduces a few wrinkles, such as dual quoting characters, triple quoted strings, and raw strings. xgettext understands none of this. Enter pygettext, which uses Python's standard tokenize module to scan Python source code, generating .pot files identical to what GNU xgettext[2] generates for C and C++ code. From there, the standard GNU tools can be used. A word about marking Python strings as candidates for translation. GNU xgettext recognizes the following keywords: gettext, dgettext, dcgettext, and gettext_noop. But those can be a lot of text to include all over your code. C and C++ have a trick: they use the C preprocessor. Most internationalized C source includes a #define for gettext() to _() so that what has to be written in the source is much less. Thus these are both translatable strings: gettext("Translatable String") _("Translatable String") Python of course has no preprocessor so this doesn't work so well. Thus, pygettext searches only for _() by default, but see the -k/--keyword flag below for how to augment this. [1] http://www.python.org/workshops/1997-10/proceedings/loewis.html [2] http://www.gnu.org/software/gettext/gettext.html NOTE: pygettext attempts to be option and feature compatible with GNU xgettext where ever possible. However some options are still missing or are not fully implemented. Also, xgettext's use of command line switches with option arguments is broken, and in these cases, pygettext just defines additional switches. Usage: pygettext [options] inputfile ... Options: -a --extract-all Extract all strings. -d name --default-domain=name Rename the default output file from messages.pot to name.pot. -E --escape Replace non-ASCII characters with octal escape sequences. -D --docstrings Extract module, class, method, and function docstrings. These do not need to be wrapped in _() markers, and in fact cannot be for Python to consider them docstrings. (See also the -X option). -h --help Print this help message and exit. -k word --keyword=word Keywords to look for in addition to the default set, which are: %(DEFAULTKEYWORDS)s You can have multiple -k flags on the command line. -K --no-default-keywords Disable the default set of keywords (see above). Any keywords explicitly added with the -k/--keyword option are still recognized. --no-location Do not write filename/lineno location comments. -n --add-location Write filename/lineno location comments indicating where each extracted string is found in the source. These lines appear before each msgid. The style of comments is controlled by the -S/--style option. This is the default. -o filename --output=filename Rename the default output file from messages.pot to filename. If filename is `-' then the output is sent to standard out. -p dir --output-dir=dir Output files will be placed in directory dir. -S stylename --style stylename Specify which style to use for location comments. Two styles are supported: Solaris # File: filename, line: line-number GNU #: filename:line The style name is case insensitive. GNU style is the default. -v --verbose Print the names of the files being processed. -V --version Print the version of pygettext and exit. -w columns --width=columns Set width of output to columns. -x filename --exclude-file=filename Specify a file that contains a list of strings that are not be extracted from the input files. Each string to be excluded must appear on a line by itself in the file. -X filename --no-docstrings=filename Specify a file that contains a list of files (one per line) that should not have their docstrings extracted. This is only useful in conjunction with the -D option above. If `inputfile' is -, standard input is read. """) import os import imp import sys import glob import time import getopt import token import tokenize import operator __version__ = '1.5' default_keywords = ['_'] DEFAULTKEYWORDS = ', '.join(default_keywords) EMPTYSTRING = '' # The normal pot-file header. msgmerge and Emacs's po-mode work better if it's # there. pot_header = _('''\ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\\n" "POT-Creation-Date: %(time)s\\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" "Last-Translator: FULL NAME \\n" "Language-Team: LANGUAGE \\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=CHARSET\\n" "Content-Transfer-Encoding: ENCODING\\n" "Generated-By: pygettext.py %(version)s\\n" ''') def usage(code, msg=''): print >> sys.stderr, __doc__ % globals() if msg: print >> sys.stderr, msg sys.exit(code) escapes = [] def make_escapes(pass_iso8859): global escapes if pass_iso8859: # Allow iso-8859 characters to pass through so that e.g. 'msgid # "Hhe"' would result not result in 'msgid "H\366he"'. Otherwise we # escape any character outside the 32..126 range. mod = 128 else: mod = 256 for i in range(256): if 32 <= (i % mod) <= 126: escapes.append(chr(i)) else: escapes.append("\\%03o" % i) escapes[ord('\\')] = '\\\\' escapes[ord('\t')] = '\\t' escapes[ord('\r')] = '\\r' escapes[ord('\n')] = '\\n' escapes[ord('\"')] = '\\"' def escape(s): global escapes s = list(s) for i in range(len(s)): s[i] = escapes[ord(s[i])] return EMPTYSTRING.join(s) def safe_eval(s): # unwrap quotes, safely return eval(s, {'__builtins__':{}}, {}) def normalize(s): # This converts the various Python string types into a format that is # appropriate for .po files, namely much closer to C style. lines = s.split('\n') if len(lines) == 1: s = '"' + escape(s) + '"' else: if not lines[-1]: del lines[-1] lines[-1] = lines[-1] + '\n' for i in range(len(lines)): lines[i] = escape(lines[i]) lineterm = '\\n"\n"' s = '""\n"' + lineterm.join(lines) + '"' return s def containsAny(str, set): """Check whether 'str' contains ANY of the chars in 'set'""" return 1 in [c in str for c in set] def _visit_pyfiles(list, dirname, names): """Helper for getFilesForName().""" # get extension for python source files if not globals().has_key('_py_ext'): global _py_ext _py_ext = [triple[0] for triple in imp.get_suffixes() if triple[2] == imp.PY_SOURCE][0] # don't recurse into CVS directories if 'CVS' in names: names.remove('CVS') # add all *.py files to list list.extend( [os.path.join(dirname, file) for file in names if os.path.splitext(file)[1] == _py_ext] ) def _get_modpkg_path(dotted_name, pathlist=None): """Get the filesystem path for a module or a package. Return the file system path to a file for a module, and to a directory for a package. Return None if the name is not found, or is a builtin or extension module. """ # split off top-most name parts = dotted_name.split('.', 1) if len(parts) > 1: # we have a dotted path, import top-level package try: file, pathname, description = imp.find_module(parts[0], pathlist) if file: file.close() except ImportError: return None # check if it's indeed a package if description[2] == imp.PKG_DIRECTORY: # recursively handle the remaining name parts pathname = _get_modpkg_path(parts[1], [pathname]) else: pathname = None else: # plain name try: file, pathname, description = imp.find_module( dotted_name, pathlist) if file: file.close() if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]: pathname = None except ImportError: pathname = None return pathname def getFilesForName(name): """Get a list of module files for a filename, a module or package name, or a directory. """ if not os.path.exists(name): # check for glob chars if containsAny(name, "*?[]"): files = glob.glob(name) list = [] for file in files: list.extend(getFilesForName(file)) return list # try to find module or package name = _get_modpkg_path(name) if not name: return [] if os.path.isdir(name): # find all python files in directory list = [] os.path.walk(name, _visit_pyfiles, list) return list elif os.path.exists(name): # a single file return [name] return [] class TokenEater: def __init__(self, options): self.__options = options self.__messages = {} self.__state = self.__waiting self.__data = [] self.__lineno = -1 self.__freshmodule = 1 self.__curfile = None def __call__(self, ttype, tstring, stup, etup, line): # dispatch ## import token ## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \ ## 'tstring:', tstring self.__state(ttype, tstring, stup[0]) def __waiting(self, ttype, tstring, lineno): opts = self.__options # Do docstring extractions, if enabled if opts.docstrings and not opts.nodocstrings.get(self.__curfile): # module docstring? if self.__freshmodule: if ttype == tokenize.STRING: self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__freshmodule = 0 elif ttype not in (tokenize.COMMENT, tokenize.NL): self.__freshmodule = 0 return # class docstring? if ttype == tokenize.NAME and tstring in ('class', 'def'): self.__state = self.__suiteseen return if ttype == tokenize.NAME and tstring in opts.keywords: self.__state = self.__keywordseen def __suiteseen(self, ttype, tstring, lineno): # ignore anything until we see the colon if ttype == tokenize.OP and tstring == ':': self.__state = self.__suitedocstring def __suitedocstring(self, ttype, tstring, lineno): # ignore any intervening noise if ttype == tokenize.STRING: self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__state = self.__waiting elif ttype not in (tokenize.NEWLINE, tokenize.INDENT, tokenize.COMMENT): # there was no class docstring self.__state = self.__waiting def __keywordseen(self, ttype, tstring, lineno): if ttype == tokenize.OP and tstring == '(': self.__data = [] self.__lineno = lineno self.__state = self.__openseen else: self.__state = self.__waiting def __openseen(self, ttype, tstring, lineno): if ttype == tokenize.OP and tstring == ')': # We've seen the last of the translatable strings. Record the # line number of the first line of the strings and update the list # of messages seen. Reset state for the next batch. If there # were no strings inside _(), then just ignore this entry. if self.__data: self.__addentry(EMPTYSTRING.join(self.__data)) self.__state = self.__waiting elif ttype == tokenize.STRING: self.__data.append(safe_eval(tstring)) elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT, token.NEWLINE, tokenize.NL]: # warn if we see anything else than STRING or whitespace print >> sys.stderr, _( '*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"' ) % { 'token': tstring, 'file': self.__curfile, 'lineno': self.__lineno } self.__state = self.__waiting def __addentry(self, msg, lineno=None, isdocstring=0): if lineno is None: lineno = self.__lineno if not msg in self.__options.toexclude: entry = (self.__curfile, lineno) self.__messages.setdefault(msg, {})[entry] = isdocstring def set_filename(self, filename): self.__curfile = filename self.__freshmodule = 1 def write(self, fp): options = self.__options timestamp = time.ctime(time.time()) # The time stamp in the header doesn't have the same format as that # generated by xgettext... print >> fp, pot_header % {'time': timestamp, 'version': __version__} # Sort the entries. First sort each particular entry's keys, then # sort all the entries by their first item. reverse = {} for k, v in self.__messages.items(): keys = v.keys() keys.sort() reverse.setdefault(tuple(keys), []).append((k, v)) rkeys = reverse.keys() rkeys.sort() for rkey in rkeys: rentries = reverse[rkey] rentries.sort() for k, v in rentries: isdocstring = 0 # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. if reduce(operator.__add__, v.values()): isdocstring = 1 # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by # file name and then by line number. v = v.keys() v.sort() if not options.writelocations: pass # location comments are different b/w Solaris and GNU: elif options.locationstyle == options.SOLARIS: for filename, lineno in v: d = {'filename': filename, 'lineno': lineno} print >>fp, _( '# File: %(filename)s, line: %(lineno)d') % d elif options.locationstyle == options.GNU: # fit as many locations on one line, as long as the # resulting line length doesn't exceeds 'options.width' locline = '#:' for filename, lineno in v: d = {'filename': filename, 'lineno': lineno} s = _(' %(filename)s:%(lineno)d') % d if len(locline) + len(s) <= options.width: locline = locline + s else: print >> fp, locline locline = "#:" + s if len(locline) > 2: print >> fp, locline if isdocstring: print >> fp, '#, docstring' print >> fp, 'msgid', normalize(k) print >> fp, 'msgstr ""\n' def main(): global default_keywords try: opts, args = getopt.getopt( sys.argv[1:], 'ad:DEhk:Kno:p:S:Vvw:x:X:', ['extract-all', 'default-domain=', 'escape', 'help', 'keyword=', 'no-default-keywords', 'add-location', 'no-location', 'output=', 'output-dir=', 'style=', 'verbose', 'version', 'width=', 'exclude-file=', 'docstrings', 'no-docstrings', ]) except getopt.error, msg: usage(1, msg) # for holding option values class Options: # constants GNU = 1 SOLARIS = 2 # defaults extractall = 0 # FIXME: currently this option has no effect at all. escape = 0 keywords = [] outpath = '' outfile = 'messages.pot' writelocations = 1 locationstyle = GNU verbose = 0 width = 78 excludefilename = '' docstrings = 0 nodocstrings = {} options = Options() locations = {'gnu' : options.GNU, 'solaris' : options.SOLARIS, } # parse options for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-a', '--extract-all'): options.extractall = 1 elif opt in ('-d', '--default-domain'): options.outfile = arg + '.pot' elif opt in ('-E', '--escape'): options.escape = 1 elif opt in ('-D', '--docstrings'): options.docstrings = 1 elif opt in ('-k', '--keyword'): options.keywords.append(arg) elif opt in ('-K', '--no-default-keywords'): default_keywords = [] elif opt in ('-n', '--add-location'): options.writelocations = 1 elif opt in ('--no-location',): options.writelocations = 0 elif opt in ('-S', '--style'): options.locationstyle = locations.get(arg.lower()) if options.locationstyle is None: usage(1, _('Invalid value for --style: %s') % arg) elif opt in ('-o', '--output'): options.outfile = arg elif opt in ('-p', '--output-dir'): options.outpath = arg elif opt in ('-v', '--verbose'): options.verbose = 1 elif opt in ('-V', '--version'): print _('pygettext.py (xgettext for Python) %s') % __version__ sys.exit(0) elif opt in ('-w', '--width'): try: options.width = int(arg) except ValueError: usage(1, _('--width argument must be an integer: %s') % arg) elif opt in ('-x', '--exclude-file'): options.excludefilename = arg elif opt in ('-X', '--no-docstrings'): fp = open(arg) try: while 1: line = fp.readline() if not line: break options.nodocstrings[line[:-1]] = 1 finally: fp.close() # calculate escapes make_escapes(options.escape) # calculate all keywords options.keywords.extend(default_keywords) # initialize list of strings to exclude if options.excludefilename: try: fp = open(options.excludefilename) options.toexclude = fp.readlines() fp.close() except IOError: print >> sys.stderr, _( "Can't read --exclude-file: %s") % options.excludefilename sys.exit(1) else: options.toexclude = [] # resolve args to module lists expanded = [] for arg in args: if arg == '-': expanded.append(arg) else: expanded.extend(getFilesForName(arg)) args = expanded # slurp through all the files eater = TokenEater(options) for filename in args: if filename == '-': if options.verbose: print _('Reading standard input') fp = sys.stdin closep = 0 else: if options.verbose: print _('Working on %s') % filename fp = open(filename) closep = 1 try: eater.set_filename(filename) try: tokenize.tokenize(fp.readline, eater) except tokenize.TokenError, e: print >> sys.stderr, '%s: %s, line %d, column %d' % ( e[0], filename, e[1][0], e[1][1]) finally: if closep: fp.close() # write the output if options.outfile == '-': fp = sys.stdout closep = 0 else: if options.outpath: options.outfile = os.path.join(options.outpath, options.outfile) fp = open(options.outfile, 'w') closep = 1 try: eater.write(fp) finally: if closep: fp.close() if __name__ == '__main__': main() # some more test strings _(u'a unicode string') # this one creates a warning _('*** Seen unexpected token "%(token)s"') % {'token': 'test'} _('more' 'than' 'one' 'string') cycle-0.3.3/msg/ru.po000066400000000000000000000113021443566760700144070ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: Fri Apr 19 10:56:14 2002\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8-bit\n" "Generated-By: pygettext.py 1.4\n" #: cal_year.py:416 msgid " day of period from " msgstr "- " #: cal_year.py:416 msgid " to " msgstr " " #: cal_year.py:417 msgid " days" msgstr " ." #: cal_year.py:417 msgid " length " msgstr " " #: cycle.py:54 msgid "Dec Year" msgstr " " #: cycle.py:57 msgid "Current Year" msgstr " " #: cycle.py:60 msgid "Inc Year" msgstr " " #: cycle.py:66 dialogs.py:15 msgid "Settings" msgstr "" #: cycle.py:69 msgid "Help" msgstr "" #: cycle.py:72 msgid "Exit" msgstr "" #: dialogs.py:20 msgid "Length of cycle" msgstr " " #: dialogs.py:22 msgid " by average" msgstr " " #: dialogs.py:34 msgid " days in cycle" msgstr " " #: dialogs.py:38 msgid "Display" msgstr "" #: dialogs.py:39 msgid "both" msgstr "" #: dialogs.py:39 msgid "fertile days" msgstr " " #: dialogs.py:39 msgid "safe sex days" msgstr " " #: dialogs.py:46 msgid "Change password" msgstr " " #: dialogs.py:54 dialogs.py:116 dialogs.py:196 msgid "Ok" msgstr "" #: dialogs.py:58 dialogs.py:120 dialogs.py:200 msgid "Cancel" msgstr "" #: dialogs.py:75 msgid "Period of cycle is invalid!" msgstr " !" #: dialogs.py:76 dialogs.py:138 dialogs.py:236 dialogs.py:281 msgid "Error!" msgstr "!" #: dialogs.py:96 dialogs.py:225 msgid "Password" msgstr "" #: dialogs.py:101 msgid "Enter your password" msgstr " " #: dialogs.py:107 msgid "Once more..." msgstr " ..." #: dialogs.py:133 msgid "Password must be not EMPTY!" msgstr " " #: dialogs.py:135 msgid "Entering password don't match!" msgstr ", ." #: dialogs.py:151 msgid "Login" msgstr " " #: dialogs.py:161 msgid "empty" msgstr "" #: dialogs.py:176 msgid "Your name" msgstr " " #: dialogs.py:190 msgid "Add user" msgstr " " #: dialogs.py:225 msgid ", enter you password:" msgstr ", :" #: dialogs.py:235 msgid "Password is invalid!" msgstr " !" #: dialogs.py:260 msgid "Enter you name:" msgstr " " #: dialogs.py:260 msgid "New user" msgstr " " #: dialogs.py:278 msgid " - already exists!" msgstr " - !" #: dialogs.py:280 msgid "Name must be not EMPTY" msgstr " " #: cycle.py:72 dialogs.py:292 msgid "Legend" msgstr "" #: dialogs.py:297 msgid "today" msgstr "" #: dialogs.py:298 msgid "begin of cycle" msgstr " " #: dialogs.py:299 msgid "prognosis of cycle begin" msgstr " " #: dialogs.py:300 msgid "safe sex" msgstr " " #: dialogs.py:301 msgid "fertile" msgstr " " #: dialogs.py:302 msgid "ovule, birth" msgstr ", " msgid "Remove" msgstr "" msgid "Note" msgstr "" msgid "Begin of cycle" msgstr " " msgid "Conception" msgstr "" msgid "conception" msgstr "" msgid " day of gestation, " msgstr " , " msgid " week" msgstr " ." msgid " weeks" msgstr " ." msgid " day" msgstr " ." msgid "First week day" msgstr " " msgid "monday" msgstr "" msgid "sunday" msgstr "" msgid "tablet N " msgstr " N " msgid " or pause" msgstr " " msgid "next 1-st tablet" msgstr " 1- " msgid "1-st tablet" msgstr "1- " msgid "tablets N 22-28 or pause" msgstr " N 22-28 " msgid "Colours" msgstr "" msgid "Colours settings" msgstr " " msgid "By default" msgstr " " #: dialogs.py:280 msgid "" "This program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS.\n" "\n" "It 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." msgstr "" " . , . ." cycle-0.3.3/msg/ru/000077500000000000000000000000001443566760700140525ustar00rootroot00000000000000cycle-0.3.3/msg/ru/LC_MESSAGES/000077500000000000000000000000001443566760700156375ustar00rootroot00000000000000cycle-0.3.3/msg/ru/LC_MESSAGES/cycle.mo000066400000000000000000000070411443566760700172750ustar00rootroot00000000000000B,<= P\au     ( 9 DQZbr   )>Zv}Y    $+ <Ib ky B    2 7 E Z g l r x         ( : M f n t            9 T \ f  ) 6 : G M \ k w       - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleBy defaultCancelChange passwordColoursColours settingsConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsThis program is not a reliable contraceptive method. Neither does it help to prevent sexually transmitted diseases like HIV/AIDS. It 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.Your namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: PACKAGE VERSION POT-Creation-Date: Fri Apr 19 10:56:14 2002 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8-bit Generated-By: pygettext.py 1.4 - ! . , - . . ., :1- , .! ... ! ! . , . . 1- , N N 22-28 cycle-0.3.3/msg/sk.po000066400000000000000000000112161443566760700144020ustar00rootroot00000000000000# translation of messages.po to slovak # Jozef Riha , 2004. # msgid "" msgstr "" "Project-Id-Version: sk_SK\n" "POT-Creation-Date: Thu Oct 24 09:07:06 2002\n" "PO-Revision-Date: 2004-03-14 16:40+0100\n" "Last-Translator: Jozef Riha \n" "Language-Team:\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.4\n" "X-Generator: KBabel 1.0.2\n" #: ../cal_year.py:70 msgid "Begin of cycle" msgstr "Začiatok cyklusu" #: ../cal_year.py:72 ../dialogs.py:313 msgid "1-st tablet" msgstr "Prvá tabletka" #: ../cal_year.py:75 msgid "Conception" msgstr "Počatie" #: ../cal_year.py:77 msgid "Note" msgstr "Poznámka" #: ../cal_year.py:505 msgid "tablet N " msgstr "Tabletka N" #: ../cal_year.py:507 msgid " or pause" msgstr " alebo prestávka" #: ../cal_year.py:509 ../dialogs.py:315 msgid "next 1-st tablet" msgstr "ďalšia prvá tabletka" #: ../cal_year.py:547 msgid " day of gestation, " msgstr " deň tehotenstva, " #: ../cal_year.py:548 msgid " week" msgstr " týždeň" #: ../cal_year.py:549 msgid " weeks" msgstr " týždne" #: ../cal_year.py:551 msgid " day" msgstr " deň" #: ../cal_year.py:552 ../cal_year.py:559 msgid " days" msgstr " dni" #: ../cal_year.py:558 msgid " day of period from " msgstr " deň periódy od " #: ../cal_year.py:558 msgid " to " msgstr " do " #: ../cal_year.py:559 msgid " length " msgstr " dĺžka " #: ../cycle.py:64 msgid "Dec Year" msgstr "Min. Rok" #: ../cycle.py:67 msgid "Current Year" msgstr "Aktuálny Rok" #: ../cycle.py:70 msgid "Inc Year" msgstr "Bud. rok" #: ../cycle.py:76 ../dialogs.py:301 msgid "Legend" msgstr "Legenda" #: ../cycle.py:79 ../dialogs.py:16 msgid "Settings" msgstr "Nastavenia" #: ../cycle.py:82 ../cycle.py:118 msgid "Help" msgstr "Pomoc" #: ../cycle.py:90 msgid "Exit" msgstr "Koniec" #: ../dialogs.py:21 msgid "Length of cycle" msgstr "Dĺžka cyklusu" #: ../dialogs.py:23 msgid " by average" msgstr " v priemere" #: ../dialogs.py:35 msgid " days in cycle" msgstr " dní v cykluse" #: ../dialogs.py:39 msgid "Display" msgstr "Zobraz" #: ../dialogs.py:40 msgid "both" msgstr "obidva" #: ../dialogs.py:40 msgid "fertile days" msgstr "plodné dni" #: ../dialogs.py:40 msgid "safe sex days" msgstr "dni bezpečného sexu" #: ../dialogs.py:46 msgid "First week day" msgstr "Prvý deň v týždni" #: ../dialogs.py:47 msgid "monday" msgstr "pondelok" #: ../dialogs.py:47 msgid "sunday" msgstr "nedeľa" #: ../dialogs.py:54 msgid "Change password" msgstr "Zmeniť heslo" #: ../dialogs.py:62 ../dialogs.py:125 ../dialogs.py:205 ../dialogs.py:318 #: ../dialogs.py:352 ../dialogs.py:403 msgid "Ok" msgstr "Ok" #: ../dialogs.py:66 ../dialogs.py:129 ../dialogs.py:209 ../dialogs.py:356 msgid "Cancel" msgstr "Zrušiť" #: ../dialogs.py:83 msgid "Period of cycle is invalid!" msgstr "Perióda cyklu je zle zadaná!" #: ../dialogs.py:84 ../dialogs.py:147 ../dialogs.py:245 ../dialogs.py:290 msgid "Error!" msgstr "Chyba!" #: ../dialogs.py:105 ../dialogs.py:234 msgid "Password" msgstr "Heslo" #: ../dialogs.py:110 msgid "Enter your password" msgstr "Zadajte vaše heslo" #: ../dialogs.py:116 msgid "Once more..." msgstr "Ešte raz..." #: ../dialogs.py:142 msgid "Password must be not EMPTY!" msgstr "Heslo nesmie byť PRÁZDNE!" #: ../dialogs.py:144 msgid "Entering password don't match!" msgstr "Heslá nie sú rovnaké!" #: ../dialogs.py:160 msgid "Login" msgstr "Prihlásenie" #: ../dialogs.py:170 msgid "empty" msgstr "prázdne" #: ../dialogs.py:185 msgid "Your name" msgstr "Vaše meno" #: ../dialogs.py:199 msgid "Add user" msgstr "Pridať užívateľa" #: ../dialogs.py:234 msgid ", enter you password:" msgstr ", zadajte vaše heslo" #: ../dialogs.py:244 msgid "Password is invalid!" msgstr "Chybné heslo!" #: ../dialogs.py:269 msgid "Enter you name:" msgstr "Zadejte vaše meno:" #: ../dialogs.py:269 msgid "New user" msgstr "Nový užívateľ" #: ../dialogs.py:287 msgid " - already exists!" msgstr " - už existuje!" #: ../dialogs.py:289 msgid "Name must be not EMPTY" msgstr "Meno nesmie byť PRÁZDNE" #: ../dialogs.py:306 msgid "today" msgstr "dnes" #: ../dialogs.py:307 msgid "begin of cycle" msgstr "začiatok cyklusu" #: ../dialogs.py:308 msgid "prognosis of cycle begin" msgstr "prognóza začiatku cyklusu" #: ../dialogs.py:309 msgid "conception" msgstr "počatie" #: ../dialogs.py:310 msgid "safe sex" msgstr "bezpečný sex" #: ../dialogs.py:311 msgid "fertile" msgstr "plodnosť" #: ../dialogs.py:312 msgid "ovule, birth" msgstr "vajíčko, narodenie" #: ../dialogs.py:314 msgid "tablets N 22-28 or pause" msgstr "tabletky N 22-28 alebo prestávka" #: ../dialogs.py:360 msgid "Remove" msgstr "Odstrániť" cycle-0.3.3/msg/sk/000077500000000000000000000000001443566760700140415ustar00rootroot00000000000000cycle-0.3.3/msg/sk/LC_MESSAGES/000077500000000000000000000000001443566760700156265ustar00rootroot00000000000000cycle-0.3.3/msg/sk/LC_MESSAGES/cycle.mo000066400000000000000000000056131443566760700172670ustar00rootroot00000000000000>  !5JP_ hrw}   "AHM\ajq  ",; @KQ Yfm ~  =) :FL`sx     ! * 8 A H \ p            ' - < X w         , ; Q Y !d  - already exists! by average day day of gestation, day of period from days days in cycle length or pause to week weeks, enter you password:1-st tabletAdd userBegin of cycleCancelChange passwordConceptionCurrent YearDec YearDisplayEnter you name:Enter your passwordEntering password don't match!Error!ExitFirst week dayHelpInc YearLegendLength of cycleLoginName must be not EMPTYNew userNoteOkOnce more...PasswordPassword is invalid!Password must be not EMPTY!Period of cycle is invalid!RemoveSettingsYour namebegin of cyclebothconceptionemptyfertilefertile daysmondaynext 1-st tabletovule, birthprognosis of cycle beginsafe sexsafe sex dayssundaytablet N tablets N 22-28 or pausetodayProject-Id-Version: sk_SK POT-Creation-Date: Thu Oct 24 09:07:06 2002 PO-Revision-Date: 2004-03-14 16:40+0100 Last-Translator: Jozef Riha Language-Team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated-By: pygettext.py 1.4 X-Generator: KBabel 1.0.2 - už existuje! v priemere deň deň tehotenstva, deň periódy od dni dní v cykluse dĺžka alebo prestávka do týždeň týždne, zadajte vaše hesloPrvá tabletkaPridať užívateľaZačiatok cyklusuZrušiťZmeniť hesloPočatieAktuálny RokMin. RokZobrazZadejte vaše meno:Zadajte vaše hesloHeslá nie sú rovnaké!Chyba!KoniecPrvý deň v týždniPomocBud. rokLegendaDĺžka cyklusuPrihlásenieMeno nesmie byť PRÁZDNENový užívateľPoznámkaOkEšte raz...HesloChybné heslo!Heslo nesmie byť PRÁZDNE!Perióda cyklu je zle zadaná!OdstrániťNastaveniaVaše menozačiatok cyklusuobidvapočatieprázdneplodnosťplodné dnipondelokďalšia prvá tabletkavajíčko, narodenieprognóza začiatku cyklusubezpečný sexdni bezpečného sexunedeľaTabletka Ntabletky N 22-28 alebo prestávkadnescycle-0.3.3/p_rotor.py000066400000000000000000000212271443566760700147000ustar00rootroot00000000000000"""This module was written by Gerd Woetzel: http://mail.python.org/pipermail/python-list/2005-January/261304.html This module is derived from Modules/rotormodule.c and translated into Python. I have appended the Copyright by Lance Ellinghouse below. The rotor module has been removed from the Python 2.4 distribution because the rotor module uses an insecure algorithm and is deprecated. ============================================================== Of course, this does still hold. However, I think this module might be used and adapted for demonstration purposes and might help some poor users who have encrypted (or obfuscated) some old stuff with the rotor module and have no access to older Python versions any more. Documentation can be found in Python Library Reference, Guido van Rossum, Fred L. Drake, Jr., editor, PythonLabs, Release 2.3.4 May 20, 2004 ##################################################################### Copyright 1994 by Lance Ellinghouse, Cathedral City, California Republic, United States of America. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Lance Ellinghouse not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ##################################################################### """ class newrotor(object): def __init__(self, key, n_rotors=6): self.n_rotors = n_rotors self.setkey(key) def setkey(self, key): self.key = key self.rotors = None self.positions = [None, None] def encrypt(self, buf): # Reset (encrypt) positions and encryptmore self.positions[0] = None return self.cryptmore(buf, 0) def encryptmore(self, buf): return self.cryptmore(buf, 0) def decrypt(self, buf): # Reset decrypt positions and decryptmore self.positions[1] = None return self.cryptmore(buf, 1) def decryptmore(self, buf): return self.cryptmore(buf, 1) def cryptmore(self, buf, do_decrypt): size, nr, rotors, pos = self.get_rotors(do_decrypt) outbuf = [] append = outbuf.append for c in buf: if do_decrypt: # Apply decrypt rotors and xor in reverse order for i in range(nr-1, -1, -1): c = pos[i] ^ rotors[i][c] else: # Apply xor and ecrypt rotors for i in range(nr): c = rotors[i][c ^ pos[i]] append(c) # Advance rotors, i.e. add the (fixed) rotor increments to the # variable rotor positions with carry. # Note: In the C-implementation, the result of the carry addition # was stored to an "unsigned char". Hence the next carry # is lost if pos[i] == size-1 and pnew >= size. # Masking with 0xff simulates this behavior. # pnew = 0 # (pnew >= size) works as "carry bit" for i in range(nr): pnew = ((pos[i] + (pnew >= size)) & 0xff) + rotors[i][size] pos[i] = pnew % size return bytes(outbuf) def get_rotors(self, do_decrypt): # Return a tuple (size, nr, rotors, positions) where # - size is the rotor size (== 256, because of 8-bit bytes) # - nr is the number of rotors. # - rotors is a tuple of nr encrypt or nr decrypt rotors # for do_decrypt == 0 or do_decrypt == 1 respectively. # - postions is a list of nr "rotor positions". # # The rotors represent the static aspect of the rotor machine which # is initially computed from key and fixed during en/decryption. # A rotor is a random permutation of range(size) extended # by an "increment value" in range(size). # # The followng statements hold for a tuple of encrypt rotors E and # and the corresponding tuple of decrypt rotors D. # # D[i][E[i][j]] == j for i in range(nr) for j in range(size) # # E[i][D[i][j]] == j for i in range(nr) for j in range(size) # # This means that the corresponding rotors E[i] and D[i] are # inverse permutations. # The increments are equal for the corresponding encrypt and # decrypt rotors and have an odd value: # # D[i][size] == E[i][size] and E[i][size] == 1 mod 2 and # 0 < E[i][size] < size for i in range(nr) # # The position vector represents the dynamic aspect. # It changes after each en/decrypted character (the rotors # are "advanced"). The initial position vector is also computed # from the key # nr = self.n_rotors rotors = self.rotors positions = self.positions[do_decrypt] if positions is None: if rotors: positions = list(rotors[3]) else: # Generate identity permutation for 8-bit bytes plus an # (unused) increment value self.size = size = 256 id_rotor = list(range(size+1)) # Generate nr "random" initial positions and "random" # en/decrypt rotors from id_rotor. # rand = random_func(self.key) E = [] D = [] positions = [] for i in range(nr): i = size positions.append(rand(i)) erotor = id_rotor[:] drotor = id_rotor[:] drotor[i] = erotor[i] = 1 + 2*rand(i//2) # increment while i > 1: r = rand(i) i -= 1 er = erotor[r] erotor[r] = erotor[i] erotor[i] = er drotor[er] = i drotor[erotor[0]] = 0 E.append(tuple(erotor)) D.append(tuple(drotor)) self.rotors = rotors = ( tuple(E), tuple(D), size, tuple(positions)) self.positions[do_decrypt] = positions return rotors[2], nr, rotors[do_decrypt], positions def random_func(key): # Generate a random number generator that is "seeded" from key. # This algorithm is copied from Python2.3 randommodule.c. # mask = 0xffff x = 995 y = 576 z = 767 for c in key: x = (((x << 3 | x >> 13) + c) & mask) y = (((y << 3 | y >> 13) ^ c) & mask) z = (((z << 3 | z >> 13) - c) & mask) # Emulate (unintended?) cast to short maxpos = mask >> 1 mask += 1 if x > maxpos: x -= mask if y > maxpos: y -= mask if z > maxpos: z -= mask y |= 1 # avoid very bad seed, why not for x and z too? # Oh, dear, for compatibility, we must evaluate the first seed transition # the hard way, later it becomes much simpler x = 171 * (x % 177) - 2 * (x//177) y = 172 * (y % 176) - 35 * (y//176) z = 170 * (z % 178) - 63 * (z//178) if x < 0: x += 30269 if y < 0: y += 30307 if z < 0: z += 30323 # At least all values are > 0 by now but may be greater than expected .. def rand(n, seed=[(x, y, z)]): # Return a random number 0 <= r < n # x, y, z = seed[0] seed[0] = ((171*x) % 30269, (172*y) % 30307, (170*z) % 30323) return int((x/30269.0 + y/30307.0 + z/30323.0) * n) % n # Original code was like this: # from math import floor # val = x/30269.0 + y/30307.0 + z/30323.0 # val = val - floor(val) # if val >= 1.0: # val = 0.0 # n = int(val*n) % n return rand cycle-0.3.3/save_load.py000066400000000000000000000127241443566760700151530ustar00rootroot00000000000000# 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 hashlib import pickle import os.path import os import cal_year import wx import warnings # deprecated since release 2.3 warnings.filterwarnings("ignore", category=DeprecationWarning, message='.*rotor module', module=__name__) try: import rotor except: import p_rotor as rotor # Unpickler with class renaming for compatibility with old saves import io class OldCycleUnpickler(pickle.Unpickler): def find_class(self, module, name): renamed_module = module if module == "sip": renamed_module = "wx.siplib" return super(OldCycleUnpickler, self).find_class(renamed_module, name) def loadPickledCycles(s): file = io.BytesIO(s) return OldCycleUnpickler(file).load() def Save_Cycle(name='cycle', passwd='123', file='cycle'): """ Save the contents of our document to disk. """ objSave = [] m = hashlib.md5() m.update(passwd.encode('utf-8')) rt = rotor.newrotor(m.digest()) objSave.append(['period', cal_year.cycle.period]) objSave.append(['by_average', cal_year.cycle.by_average]) objSave.append(['disp', cal_year.cycle.disp]) objSave.append(['first_week_day', cal_year.cycle.first_week_day]) objSave.append(['note', cal_year.cycle.note]) for d in cal_year.cycle.begin: objSave.append(['begin', [d.GetDay(), d.GetMonth(), d.GetYear()]]) for d in cal_year.cycle.last: objSave.append(['last', [d.GetDay(), d.GetMonth(), d.GetYear()]]) for d in cal_year.cycle.tablet: objSave.append(['tablet', [d.GetDay(), d.GetMonth(), d.GetYear()]]) for d in list(cal_year.cycle.colour_set.keys()): objSave.append(['colour', [d, cal_year.cycle.colour_set[d].Get()]]) tmp = rt.encrypt(b'Cycle'+pickle.dumps(objSave)) tmp = b"UserName="+pickle.dumps(name)+b"==="+tmp p, f_name = get_f_name(file) if not os.path.exists(p): os.mkdir(p, 0o700) f = open(f_name, "wb") f.write(tmp) f.close() # print "All data saved to disk" def Load_Cycle(name='cycle', passwd='123', file='cycle'): p, f_name = get_f_name(file) if os.path.isfile(f_name): m = hashlib.md5() m.update(passwd.encode('utf-8')) rt = rotor.newrotor(m.digest()) f = open(f_name, "rb") tmp = f.read() if tmp[:len(b"UserName=")] == b"UserName=": # new format n = tmp.find(b"===")+len(b"===") tmp = tmp[n:] # remove username tmp = rt.decrypt(tmp) f.close() if tmp[0:5] != b'Cycle': # print 'Password is invalid' return False else: tmp = tmp[5:] # remove control word 'Cycle' objLoad = loadPickledCycles(tmp) set_color_default() for type, d in objLoad: # print "Load: ", type, d if type == 'period': cal_year.cycle.period = int(d) elif type == 'by_average': cal_year.cycle.by_average = int(d) elif type == 'disp': cal_year.cycle.disp = int(d) elif type == 'first_week_day': cal_year.cycle.first_week_day = int(d) elif type == 'begin': dt = wx.DateTime.FromDMY(d[0], d[1], d[2]) cal_year.cycle.begin.append(dt) elif type == 'last': dt = wx.DateTime.FromDMY(d[0], d[1], d[2]) cal_year.cycle.last.append(dt) elif type == 'tablet': dt = wx.DateTime.FromDMY(d[0], d[1], d[2]) cal_year.cycle.tablet.append(dt) elif type == 'note': cal_year.cycle.note = d.copy() elif type == 'colour': # d=['item', (r,g,b)] c = wx.Colour(d[1][0], d[1][1], d[1][2]) if d[0] in cal_year.cycle.colour_set: cal_year.cycle.colour_set[d[0]] = c else: cal_yaar.cycle.colour_set.update({d[0]: c}) # print "Load OK" return True # ------------------------------------------------------- def get_f_name(name=""): if '__WXMSW__' in wx.PlatformInfo: p = os.path.join(os.getcwd(), "data") else: p = os.path.expanduser("~/.cycle") f_name = os.path.join(p, name) return p, f_name # ------------------------------------------------------- def set_color_default(): cal_year.cycle.colour_set = {'begin': wx.TheColourDatabase.Find('RED'), 'prog begin': wx.TheColourDatabase.Find('PINK'), 'conception': wx.TheColourDatabase.Find('MAGENTA'), 'safe sex': wx.TheColourDatabase.Find('WHEAT'), 'fertile': wx.TheColourDatabase.Find('GREEN YELLOW'), 'ovule': wx.TheColourDatabase.Find('SPRING GREEN'), '1-st tablet': wx.TheColourDatabase.Find('GOLD'), 'pause': wx.TheColourDatabase.Find('LIGHT BLUE'), 'next 1-st tablet': wx.TheColourDatabase.Find('PINK')} cycle-0.3.3/set_dir.py000066400000000000000000000001021443566760700146320ustar00rootroot00000000000000 msg_dir="msg" doc_dir="" icons_dir="icons" bitmaps_dir="bitmaps" cycle-0.3.3/setup.py000066400000000000000000000004511443566760700143500ustar00rootroot00000000000000#!/usr/bin/env python from distutils.core import setup setup(name="cycle", version="0.3.3", description="Calendar for women", author="Konstantin L. Metlov", author_email="metlov@donfti.ru", url="https://github.com/metlov/cycle", py_modules=['cycle'], )