From 5b2632bcae03b159d137fe9489eb2620c0f65f1a Mon Sep 17 00:00:00 2001 From: alwin Date: Mon, 21 Mar 2005 14:31:01 +0000 Subject: 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/ --- (limited to 'core/pim') 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"; static QString _key_doc="nationaldays"; static QString _key_list="entries"; static QString _key_entry="entry"; +static QString _key_calc="calculation"; + +static QString _content_type="type"; +static QString _content_float="floating"; +static QString _content_fix="fix"; + static QString _content_name="name"; +static QString _content_value="value"; + static QString _content_date="date"; +static QString _content_weekd="weekday"; +static QString _content_offset="offset"; +static QString _content_dayofmonth="dayofmonth"; +static QString _content_datedep="datedep"; +static QString _content_month="month"; NHcfg::NHcfg() :QXmlDefaultHandler(),err(""),_path("") @@ -24,7 +37,6 @@ bool NHcfg::load(const QString&aPath) { _path=aPath; stage = 0; - _content.clear(); QFile *f=new QFile(_path); if (!f) { oerr << "Could not open file" << oendl; @@ -35,6 +47,11 @@ bool NHcfg::load(const QString&aPath) reader.setContentHandler(this); reader.setErrorHandler(this); + currentFixList.clear(); + currentFloatList.clear(); + counter = 0; + level = 0; + err = ""; bool ret = reader.parse(is); if (err.length()>0) @@ -42,9 +59,14 @@ bool NHcfg::load(const QString&aPath) return ret; } -const tholidaylist&NHcfg::days()const +const tentrylist&NHcfg::fixDates()const +{ + return currentFixList; +} + +const tentrylist&NHcfg::floatingDates()const { - return _content; + return currentFloatList; } bool NHcfg::warning(const QXmlParseException& e) @@ -101,28 +123,156 @@ bool NHcfg::startElement(const QString&, const QString&,const QString& name, con } if (stage<2) {return false;} if (name==_key_list) {stage=3;return true;} + if (stage<3) {return false;} - return parsevalue(name,attr); + + if (name==_key_entry) { + ++level; + ++counter; + m_currentEntry = NHentry(); + // odebug << "Level == " << level << oendl; + } + if (name==_key_calc) { + ++level; +// odebug << "Level == " << level << oendl; + return true; + } + if (level == 1) { + return parsevalue(name,attr); + } else if (level >= 2) { + return parseCalc(name,attr); + } +} + +bool NHcfg::setName(const QXmlAttributes&attr) +{ + int nindx = attr.index("value"); + if (nindx==-1) { + return false; + } + _contentname = attr.value(nindx); + return true; } bool NHcfg::parsevalue(const QString&name,const QXmlAttributes&attr) { + if (name != _key_entry && name != _key_calc) {err = QString("Not a valid entry (%1)").arg(name); return false;} + int nindex = attr.index(_content_name); int dindex = attr.index(_content_date); - if (name != _key_entry) {err = "Not a valid entry"; return false;} - if (dindex == -1 || nindex == -1) {err = QString("Listentry %i is invalid").arg(1);return false;} + int tindex = attr.index(_content_type); + + if (nindex == -1) { + err = QString("Listentry %1 is invalid (name missing)").arg(counter); + return false; + } + m_currentEntry.setName(attr.value(nindex)); + + if (tindex != -1 && attr.value(tindex)==_content_float) { + m_currentEntry.setType(NHentry::floating); + return true; + } + + if (dindex == -1) { + err = QString("Listentry %1 is invalid ").arg(counter);return false; + } + QString txt = attr.value(nindex); QString dstring = attr.value(dindex); QStringList e = QStringList::split("-",dstring); - if (e.count()!=2){err=QString("Datestring %1 is invalid").arg(dstring);return false;} + if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(dstring).arg(counter);return false;} QDate d(0,e[0].toInt(),e[1].toInt()); - odebug << "Found entry \"" << txt<<"\" on "<=3) { + --level; + } +// odebug << "Level == " << level << oendl; return true; } @@ -131,12 +281,91 @@ const QString&NHcfg::errorString()const return err; } -bool NHcfg::setName(const QXmlAttributes&attr) +NHentry::NHentry() + :m_Type(fix) { - int nindx = attr.index("value"); - if (nindx==-1) { - return false; - } - _contentname = attr.value(nindx); - return true; + m_Offset=0; +} + +NHentry::~NHentry() +{} + +void NHentry::setName(const QString&aName) +{ + m_Name = aName; +} + +const QString&NHentry::name()const +{ + return m_Name; +} + +void NHentry::setType(NHentry::entry_type aType) +{ + m_Type = aType; +} + +NHentry::entry_type NHentry::type()const +{ + return m_Type; +} + +void NHentry::setDate(const QDate&aDate) +{ + m_Date = aDate; +} + +const QDate&NHentry::date()const +{ + return m_Date; +} + +void NHentry::setWeekday(const QString&aDay) +{ + m_Weekday = aDay; +} + +const QString&NHentry::weekday()const +{ + return m_Weekday; +} + +void NHentry::setDayofmonth(const QString&aDay) +{ + m_Dayofmonth = aDay; +} + +const QString&NHentry::dayofmonth()const +{ + return m_Dayofmonth; +} + +void NHentry::setDaydep(const QString&dep) +{ + m_Depth = dep; +} + +const QString&NHentry::daydep()const +{ + return m_Depth; +} + +void NHentry::setMonth(const QString&month) +{ + m_Month = month; +} + +const QString&NHentry::month()const +{ + return m_Month; +} + +void NHentry::setOffet(int aOffset) +{ + m_Offset = aOffset; +} + +const int NHentry::offset()const +{ + return m_Offset; } 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 @@ #include #include +#include #include #include typedef QMap tholidaylist; +class NHentry +{ +public: + enum entry_type{fix,floating}; + NHentry(); + virtual ~NHentry(); + + void setName(const QString&); + const QString&name()const; + void setType(entry_type); + entry_type type()const; + void setDate(const QDate&); + const QDate&date()const; + void setWeekday(const QString&); + const QString&weekday()const; + void setDayofmonth(const QString&); + const QString&dayofmonth()const; + void setDaydep(const QString&); + const QString&daydep()const; + void setMonth(const QString&); + const QString&month()const; + void setOffet(int); + const int offset()const; + +protected: + entry_type m_Type; + QString m_Name,m_Weekday,m_Dayofmonth,m_Depth,m_Month; + QDate m_Date; + int m_Offset; +}; + +typedef QValueList tentrylist; + class NHcfg:public QXmlDefaultHandler { public: @@ -15,7 +49,8 @@ public: virtual ~NHcfg(); bool load(const QString&); - const tholidaylist&days()const; + const tentrylist&fixDates()const; + const tentrylist&floatingDates()const; virtual bool warning(const QXmlParseException& e); virtual bool error(const QXmlParseException& e); @@ -25,15 +60,16 @@ public: virtual const QString&errorString()const; protected: - tholidaylist _content; - QString _contentname; - QString err; + QString err,_contentname; QString _path; + NHentry m_currentEntry; + bool setName(const QXmlAttributes&); bool parsevalue(const QString&,const QXmlAttributes&); - int stage; -// int pos; + bool parseCalc(const QString&,const QXmlAttributes&); + int stage,counter,level; + tentrylist currentFloatList,currentFixList; }; #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() Config cfg("nationaldays"); cfg.setGroup("entries"); QStringList::ConstIterator it; + floatingDates.clear(); NHcfg readit; for (it=files.begin();it!=files.end();++it) { if (!readit.load(QPEApplication::qpeDir()+"/etc/nationaldays/"+(*it))) { continue; } - tholidaylist::ConstIterator it; - for (it=readit.days().begin();it!=readit.days().end();++it) { - _days[it.key()]+=(it.data()); - } + tentrylist::ConstIterator it; + + for (it=readit.fixDates().begin();it!=readit.fixDates().end();++it) { + _days[(*it).date()]+=(*it).name(); + } + floatingDates+=readit.floatingDates(); } init_done = true; } +void NationalHoliday::calc_easterDate() +{ + unsigned long n = 0; + unsigned long p = 0; + + if ( _lastyear > 1582 ) { + unsigned long a = _lastyear%19; + unsigned long b = _lastyear/100; + unsigned long c = _lastyear%100; + unsigned long d = b/4; + unsigned long e = b%4; + unsigned long f = (b+8)/25; + unsigned long g = (b+f+1)/3; + unsigned long h = (19*a+b-d-g+15)%30; + unsigned long i = c/4; + unsigned long j = c%4; + unsigned long k = j%100; + unsigned long l = (32+2*e+2*i-h-k)%7; + unsigned long m = (a+11*h+22*l)/451; + n = (h+l-7*m+114)/31; + p = (h+l-7*m+114)%31; + } else { + unsigned long a = _lastyear%4; + unsigned long b = _lastyear%7; + unsigned long c = _lastyear%19; + unsigned long d = (19*c+15)%30; + unsigned long e = (2*a+4*b-d+34)%7; + n = (d+e+114)/31; + p = (d+e+114)%31; + } + p++; + easterDate = QDate(_lastyear,n,p); + odebug << "Easterdate = " << easterDate << oendl; +} + + +void NationalHoliday::setyear(const QDate&aDate) +{ + if (aDate.year()==_lastyear) return; + odebug << "calc year" << oendl; + _lastyear = aDate.year(); + _fdays.clear(); + calc_easterDate(); + tentrylist::ConstIterator it; + QDate tempdate,t; + + for (it = floatingDates.begin();it!=floatingDates.end();++it) { + odebug << "Float day " << (*it).name() << oendl; + + if ( (*it).date().year()==9999) { + tempdate = QDate(easterDate.year(),easterDate.month(),easterDate.day()); + } else { + tempdate = QDate(_lastyear,(*it).date().month(),(*it).date().day()); + } + + odebug << "Start calc date: " << tempdate << oendl; + int weekday = weektonumber((*it).weekday()); + int mo; + + if (weekday>0) { + /* specific weekday set */ + bool dir = true; + if (!(*it).daydep().isEmpty()) { + dir = ((*it).daydep()=="before"?true:false); + tempdate = movedateday(tempdate,weekday,dir); + } else if (!(*it).dayofmonth().isEmpty() && + (mo=monthtonumber((*it).month())) !=0 ) { + t = QDate(_lastyear,mo,1); + if ((*it).dayofmonth()=="last") { + int l = t.daysInMonth(); + tempdate.setYMD(_lastyear,mo,l); + tempdate = movedateday(tempdate,weekday,true); + } else { + tempdate = movedateday(t,weekday,false); + tempdate = tempdate.addDays(dayoftoint((*it).dayofmonth())); + } + } + + } + tempdate = tempdate.addDays((*it).offset()); + odebug << "Moved date to " << tempdate << oendl; + _fdays[tempdate]+=(*it).name(); + } +} + +int NationalHoliday::dayoftoint(const QString&d) +{ + if (d=="first") return 0; + else if (d=="second") return 7; + else if (d=="third") return 14; + else if (d=="fourth") return 21; + return 0; +} + +int NationalHoliday::monthtonumber(const QString&m) +{ + if (m=="january")return 1; + else if (m=="february")return 2; + else if (m=="march") return 3; + else if (m=="april") return 4; + else if (m=="may") return 5; + else if (m=="june") return 6; + else if (m=="july") return 7; + else if (m=="august") return 8; + else if (m=="september") return 9; + else if (m=="october") return 10; + else if (m=="november") return 11; + else if (m=="december") return 12; + return 0; +} + +QDate NationalHoliday::movedateday(const QDate&start,int weekday,bool direction) +{ + QDate d = start; + if (weekday==0) return d; + int c = (direction?-1:1); + + while (d.dayOfWeek()!=weekday) { + d = d.addDays(c); + } + return d; +} + +int NationalHoliday::weektonumber(const QString&w) +{ + if (w=="monday") return 1; + else if (w=="tuesday") return 2; + else if (w=="wednesday") return 3; + else if (w=="thursday" ) return 4; + else if (w=="friday") return 5; + else if (w=="saturday") return 6; + else if (w=="sunday") return 7; + return 0; +} + QStringList NationalHoliday::entries(const QDate&aDate) { load_days(); + setyear(aDate); + QStringList ret; QDate d(0,aDate.month(),aDate.day()); @@ -59,7 +199,11 @@ QStringList NationalHoliday::entries(const QDate&aDate) if (it!=_days.end()) { ret+=*it; } - + QDate d2(_lastyear,d.month(),d.day()); + it = _fdays.find(d2); + if (it!=_fdays.end()) { + ret+=*it; + } return ret; } @@ -71,6 +215,7 @@ QStringList NationalHoliday::entries(unsigned year, unsigned month, unsigned day QMap NationalHoliday::entries(const QDate&start,const QDate&end) { load_days(); + setyear(start); QMap ret; if (start==end) { 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: protected: void init(); + void setyear(const QDate&); + void calc_easterDate(); + static int weektonumber(const QString&); + static QDate movedateday(const QDate&,int weekday,bool direction); + static int monthtonumber(const QString&m); + static int dayoftoint(const QString&d); + unsigned int _lastyear; tholidaylist _days; + tholidaylist _fdays; + tentrylist floatingDates; + QStringList files; bool init_done:1; void load_days(); + QDate easterDate; }; #endif -- cgit v0.9.0.2