summaryrefslogtreecommitdiff
authoralwin <alwin>2005-03-21 14:31:01 (UTC)
committer alwin <alwin>2005-03-21 14:31:01 (UTC)
commit5b2632bcae03b159d137fe9489eb2620c0f65f1a (patch) (unidiff)
tree7984efeeff1bba3083494b38378aaa223a82d117
parent18825d8195f05d1a82affc0111f524371dbdeb5f (diff)
downloadopie-5b2632bcae03b159d137fe9489eb2620c0f65f1a.zip
opie-5b2632bcae03b159d137fe9489eb2620c0f65f1a.tar.gz
opie-5b2632bcae03b159d137fe9489eb2620c0f65f1a.tar.bz2
design bug fixed.
xml-file now may contain floating holidays. syntax of it - see german.xml as example and/or README file in OPIEDIR/etc/nationaldays/
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/datebook/holiday/national/nationalcfg.cpp261
-rw-r--r--core/pim/datebook/holiday/national/nationalcfg.h48
-rw-r--r--core/pim/datebook/holiday/national/nationalholiday.cpp155
-rw-r--r--core/pim/datebook/holiday/national/nationalholiday.h11
4 files changed, 448 insertions, 27 deletions
diff --git a/core/pim/datebook/holiday/national/nationalcfg.cpp b/core/pim/datebook/holiday/national/nationalcfg.cpp
index 52c453f..f71c833 100644
--- a/core/pim/datebook/holiday/national/nationalcfg.cpp
+++ b/core/pim/datebook/holiday/national/nationalcfg.cpp
@@ -8,8 +8,21 @@ static QString _key_desc="description";
8static QString _key_doc="nationaldays"; 8static QString _key_doc="nationaldays";
9static QString _key_list="entries"; 9static QString _key_list="entries";
10static QString _key_entry="entry"; 10static QString _key_entry="entry";
11static QString _key_calc="calculation";
12
13static QString _content_type="type";
14static QString _content_float="floating";
15static QString _content_fix="fix";
16
11static QString _content_name="name"; 17static QString _content_name="name";
18static QString _content_value="value";
19
12static QString _content_date="date"; 20static QString _content_date="date";
21static QString _content_weekd="weekday";
22static QString _content_offset="offset";
23static QString _content_dayofmonth="dayofmonth";
24static QString _content_datedep="datedep";
25static QString _content_month="month";
13 26
14NHcfg::NHcfg() 27NHcfg::NHcfg()
15 :QXmlDefaultHandler(),err(""),_path("") 28 :QXmlDefaultHandler(),err(""),_path("")
@@ -24,7 +37,6 @@ bool NHcfg::load(const QString&aPath)
24{ 37{
25 _path=aPath; 38 _path=aPath;
26 stage = 0; 39 stage = 0;
27 _content.clear();
28 QFile *f=new QFile(_path); 40 QFile *f=new QFile(_path);
29 if (!f) { 41 if (!f) {
30 oerr << "Could not open file" << oendl; 42 oerr << "Could not open file" << oendl;
@@ -35,6 +47,11 @@ bool NHcfg::load(const QString&aPath)
35 reader.setContentHandler(this); 47 reader.setContentHandler(this);
36 reader.setErrorHandler(this); 48 reader.setErrorHandler(this);
37 49
50 currentFixList.clear();
51 currentFloatList.clear();
52 counter = 0;
53 level = 0;
54
38 err = ""; 55 err = "";
39 bool ret = reader.parse(is); 56 bool ret = reader.parse(is);
40 if (err.length()>0) 57 if (err.length()>0)
@@ -42,9 +59,14 @@ bool NHcfg::load(const QString&aPath)
42 return ret; 59 return ret;
43} 60}
44 61
45const tholidaylist&NHcfg::days()const 62const tentrylist&NHcfg::fixDates()const
63{
64 return currentFixList;
65}
66
67const tentrylist&NHcfg::floatingDates()const
46{ 68{
47 return _content; 69 return currentFloatList;
48} 70}
49 71
50bool NHcfg::warning(const QXmlParseException& e) 72bool NHcfg::warning(const QXmlParseException& e)
@@ -101,28 +123,156 @@ bool NHcfg::startElement(const QString&, const QString&,const QString& name, con
101 } 123 }
102 if (stage<2) {return false;} 124 if (stage<2) {return false;}
103 if (name==_key_list) {stage=3;return true;} 125 if (name==_key_list) {stage=3;return true;}
126
104 if (stage<3) {return false;} 127 if (stage<3) {return false;}
105 return parsevalue(name,attr); 128
129 if (name==_key_entry) {
130 ++level;
131 ++counter;
132 m_currentEntry = NHentry();
133 // odebug << "Level == " << level << oendl;
134 }
135 if (name==_key_calc) {
136 ++level;
137// odebug << "Level == " << level << oendl;
138 return true;
139 }
140 if (level == 1) {
141 return parsevalue(name,attr);
142 } else if (level >= 2) {
143 return parseCalc(name,attr);
144 }
145}
146
147bool NHcfg::setName(const QXmlAttributes&attr)
148{
149 int nindx = attr.index("value");
150 if (nindx==-1) {
151 return false;
152 }
153 _contentname = attr.value(nindx);
154 return true;
106} 155}
107 156
108bool NHcfg::parsevalue(const QString&name,const QXmlAttributes&attr) 157bool NHcfg::parsevalue(const QString&name,const QXmlAttributes&attr)
109{ 158{
159 if (name != _key_entry && name != _key_calc) {err = QString("Not a valid entry (%1)").arg(name); return false;}
160
110 int nindex = attr.index(_content_name); 161 int nindex = attr.index(_content_name);
111 int dindex = attr.index(_content_date); 162 int dindex = attr.index(_content_date);
112 if (name != _key_entry) {err = "Not a valid entry"; return false;} 163 int tindex = attr.index(_content_type);
113 if (dindex == -1 || nindex == -1) {err = QString("Listentry %i is invalid").arg(1);return false;} 164
165 if (nindex == -1) {
166 err = QString("Listentry %1 is invalid (name missing)").arg(counter);
167 return false;
168 }
169 m_currentEntry.setName(attr.value(nindex));
170
171 if (tindex != -1 && attr.value(tindex)==_content_float) {
172 m_currentEntry.setType(NHentry::floating);
173 return true;
174 }
175
176 if (dindex == -1) {
177 err = QString("Listentry %1 is invalid ").arg(counter);return false;
178 }
179
114 QString txt = attr.value(nindex); 180 QString txt = attr.value(nindex);
115 QString dstring = attr.value(dindex); 181 QString dstring = attr.value(dindex);
116 QStringList e = QStringList::split("-",dstring); 182 QStringList e = QStringList::split("-",dstring);
117 if (e.count()!=2){err=QString("Datestring %1 is invalid").arg(dstring);return false;} 183 if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(dstring).arg(counter);return false;}
118 QDate d(0,e[0].toInt(),e[1].toInt()); 184 QDate d(0,e[0].toInt(),e[1].toInt());
119 odebug << "Found entry \"" << txt<<"\" on "<<d<<oendl; 185 m_currentEntry.setDate(d);
120 _content[d].append(txt); 186 return true;
187}
188
189bool NHcfg::parseCalc(const QString&name,const QXmlAttributes&attr)
190{
191 ++level;
192 int vindex = attr.index(_content_value);
193 if (vindex == -1) {
194 err = QString("Value for element %1 on entry %2 is missing").arg(name).arg(counter);
195 return false;
196 }
197 int what_c =0;
198 QString what = name.lower();
199 QString value;
200 if (what == _content_date) {
201 what_c = 1;
202 } else if (what == _content_weekd) {
203 what_c = 2;
204 } else if (what == _content_offset) {
205 what_c = 3;
206 } else if (what == _content_dayofmonth) {
207 what_c = 4;
208 } else if (what == _content_datedep) {
209 what_c = 5;
210 } else if (what == _content_month) {
211 what_c = 6;
212 }
213 if (what_c == 0) {
214 err = QString("Unknown element %1 on entry %2").arg(name).arg(counter);
215 return false;
216 }
217 value = attr.value(vindex).lower();
218 QStringList e;
219 QDate d;
220 bool dotformat = false;
221 switch (what_c) {
222 case 1:
223 if (value != "easter") {
224 e = QStringList::split("-",value);
225 if (e.count()!=2) {
226 e = QStringList::split(".",value);
227 dotformat = true;
228 }
229 if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(value).arg(counter);return false;}
230 if (!dotformat) {
231 d=QDate(0,e[0].toInt(),e[1].toInt());
232 } else {
233 d=QDate(0,e[1].toInt(),e[0].toInt());
234 }
235 } else {
236 d=QDate(9999,1,1);
237 }
238 m_currentEntry.setDate(d);
239 break;
240 case 2:
241 m_currentEntry.setWeekday(value);
242 break;
243 case 3:
244 m_currentEntry.setOffet(value.toInt());
245 break;
246 case 4:
247 m_currentEntry.setDayofmonth(value);
248 break;
249 case 5:
250 m_currentEntry.setDaydep(value);
251 break;
252 case 6:
253 m_currentEntry.setMonth(value);
254 break;
255 }
121 return true; 256 return true;
122} 257}
123 258
124bool NHcfg::endElement(const QString&, const QString&,const QString& name) 259bool NHcfg::endElement(const QString&, const QString&,const QString& name)
125{ 260{
261// odebug << "End element: " << name << oendl;
262 if (name==_key_entry) {
263 if (m_currentEntry.type()==NHentry::fix) {
264 currentFixList.append(m_currentEntry);
265 } else {
266 currentFloatList.append(m_currentEntry);
267// odebug << "Floatlist count " << currentFloatList.count() << oendl;
268 }
269 } else if (name==_key_calc) {
270
271 }
272 if (stage>=3) {
273 --level;
274 }
275// odebug << "Level == " << level << oendl;
126 return true; 276 return true;
127} 277}
128 278
@@ -131,12 +281,91 @@ const QString&NHcfg::errorString()const
131 return err; 281 return err;
132} 282}
133 283
134bool NHcfg::setName(const QXmlAttributes&attr) 284NHentry::NHentry()
285 :m_Type(fix)
135{ 286{
136 int nindx = attr.index("value"); 287 m_Offset=0;
137 if (nindx==-1) { 288}
138 return false; 289
139 } 290NHentry::~NHentry()
140 _contentname = attr.value(nindx); 291{}
141 return true; 292
293void NHentry::setName(const QString&aName)
294{
295 m_Name = aName;
296}
297
298const QString&NHentry::name()const
299{
300 return m_Name;
301}
302
303void NHentry::setType(NHentry::entry_type aType)
304{
305 m_Type = aType;
306}
307
308NHentry::entry_type NHentry::type()const
309{
310 return m_Type;
311}
312
313void NHentry::setDate(const QDate&aDate)
314{
315 m_Date = aDate;
316}
317
318const QDate&NHentry::date()const
319{
320 return m_Date;
321}
322
323void NHentry::setWeekday(const QString&aDay)
324{
325 m_Weekday = aDay;
326}
327
328const QString&NHentry::weekday()const
329{
330 return m_Weekday;
331}
332
333void NHentry::setDayofmonth(const QString&aDay)
334{
335 m_Dayofmonth = aDay;
336}
337
338const QString&NHentry::dayofmonth()const
339{
340 return m_Dayofmonth;
341}
342
343void NHentry::setDaydep(const QString&dep)
344{
345 m_Depth = dep;
346}
347
348const QString&NHentry::daydep()const
349{
350 return m_Depth;
351}
352
353void NHentry::setMonth(const QString&month)
354{
355 m_Month = month;
356}
357
358const QString&NHentry::month()const
359{
360 return m_Month;
361}
362
363void NHentry::setOffet(int aOffset)
364{
365 m_Offset = aOffset;
366}
367
368const int NHentry::offset()const
369{
370 return m_Offset;
142} 371}
diff --git a/core/pim/datebook/holiday/national/nationalcfg.h b/core/pim/datebook/holiday/national/nationalcfg.h
index 8f15097..872df65 100644
--- a/core/pim/datebook/holiday/national/nationalcfg.h
+++ b/core/pim/datebook/holiday/national/nationalcfg.h
@@ -3,11 +3,45 @@
3 3
4#include <qxml.h> 4#include <qxml.h>
5#include <qstringlist.h> 5#include <qstringlist.h>
6#include <qvaluelist.h>
6#include <qmap.h> 7#include <qmap.h>
7#include <qdatetime.h> 8#include <qdatetime.h>
8 9
9typedef QMap<QDate,QStringList> tholidaylist; 10typedef QMap<QDate,QStringList> tholidaylist;
10 11
12class NHentry
13{
14public:
15 enum entry_type{fix,floating};
16 NHentry();
17 virtual ~NHentry();
18
19 void setName(const QString&);
20 const QString&name()const;
21 void setType(entry_type);
22 entry_type type()const;
23 void setDate(const QDate&);
24 const QDate&date()const;
25 void setWeekday(const QString&);
26 const QString&weekday()const;
27 void setDayofmonth(const QString&);
28 const QString&dayofmonth()const;
29 void setDaydep(const QString&);
30 const QString&daydep()const;
31 void setMonth(const QString&);
32 const QString&month()const;
33 void setOffet(int);
34 const int offset()const;
35
36protected:
37 entry_type m_Type;
38 QString m_Name,m_Weekday,m_Dayofmonth,m_Depth,m_Month;
39 QDate m_Date;
40 int m_Offset;
41};
42
43typedef QValueList<NHentry> tentrylist;
44
11class NHcfg:public QXmlDefaultHandler 45class NHcfg:public QXmlDefaultHandler
12{ 46{
13public: 47public:
@@ -15,7 +49,8 @@ public:
15 virtual ~NHcfg(); 49 virtual ~NHcfg();
16 50
17 bool load(const QString&); 51 bool load(const QString&);
18 const tholidaylist&days()const; 52 const tentrylist&fixDates()const;
53 const tentrylist&floatingDates()const;
19 54
20 virtual bool warning(const QXmlParseException& e); 55 virtual bool warning(const QXmlParseException& e);
21 virtual bool error(const QXmlParseException& e); 56 virtual bool error(const QXmlParseException& e);
@@ -25,15 +60,16 @@ public:
25 virtual const QString&errorString()const; 60 virtual const QString&errorString()const;
26 61
27protected: 62protected:
28 tholidaylist _content; 63 QString err,_contentname;
29 QString _contentname;
30 QString err;
31 QString _path; 64 QString _path;
32 65
66 NHentry m_currentEntry;
67
33 bool setName(const QXmlAttributes&); 68 bool setName(const QXmlAttributes&);
34 bool parsevalue(const QString&,const QXmlAttributes&); 69 bool parsevalue(const QString&,const QXmlAttributes&);
35 int stage; 70 bool parseCalc(const QString&,const QXmlAttributes&);
36// int pos; 71 int stage,counter,level;
72 tentrylist currentFloatList,currentFixList;
37}; 73};
38 74
39#endif 75#endif
diff --git a/core/pim/datebook/holiday/national/nationalholiday.cpp b/core/pim/datebook/holiday/national/nationalholiday.cpp
index 52f3489..a7ab9a5 100644
--- a/core/pim/datebook/holiday/national/nationalholiday.cpp
+++ b/core/pim/datebook/holiday/national/nationalholiday.cpp
@@ -35,23 +35,163 @@ void NationalHoliday::load_days()
35 Config cfg("nationaldays"); 35 Config cfg("nationaldays");
36 cfg.setGroup("entries"); 36 cfg.setGroup("entries");
37 QStringList::ConstIterator it; 37 QStringList::ConstIterator it;
38 floatingDates.clear();
38 NHcfg readit; 39 NHcfg readit;
39 for (it=files.begin();it!=files.end();++it) { 40 for (it=files.begin();it!=files.end();++it) {
40 if (!readit.load(QPEApplication::qpeDir()+"/etc/nationaldays/"+(*it))) { 41 if (!readit.load(QPEApplication::qpeDir()+"/etc/nationaldays/"+(*it))) {
41 continue; 42 continue;
42 } 43 }
43 tholidaylist::ConstIterator it;
44 for (it=readit.days().begin();it!=readit.days().end();++it) {
45 _days[it.key()]+=(it.data());
46 }
47 44
45 tentrylist::ConstIterator it;
46
47 for (it=readit.fixDates().begin();it!=readit.fixDates().end();++it) {
48 _days[(*it).date()]+=(*it).name();
49 }
50 floatingDates+=readit.floatingDates();
48 } 51 }
49 init_done = true; 52 init_done = true;
50} 53}
51 54
55void NationalHoliday::calc_easterDate()
56{
57 unsigned long n = 0;
58 unsigned long p = 0;
59
60 if ( _lastyear > 1582 ) {
61 unsigned long a = _lastyear%19;
62 unsigned long b = _lastyear/100;
63 unsigned long c = _lastyear%100;
64 unsigned long d = b/4;
65 unsigned long e = b%4;
66 unsigned long f = (b+8)/25;
67 unsigned long g = (b+f+1)/3;
68 unsigned long h = (19*a+b-d-g+15)%30;
69 unsigned long i = c/4;
70 unsigned long j = c%4;
71 unsigned long k = j%100;
72 unsigned long l = (32+2*e+2*i-h-k)%7;
73 unsigned long m = (a+11*h+22*l)/451;
74 n = (h+l-7*m+114)/31;
75 p = (h+l-7*m+114)%31;
76 } else {
77 unsigned long a = _lastyear%4;
78 unsigned long b = _lastyear%7;
79 unsigned long c = _lastyear%19;
80 unsigned long d = (19*c+15)%30;
81 unsigned long e = (2*a+4*b-d+34)%7;
82 n = (d+e+114)/31;
83 p = (d+e+114)%31;
84 }
85 p++;
86 easterDate = QDate(_lastyear,n,p);
87 odebug << "Easterdate = " << easterDate << oendl;
88}
89
90
91void NationalHoliday::setyear(const QDate&aDate)
92{
93 if (aDate.year()==_lastyear) return;
94 odebug << "calc year" << oendl;
95 _lastyear = aDate.year();
96 _fdays.clear();
97 calc_easterDate();
98 tentrylist::ConstIterator it;
99 QDate tempdate,t;
100
101 for (it = floatingDates.begin();it!=floatingDates.end();++it) {
102 odebug << "Float day " << (*it).name() << oendl;
103
104 if ( (*it).date().year()==9999) {
105 tempdate = QDate(easterDate.year(),easterDate.month(),easterDate.day());
106 } else {
107 tempdate = QDate(_lastyear,(*it).date().month(),(*it).date().day());
108 }
109
110 odebug << "Start calc date: " << tempdate << oendl;
111 int weekday = weektonumber((*it).weekday());
112 int mo;
113
114 if (weekday>0) {
115 /* specific weekday set */
116 bool dir = true;
117 if (!(*it).daydep().isEmpty()) {
118 dir = ((*it).daydep()=="before"?true:false);
119 tempdate = movedateday(tempdate,weekday,dir);
120 } else if (!(*it).dayofmonth().isEmpty() &&
121 (mo=monthtonumber((*it).month())) !=0 ) {
122 t = QDate(_lastyear,mo,1);
123 if ((*it).dayofmonth()=="last") {
124 int l = t.daysInMonth();
125 tempdate.setYMD(_lastyear,mo,l);
126 tempdate = movedateday(tempdate,weekday,true);
127 } else {
128 tempdate = movedateday(t,weekday,false);
129 tempdate = tempdate.addDays(dayoftoint((*it).dayofmonth()));
130 }
131 }
132
133 }
134 tempdate = tempdate.addDays((*it).offset());
135 odebug << "Moved date to " << tempdate << oendl;
136 _fdays[tempdate]+=(*it).name();
137 }
138}
139
140int NationalHoliday::dayoftoint(const QString&d)
141{
142 if (d=="first") return 0;
143 else if (d=="second") return 7;
144 else if (d=="third") return 14;
145 else if (d=="fourth") return 21;
146 return 0;
147}
148
149int NationalHoliday::monthtonumber(const QString&m)
150{
151 if (m=="january")return 1;
152 else if (m=="february")return 2;
153 else if (m=="march") return 3;
154 else if (m=="april") return 4;
155 else if (m=="may") return 5;
156 else if (m=="june") return 6;
157 else if (m=="july") return 7;
158 else if (m=="august") return 8;
159 else if (m=="september") return 9;
160 else if (m=="october") return 10;
161 else if (m=="november") return 11;
162 else if (m=="december") return 12;
163 return 0;
164}
165
166QDate NationalHoliday::movedateday(const QDate&start,int weekday,bool direction)
167{
168 QDate d = start;
169 if (weekday==0) return d;
170 int c = (direction?-1:1);
171
172 while (d.dayOfWeek()!=weekday) {
173 d = d.addDays(c);
174 }
175 return d;
176}
177
178int NationalHoliday::weektonumber(const QString&w)
179{
180 if (w=="monday") return 1;
181 else if (w=="tuesday") return 2;
182 else if (w=="wednesday") return 3;
183 else if (w=="thursday" ) return 4;
184 else if (w=="friday") return 5;
185 else if (w=="saturday") return 6;
186 else if (w=="sunday") return 7;
187 return 0;
188}
189
52QStringList NationalHoliday::entries(const QDate&aDate) 190QStringList NationalHoliday::entries(const QDate&aDate)
53{ 191{
54 load_days(); 192 load_days();
193 setyear(aDate);
194
55 QStringList ret; 195 QStringList ret;
56 QDate d(0,aDate.month(),aDate.day()); 196 QDate d(0,aDate.month(),aDate.day());
57 197
@@ -59,7 +199,11 @@ QStringList NationalHoliday::entries(const QDate&aDate)
59 if (it!=_days.end()) { 199 if (it!=_days.end()) {
60 ret+=*it; 200 ret+=*it;
61 } 201 }
62 202 QDate d2(_lastyear,d.month(),d.day());
203 it = _fdays.find(d2);
204 if (it!=_fdays.end()) {
205 ret+=*it;
206 }
63 return ret; 207 return ret;
64} 208}
65 209
@@ -71,6 +215,7 @@ QStringList NationalHoliday::entries(unsigned year, unsigned month, unsigned day
71QMap<QDate,QStringList> NationalHoliday::entries(const QDate&start,const QDate&end) 215QMap<QDate,QStringList> NationalHoliday::entries(const QDate&start,const QDate&end)
72{ 216{
73 load_days(); 217 load_days();
218 setyear(start);
74 QMap<QDate,QStringList> ret; 219 QMap<QDate,QStringList> ret;
75 if (start==end) { 220 if (start==end) {
76 ret[start]=entries(start); 221 ret[start]=entries(start);
diff --git a/core/pim/datebook/holiday/national/nationalholiday.h b/core/pim/datebook/holiday/national/nationalholiday.h
index afce3f4..7f240e0 100644
--- a/core/pim/datebook/holiday/national/nationalholiday.h
+++ b/core/pim/datebook/holiday/national/nationalholiday.h
@@ -26,11 +26,22 @@ public:
26 26
27protected: 27protected:
28 void init(); 28 void init();
29 void setyear(const QDate&);
30 void calc_easterDate();
31 static int weektonumber(const QString&);
32 static QDate movedateday(const QDate&,int weekday,bool direction);
33 static int monthtonumber(const QString&m);
34 static int dayoftoint(const QString&d);
35
29 unsigned int _lastyear; 36 unsigned int _lastyear;
30 tholidaylist _days; 37 tholidaylist _days;
38 tholidaylist _fdays;
39 tentrylist floatingDates;
40
31 QStringList files; 41 QStringList files;
32 bool init_done:1; 42 bool init_done:1;
33 void load_days(); 43 void load_days();
44 QDate easterDate;
34}; 45};
35 46
36#endif 47#endif