-- sedatebk.lua -- Program that add calendar events to the built in DatebookDB -- -- This program is distributed under the BSD license! -- -- Copyright (c) 2005-2007, Robdem Soft AB, Sweden -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions -- are met: -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in -- the documentation and/or other materials provided with the -- distribution. -- * Neither the name of Robdem Soft AB, Sweden nor the names of its -- contributors may be used to endorse or promote products derived -- from this software without specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. SDG_VERSION = '$Revision: 1.0 $' SDG_DATE = '$Date: 2005/02/12 22:26:51 $' SDG_AUTHOR = '$Author: robert $' -- Global variables DBNAME="DatebookDB" IOMODE="w" Noll=1721424.5 caltable= { -- Seeded with events that occur on the same date every year "01-05 Trettondedagsafton", "01-06 Trettondedag jul", "01-13 Tjugondag Knut", "01-27 Förintelsens minnesdag", "01-28 Konungens namnsdag (flaggdag)", "02-14 Alla hjärtans dag", "03-08 Internationella kvinnodagen", "03-12 Kronprinsessans namnsdag (flaggdag)", "03-23 Världsmeteorologidagen", "03-25 Våffeldagen", "04-07 Världshälsodagen", "04-23 Världsboksdagen", "04-30 Valborgsmässoafton", "04-30 Konungens födelsedag (flaggdag)", "05-01 Första Maj (flaggdag)", "05-09 Europadagen", "05-15 Internationella familjedagen", "06-05 Världsmiljödagen", "06-06 Sverige nationaldag (flaggdag)", "07-14 Kronprinsessans födelsedag (flaggdag)", "07-27 Sjusovardagen", "08-08 Drottningens namnsdag (flaggdag)", "08-12 Internationella ungdomsdagen", "09-21 Internationella fredsdagen", "10-24 FN-dagen (flaggdag)", "11-06 Gustav Adolfsdagen (flaggdag)", "11-10 Mårtensafton", "12-10 Nobeldagen (flaggdag)", "12-23 Drottningens födelsedag (flaggdag)", "12-24 Julafton", "12-26 Annandag jul", "12-28 Värnlösa barns dag", "12-31 Nyårsafton", } -- Official Swedish name days since 1991 jantable= { '01-01 Nyårsdagen (flaggdag)', '01-02 Svea', '01-03 Alfred Alfrida', '01-04 Rut', '01-05 Hanna Hannele', '01-06 Kasper Melker Baltsar', '01-07 August Augusta', '01-08 Erland', '01-09 Gunnar Gunder', '01-10 Sigurd Sigbritt', '01-11 Jan Jannike', '01-12 Frideborg Fridolf ', '01-13 Knut', '01-14 Felix Felicia', '01-15 Laura Lorentz', '01-16 Hjalmar Helmer', '01-17 Anton Tony', '01-18 Hilda Hildur', '01-19 Henrik', '01-20 Fabian Sebastian', '01-21 Agnes Agneta', '01-22 Vincent Viktor', '01-23 Frej Freja', '01-24 Erika', '01-25 Paul Pål', '01-26 Bodil Boel', '01-27 Göte Göta', '01-28 Karl Karla', '01-29 Diana', '01-30 Gunilla Gunhild', '01-31 Ivar Joar' } febtable= { '02-01 Max Maximilian', '02-02 Kyndelsmässodagen', '02-03 Disa Hjördis', '02-04 Ansgar Anselm', '02-05 Agata Agda', '02-06 Dorotea Doris', '02-07 Rikard Dick', '02-08 Berta Bert', '02-09 Fanny Franciska', '02-10 Iris', '02-11 Yngve Inge', '02-12 Evelina Evy', '02-13 Agne Ove', '02-14 Valentin', '02-15 Sigfrid', '02-16 Julia Julius', '02-17 Alexandra Sandra', '02-18 Frida Fritiof', '02-19 Gabriella Ella', '02-20 Vivianne', '02-21 Hilding ', '02-22 Pia', '02-23 Torsten Torun', '02-24 Mattias Mats', '02-25 Sigvard Sivert', '02-26 Torgny Torkel', '02-27 Lage', '02-28 Maria' } martable= { '03-01 Albin Elvira', '03-02 Ernst Erna', '03-03 Gunborg Gunvor', '03-04 Adrian Adriana', '03-05 Tora Tove', '03-06 Ebba Ebbe', '03-07 Camilla', '03-08 Siv', '03-09 Torbjörn Torleif', '03-10 Edla Ada', '03-11 Edvin Egon', '03-12 Viktoria', '03-13 Greger', '03-14 Matilda Maud', '03-15 Kristoffer Christel', '03-16 Herbert Gilbert', '03-17 Gertrud', '03-18 Edvard Edmund', '03-19 Josef Josefina', '03-20 Joakim Kim', '03-21 Bengt', '03-22 Kennet Kent', '03-23 Gerda Gerd', '03-24 Gabriel Rafael', '03-25 Marie bebådelsedag', '03-26 Emanuel', '03-27 Rudolf Ralf', '03-28 Malkolm Morgan', '03-29 Jonas Jens', '03-30 Holger Holmfrid', '03-31 Ester' } aprtable= { '04-01 Harald Hervor', '04-02 Gudmund Ingemund', '04-03 Ferdinand Nanna', '04-04 Marianne Marlene', '04-05 Irene Irja', '04-06 Vilhelm Helmi', '04-07 Irma Irmelin', '04-08 Nadja Tanja', '04-09 Otto Ottilia', '04-10 Ingvar Ingvor', '04-11 Ulf Ylva', '04-12 Liv', '04-13 Artur Douglas', '04-14 Tiburtius', '04-15 Olivia Oliver', '04-16 Patrik Patricia', '04-17 Elias Elis', '04-18 Valdemar Volmar', '04-19 Olaus Ola', '04-20 Amalia Amelie', '04-21 Anneli Annika', '04-22 Allan Glenn', '04-23 Georg Göran', '04-24 Vega', '04-25 Markus', '04-26 Teresia Terese', '04-27 Engelbrekt', '04-28 Ture Tyra', '04-29 Tyko', '04-30 Mariana' } majtable= { '05-01 Valborg', '05-02 Filip Filippa', '05-03 John Jane', '05-04 Monika Mona', '05-05 Gotthard Erhard', '05-06 Marit Rita', '05-07 Carina Carita', '05-08 Åke', '05-09 Reidar Reidun', '05-10 Esbjörn Styrbjörn', '05-11 Märta Märit', '05-12 Charlotta Lotta', '05-13 Linnea Linn', '05-14 Halvard Halvar ', '05-15 Sofia Sonja', '05-16 Ronald Ronny', '05-17 Rebecka Ruben', '05-18 Erik', '05-19 Maj Majken', '05-20 Karolina Carola', '05-21 Konstantin Conny', '05-22 Hemming Henning', '05-23 Desideria Desirée', '05-24 Ivan Vanja', '05-25 Urban', '05-26 Vilhelmina Vilma', '05-27 Beda Blenda', '05-28 Ingeborg Borghild', '05-29 Yvonne Jeanette', '05-30 Vera Veronika', '05-31 Petronella Pernilla' } juntable= { '06-01 Gun Gunnel', '06-02 Rutger Roger', '06-03 Ingemar Gudmar', '06-04 Solbritt Solveig', '06-05 Bo', '06-06 Gustav Gösta', '06-07 Robert Robin', '06-08 Eivor Majvor', '06-09 Börje Birger', '06-10 Svante Boris', '06-11 Bertil Berthold', '06-12 Eskil', '06-13 Aina Aino', '06-14 Håkan Hakon', '06-15 Margit Margot', '06-16 Axel Axelina', '06-17 Torborg Torvald', '06-18 Björn Bjarne', '06-19 Germund Görel', '06-20 Linda', '06-21 Alf Alvar', '06-22 Paulina Paula', '06-23 Adolf Alice', '06-24 Johannes Döparens dag', '06-25 David Salomon', '06-26 Rakel Lea', '06-27 Selma Fingal', '06-28 Leo', '06-29 Peter Petra', '06-30 Elof Leif' } jultable= { '07-01 Aron Mirjam', '07-02 Rosa Rosita', '07-03 Aurora', '07-04 Ulrika Ulla', '07-05 Laila Ritva', '07-06 Esaias Jessika', '07-07 Klas', '07-08 Kjell', '07-09 Jörgen Örjan', '07-10 André Andrea', '07-11 Eleonora Ellinor', '07-12 Herman Hermine', '07-13 Joel Judit', '07-14 Folke', '07-15 Ragnhild Ragnvald', '07-16 Reinhold Reine', '07-17 Bruno', '07-18 Fredrik Fritz', '07-19 Sara', '07-20 Margareta Greta', '07-21 Johanna', '07-22 Magdalena Madeleine', '07-23 Emma', '07-24 Kristina Kerstin', '07-25 Jakob', '07-26 Jesper', '07-27 Marta', '07-28 Botvid Seved', '07-29 Olof', '07-30 Algot', '07-31 Helena Elin' } augtable= { '08-01 Per', '08-02 Karin Kajsa', '08-03 Tage', '08-04 Arne Arnold', '08-05 Ulrik Alrik', '08-06 Alfons Inez', '08-07 Dennis Denise', '08-08 Silvia Sylvia', '08-09 Roland', '08-10 Lars', '08-11 Susanna', '08-12 Klara', '08-13 Kaj', '08-14 Uno', '08-15 Stella Estelle', '08-16 Brynolf', '08-17 Verner Valter', '08-18 Ellen Lena', '08-19 Magnus Måns', '08-20 Bernhard Bernt', '08-21 Jon Jonna', '08-22 Henrietta Henrika', '08-23 Signe Signhild', '08-24 Bartolomeus', '08-25 Lovisa Louise', '08-26 Östen', '08-27 Rolf Raoul', '08-28 Gurli Leila', '08-29 Hans Hampus', '08-30 Albert Albertina', '08-31 Arvid Vidar' } septable= { '09-01 Samuel', '09-02 Justus Justina', '09-03 Alfhild Alva', '09-04 Gisela', '09-05 Adela Heidi', '09-06 Lilian Lilly', '09-07 Regina Roy', '09-08 Alma Hulda', '09-09 Anita Annette', '09-10 Tord Turid', '09-11 Dagny Helny', '09-12 Åsa Åslög', '09-13 Sture', '09-14 Ida', '09-15 Sigrid Siri', '09-16 Dag Daga', '09-17 Hildegard Magnhild', '09-18 Orvar', '09-19 Fredrika', '09-20 Elise Lisa', '09-21 Matteus', '09-22 Maurits Moritz', '09-23 Tekla Tea', '09-24 Gerhard Gert', '09-25 Tryggve', '09-26 Enar Einar', '09-27 Dagmar Rigmor', '09-28 Lennart Leonard', '09-29 Mikael Mikaela', '09-30 Helge' } okttable= { '10-01 Ragnar Ragna', '10-02 Ludvig Love', '10-03 Evald Osvald', '10-04 Frans Frank', '10-05 Bror', '10-06 Jenny Jennifer', '10-07 Birgitta Britta', '10-08 Nils', '10-09 Ingrid Inger', '10-10 Harry Harriet', '10-11 Erling Jarl', '10-12 Valfrid Manfred', '10-13 Berit Birgit', '10-14 Stellan', '10-15 Hedvig Hillevi', '10-16 Finn', '10-17 Antonia Toini', '10-18 Lukas', '10-19 Tore Tor', '10-20 Sibylla', '10-21 Ursula Yrsa', '10-22 Marika Marita', '10-23 Severin Sören', '10-24 Evert Eilert', '10-25 Inga Ingalill', '10-26 Amanda Rasmus', '10-27 Sabina', '10-28 Simon Simone', '10-29 Viola', '10-30 Elsa Isabella', '10-31 Edit Edgar' } novtable= { '11-01 Allhelgonadagen', '11-02 Tobias', '11-03 Hubert Hugo', '11-04 Sverker', '11-05 Eugen Eugenia', '11-06 Gustav Adolf', '11-07 Ingegerd Ingela', '11-08 Vendela', '11-09 Teodor Teodora', '11-10 Martin Martina', '11-11 Mårten', '11-12 Konrad Kurt', '11-13 Kristian Krister', '11-14 Emil Emilia', '11-15 Leopold', '11-16 Vibeke Viveka', '11-17 Naemi Naima', '11-18 Lillemor Moa', '11-19 Elisabet Lisbet', '11-20 Pontus Marina', '11-21 Helga Olga', '11-22 Cecilia Sissela', '11-23 Klemens', '11-24 Gudrun Rune', '11-25 Katarina Katja', '11-26 Linus', '11-27 Astrid Asta', '11-28 Malte', '11-29 Sune', '11-30 Andreas Anders' } dectable= { '12-01 Oskar Ossian', '12-02 Beata Beatrice', '12-03 Lydia', '12-04 Barbara Barbro', '12-05 Sven', '12-06 Nikolaus Niklas', '12-07 Angela Angelika', '12-08 Virginia', '12-09 Anna', '12-10 Malin Malena', '12-11 Daniel Daniela', '12-12 Alexander Alexis', '12-13 Lucia', '12-14 Sten Sixten', '12-15 Gottfrid', '12-16 Assar', '12-17 Stig', '12-18 Abraham ', '12-19 Isak', '12-20 Israel Moses', '12-21 Tomas', '12-22 Natanael Jonatan', '12-23 Adam', '12-24 Eva', '12-25 Juldagen (flaggdag)', '12-26 Stefan Staffan', '12-27 Johannes Johan', '12-28 Benjamin', '12-29 Natalia Natalie', '12-30 Abel Set', '12-31 Sylvester' } -- ---------------- -- Date functions -- ---------------- function xdayonorbefore(absdate, xday) -- Using a date in absolute form and a weekday (0=sun,6=sat) return -- the first absolute date this occurs -- local _date = absdate - Noll return ((_date - mod((_date - xday), 7)) + Noll) end function ntexdag(n, xday, absdate) -- Return the first absolute date when the n:th weekday after the -- specified date occurs, i.e. midsummer's day occurs on the first -- saturday on or after July 20. -- if (n > 0) then return (7 * (n - 1) + xdayonorbefore(6 + absdate, xday)) else return (7 * (n + 1) + xdayonorbefore(absdate, xday)) end end function gregorianeaster(year) -- Returns Easter day as an absolute date for the year given. -- local adjusted local century=(1 + floor(year / 100)) local shifted=mod((14+(11*mod(year,19))-floor((3*century)/4)+floor(((8*century)+5)/25)+(30*century)),30) if (shifted == 0 or (shifted == 1 and (10 > mod(year,19)))) then adjusted=(shifted + 1) else adjusted=shifted end return xdayonorbefore(((absgregoriandate(year, 4, 19) - adjusted) + 7),0) end function lastdayofgregorianmonth(month, year) -- Return the last day of the month for a given combination of year -- and month. -- if (month == 2) then if (((mod(year,4) == 0) and (mod(year,100) ~= 0)) or (mod(year,400) == 0)) then return 29 else return 28 end else if ((month == 4) or (month == 6) or (month == 9) or (month == 11)) then return 30 else return 31 end end end function absgregoriandate(year, month, day) -- Return the absolute date of the given year, month, day. -- local _m=month - 1 local _d=day while (_m > 0) do _d=(_d + lastdayofgregorianmonth(_m, year)) _m = _m - 1 end return (_d+(365*floor(year-1))+floor((year-1)/4)-floor((year-1)/100)+floor((year-1)/400)+Noll) end function gregoriandate(absdate) -- Return year, month, day as a table for the given absolute date. -- local year=floor((absdate - Noll) / 366) while (absdate >= absgregoriandate((year + 1), 1, 1)) do year=year + 1 end local month=1 while (absdate > absgregoriandate(year, month,(lastdayofgregorianmonth(month, year)))) do month=month + 1 end local day=(absdate - absgregoriandate(year, month, 1) + 1) return {year, month, day} end -- ------------- -- main ui form -- ------------- function date_form() -- Create and display ui form, handle user input. -- local width, height = pmode() local ha = height / 160 local wa = width / 160 local top = 18 * ha local bot = height - (16 * ha) local lft = 1 local wcenter = 40 * wa local hcenter = 80 * ha local diaw = 50 * wa local diah = 30 * ha pclear() pdestroy() ptitle('Skapa svensk kalender') pmenu({'Om Kalenderfix'}) pmoveto(lft, bot) local cbutid=pbutton(' Utför ') pmoveto(lft, top) plabel("Välj år: ") local wyear={} local ynow=tonumber(date('%Y')) for _=(ynow-3),(ynow+5) do tinsert(wyear, _) end local popid = ppopup(wyear,3) pnl() pnl() print("Programmet kommer att lägga till") print("helger, flaggdagar, namnsdagar och") print("andra speciella datum i din kalender") print("för det år du väljer ovan.") if IOcheckdb() then palert('Kalenderdatabasen saknas!\nSkapa en händelse i kalendern först.') exit(1) end -- while not nil do local event, id, slct = pevent() if event == ctlSelect then if id == cbutid then pdialog(wcenter,hcenter,diaw,diah,'Arbetar') pmoveto(lft,top) plabel("Vänta!") local fh, reccount = IOopendb() addStaticDates(fh, ynow) addVariableDates(fh, ynow) IOclosedb(fh) pdestroy() break end elseif event == popSelect then ynow=wyear[slct+1] elseif event == menuSelect then handle_menu(id) end end pclear() pdestroy() ptitle('Skapa svensk kalender') pmoveto(lft, bot) local cbutid=pbutton(' Ok ') pmoveto(lft, top) print("Alla poster har skrivits.") print("Så fort du avslutat det här") print("programmet skall du utföra en") print("HotSync!") pnl() print("OBS! Om du inte utför en HotSync") print("kommer din kalender inte vara") print("korrekt sorterad. I värsta fall") print("kan din palm krascha!") -- while not nil do local event = pevent() if event == ctlSelect then break end end end function handle_menu(menuindex) -- Show the application about dialog. if menuindex == 1 then local _ = 'Svensk Kalenderfix\nVersion' _ = _ .. strsub(SDG_VERSION, 12, -3) _ = _ .. [[ Copyright (c) 2005-07 Robert de Mander Robdem Soft AB robdemsoft@bostream.nu]] palert(_) end end -- ---------------------------- -- Database io and formatting -- ---------------------------- function calfmt(daystring, absdate) -- Format a calendar event from an absolute date -- local _=gregoriandate(absdate) return (format("%02d-%02d %s", _[2], _[3], daystring)) end function addVariableDates(dbid, year) -- Write variable calendar events/records to the DatebookDB -- local totable = {} if (lastdayofgregorianmonth(2,year) == 29) then tinsert(totable,calfmt("Skottdagen", absgregoriandate(year,2,29))) end local pask=gregorianeaster(year) tinsert(totable,calfmt("Påskdagen (flaggdag)", pask)) tinsert(totable,calfmt("Annandag påsk", pask+1)) tinsert(totable,calfmt("Dymmelonsdagen", pask-4)) tinsert(totable,calfmt("Skärtorsdagen", pask-3)) tinsert(totable,calfmt("Långfredagen", pask-2)) tinsert(totable,calfmt("Påskafton", pask-1)) tinsert(totable,calfmt("Kristi himmmelfärds dag", pask+39)) tinsert(totable,calfmt("Pingstafton", pask+48)) tinsert(totable,calfmt("Pingstdagen (flaggdag)", pask+49)) tinsert(totable,calfmt("Annandag pingst", pask+50)) local fastlag=pask-1 for _=1,7,1 do fastlag=xdayonorbefore(fastlag-1,0) end tinsert(totable,calfmt("Blåmåndag", fastlag+1)) tinsert(totable,calfmt("Fettisdagen", fastlag+2)) tinsert(totable,calfmt("Askonsdagen", fastlag+3)) local midsommar=ntexdag(1,6,absgregoriandate(year,6,20)) tinsert(totable,calfmt("Midsommarafton", midsommar-1)) tinsert(totable,calfmt("Midsommardagen (flaggdag)", midsommar)) local allahelgon=ntexdag(1,6,absgregoriandate(year,10,31)) tinsert(totable,calfmt("Alla helgons dag", allahelgon)) local dstbegin=xdayonorbefore(absgregoriandate(year,3,lastdayofgregorianmonth(3,year)),0) tinsert(totable,calfmt("Sommartid börjar(fram en timme)", dstbegin)) local dstend=xdayonorbefore(absgregoriandate(year,10,lastdayofgregorianmonth(10,year)),0) tinsert(totable,calfmt("Sommartid upphör (tillbaka en timme)", dstend)) local morsdag=xdayonorbefore(absgregoriandate(year,5,lastdayofgregorianmonth(5,year)),0) tinsert(totable,calfmt("Mors dag", morsdag)) local farsdag=ntexdag(2,0,absgregoriandate(year,11,1)) tinsert(totable,calfmt("Fars dag", farsdag)) for _=1,getn(totable),1 do IOwritedb(dbid, IOmakerec(year, totable[_])) end return end function addStaticDates(dbid, year) -- Write static calendar events/records to the DatebookDB -- local totable = { caltable, jantable, febtable, martable, aprtable, majtable, juntable, jultable, augtable, septable, okttable, novtable, dectable } for _, atable in totable do for __, cdata in atable do IOwritedb(dbid, IOmakerec(year, cdata)) end end return end function IOcheckdb() -- Check that DatebookDB is present -- local dblista = listdb('date','DATA') for _=1,getn(dblista),1 do if dblista[_] == DBNAME then return nil end end return 'Ingen DatebookDB' end function IOopendb() -- Open database -- return opendb(DBNAME, IOMODE) end function IOclosedb(dbid) -- Close database -- return closedb(dbid) end function IOwritedb(dbid, wdata) -- Write an untimed entry in the DatebookDB -- local recidx = createrec(dbid,strlen(wdata)) local reclen = openrec(dbid,recidx) if reclen then local iook, iomess = write(dbid,wdata) if not iook then palert('Skrivfel i ' .. DBNAME .. '\n' .. iomess) exit(1) end closerec(dbid) end return end function IOmakerec(byear, bdata) -- Assemble an untimed Datebook entry suitable for writing. -- Data format for an untimed event: -- start hour (byte) always 0xff -- start minute (byte) always 0xff -- end hour (byte) always 0xff -- end minute (byte) always 0xff -- raw date (16-bit word) computed -- flags (16-bit word) computed (0x0400 means description present), 0x008e other flags??????) -- description (null terminated string) -- local ptable = { 255, 255, 255, 255 } -- raw date is -- day and 0x001f (mask five bits) -- month and 0x000f (mask four bits) shifted left 5 bits -- year - 1904 and 0x007f (mask seven) shifted left 9 bits local rday = andb(tonumber(strsub(bdata,4,5)),31) local rmonth = andb(tonumber(strsub(bdata,1,2)),15) * pow(2,5) local ryear = andb((byear - 1904),127) * pow(2,9) local rdate = (rday + rmonth + ryear) tinsert(ptable, rdate) local rflags=1166 tinsert(ptable, rflags) local rtext = strsub(bdata,7) tinsert(ptable, rtext) local wdata = pack('BBBBWWS', ptable) return wdata end -- Main date_form()