00001 #include "nationalholiday.h"
00002 #include "nationalcfg.h"
00003 #include "nationalcfgwidget.h"
00004
00005 #include <opie2/odebug.h>
00006
00007 #include <qobject.h>
00008 #include <qpe/event.h>
00009 #include <qpe/config.h>
00010 #include <qpe/qpeapplication.h>
00011
00012 NationalHoliday::NationalHoliday()
00013 :Opie::Datebook::HolidayPlugin()
00014 {
00015 _lastyear=0;
00016 init_done = false;
00017 init();
00018 }
00019
00020 QString NationalHoliday::description()
00021 {
00022 return QObject::tr("National holidays","holidays");
00023 }
00024
00025 void NationalHoliday::init()
00026 {
00027 Config cfg("nationaldays");
00028 cfg.setGroup("entries");
00029 files = cfg.readListEntry("files");
00030 }
00031
00032 void NationalHoliday::load_days()
00033 {
00034 if (init_done) return;
00035 Config cfg("nationaldays");
00036 cfg.setGroup("entries");
00037 QStringList::ConstIterator it;
00038 floatingDates.clear();
00039 NHcfg readit;
00040 for (it=files.begin();it!=files.end();++it) {
00041 if (!readit.load(QPEApplication::qpeDir()+"/etc/nationaldays/"+(*it))) {
00042 continue;
00043 }
00044
00045 tentrylist::ConstIterator it;
00046
00047 for (it=readit.fixDates().begin();it!=readit.fixDates().end();++it) {
00048 _days[(*it).date()]+=(*it).name();
00049 }
00050 floatingDates+=readit.floatingDates();
00051 }
00052 init_done = true;
00053 }
00054
00055 void NationalHoliday::calc_easterDate()
00056 {
00057 unsigned long n = 0;
00058 unsigned long p = 0;
00059
00060 if ( _lastyear > 1582 ) {
00061 unsigned long a = _lastyear%19;
00062 unsigned long b = _lastyear/100;
00063 unsigned long c = _lastyear%100;
00064 unsigned long d = b/4;
00065 unsigned long e = b%4;
00066 unsigned long f = (b+8)/25;
00067 unsigned long g = (b+f+1)/3;
00068 unsigned long h = (19*a+b-d-g+15)%30;
00069 unsigned long i = c/4;
00070 unsigned long j = c%4;
00071 unsigned long k = j%100;
00072 unsigned long l = (32+2*e+2*i-h-k)%7;
00073 unsigned long m = (a+11*h+22*l)/451;
00074 n = (h+l-7*m+114)/31;
00075 p = (h+l-7*m+114)%31;
00076 } else {
00077 unsigned long a = _lastyear%4;
00078 unsigned long b = _lastyear%7;
00079 unsigned long c = _lastyear%19;
00080 unsigned long d = (19*c+15)%30;
00081 unsigned long e = (2*a+4*b-d+34)%7;
00082 n = (d+e+114)/31;
00083 p = (d+e+114)%31;
00084 }
00085 p++;
00086 easterDate = QDate(_lastyear,n,p);
00087 odebug << "Easterdate = " << easterDate << oendl;
00088 }
00089
00090
00091 void NationalHoliday::setyear(const QDate&aDate)
00092 {
00093 if (aDate.year()==_lastyear) return;
00094 odebug << "calc year" << oendl;
00095 _lastyear = aDate.year();
00096 _fdays.clear();
00097 calc_easterDate();
00098 tentrylist::ConstIterator it;
00099 QDate tempdate,t;
00100
00101 for (it = floatingDates.begin();it!=floatingDates.end();++it) {
00102 odebug << "Float day " << (*it).name() << oendl;
00103
00104 if ( (*it).date().year()==9999) {
00105 tempdate = QDate(easterDate.year(),easterDate.month(),easterDate.day());
00106 } else {
00107 tempdate = QDate(_lastyear,(*it).date().month(),(*it).date().day());
00108 }
00109
00110 odebug << "Start calc date: " << tempdate << oendl;
00111 int weekday = weektonumber((*it).weekday());
00112 int mo;
00113
00114 if (weekday>0) {
00115
00116 bool dir = true;
00117 if (!(*it).daydep().isEmpty()) {
00118 dir = ((*it).daydep()=="before"?true:false);
00119 tempdate = movedateday(tempdate,weekday,dir);
00120 } else if (!(*it).dayofmonth().isEmpty() &&
00121 (mo=monthtonumber((*it).month())) !=0 ) {
00122 t = QDate(_lastyear,mo,1);
00123 if ((*it).dayofmonth()=="last") {
00124 int l = t.daysInMonth();
00125 tempdate.setYMD(_lastyear,mo,l);
00126 tempdate = movedateday(tempdate,weekday,true);
00127 } else {
00128 tempdate = movedateday(t,weekday,false);
00129 tempdate = tempdate.addDays(dayoftoint((*it).dayofmonth()));
00130 }
00131 }
00132
00133 }
00134 tempdate = tempdate.addDays((*it).offset());
00135 odebug << "Moved date to " << tempdate << oendl;
00136 _fdays[tempdate]+=(*it).name();
00137 }
00138 }
00139
00140 int NationalHoliday::dayoftoint(const QString&d)
00141 {
00142 if (d=="first") return 0;
00143 else if (d=="second") return 7;
00144 else if (d=="third") return 14;
00145 else if (d=="fourth") return 21;
00146 return 0;
00147 }
00148
00149 int NationalHoliday::monthtonumber(const QString&m)
00150 {
00151 if (m=="january")return 1;
00152 else if (m=="february")return 2;
00153 else if (m=="march") return 3;
00154 else if (m=="april") return 4;
00155 else if (m=="may") return 5;
00156 else if (m=="june") return 6;
00157 else if (m=="july") return 7;
00158 else if (m=="august") return 8;
00159 else if (m=="september") return 9;
00160 else if (m=="october") return 10;
00161 else if (m=="november") return 11;
00162 else if (m=="december") return 12;
00163 return 0;
00164 }
00165
00166 QDate NationalHoliday::movedateday(const QDate&start,int weekday,bool direction)
00167 {
00168 QDate d = start;
00169 if (weekday==0) return d;
00170 int c = (direction?-1:1);
00171
00172 while (d.dayOfWeek()!=weekday) {
00173 d = d.addDays(c);
00174 }
00175 return d;
00176 }
00177
00178 int NationalHoliday::weektonumber(const QString&w)
00179 {
00180 if (w=="monday") return 1;
00181 else if (w=="tuesday") return 2;
00182 else if (w=="wednesday") return 3;
00183 else if (w=="thursday" ) return 4;
00184 else if (w=="friday") return 5;
00185 else if (w=="saturday") return 6;
00186 else if (w=="sunday") return 7;
00187 return 0;
00188 }
00189
00190 QStringList NationalHoliday::entries(const QDate&aDate)
00191 {
00192 load_days();
00193 setyear(aDate);
00194
00195 QStringList ret;
00196 QDate d(0,aDate.month(),aDate.day());
00197
00198 tholidaylist::Iterator it = _days.find(d);
00199 if (it!=_days.end()) {
00200 ret+=*it;
00201 }
00202 QDate d2(_lastyear,d.month(),d.day());
00203 it = _fdays.find(d2);
00204 if (it!=_fdays.end()) {
00205 ret+=*it;
00206 }
00207 return ret;
00208 }
00209
00210 QStringList NationalHoliday::entries(unsigned year, unsigned month, unsigned day)
00211 {
00212 return entries(QDate(0,month,day));
00213 }
00214
00215 QMap<QDate,QStringList> NationalHoliday::entries(const QDate&start,const QDate&end)
00216 {
00217 load_days();
00218 setyear(start);
00219 QMap<QDate,QStringList> ret;
00220 if (start==end) {
00221 ret[start]=entries(start);
00222 return ret;
00223 }
00224 QDate d;
00225 int daysto;
00226 if (end < start) {
00227 d = end;
00228 daysto = end.daysTo(start);
00229 } else {
00230 d = start;
00231 daysto = start.daysTo(end);
00232 }
00233 QStringList temp;
00234 for (int i=0;i<=daysto;++i) {
00235 temp = entries(d.addDays(i));
00236 if (temp.count()==0) continue;
00237 ret[d.addDays(i)]+=temp;
00238 temp.clear();
00239 }
00240 return ret;
00241 }
00242
00243 QValueList<EffectiveEvent> NationalHoliday::events(const QDate&start,const QDate&end)
00244 {
00245 QValueList<EffectiveEvent> ret;
00246 QDate d = (start<end?start:end);
00247 int daysto = start.daysTo(end);
00248 if (daysto < 0) {
00249 daysto = end.daysTo(start);
00250 }
00251
00252 QStringList temp;
00253 for (int i =0; i<=daysto;++i) {
00254 temp = entries(d.addDays(i));
00255 if (temp.count()==0) {
00256 continue;
00257 }
00258 for (unsigned j=0;j<temp.count();++j) {
00259 Event ev;
00260 ev.setDescription(temp[j]);
00261 ev.setStart(d.addDays(i));
00262 ev.setAllDay(true);
00263 ret.append(EffectiveEvent(ev,d.addDays(i)));
00264 }
00265 }
00266
00267 return ret;
00268 }
00269
00270 Opie::Datebook::HolidayPluginConfigWidget*NationalHoliday::configWidget(QWidget *parent, const char *name, QWidget::WFlags fl)
00271 {
00272 return new NationalHolidayConfigWidget(parent,name,fl);
00273 }
00274
00275 EXPORT_HOLIDAY_PLUGIN(NationalHoliday);