summaryrefslogtreecommitdiff
authoralwin <alwin>2005-03-21 14:31:01 (UTC)
committer alwin <alwin>2005-03-21 14:31:01 (UTC)
commit5b2632bcae03b159d137fe9489eb2620c0f65f1a (patch) (side-by-side diff)
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) (show whitespace changes)
-rw-r--r--core/pim/datebook/holiday/national/nationalcfg.cpp257
-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, 446 insertions, 25 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
@@ -3,53 +3,75 @@
#include <opie2/odebug.h>
#include <qfile.h>
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("")
{
}
NHcfg::~NHcfg()
{
}
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;
return false;
}
QXmlInputSource is(*f);
QXmlSimpleReader reader;
reader.setContentHandler(this);
reader.setErrorHandler(this);
+ currentFixList.clear();
+ currentFloatList.clear();
+ counter = 0;
+ level = 0;
+
err = "";
bool ret = reader.parse(is);
if (err.length()>0)
odebug << "Errors: " << err << oendl;
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)
{
QString tmp;
tmp.sprintf("%d: warning: %s\n", e.lineNumber(),
(const char*) e.message().utf8());
@@ -96,47 +118,254 @@ bool NHcfg::startElement(const QString&, const QString&,const QString& name, con
}
if (name==_key_desc) {
stage = 2;
ret = setName(attr);
return ret;
}
if (stage<2) {return false;}
if (name==_key_list) {stage=3;return true;}
+
if (stage<3) {return false;}
+
+ 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 "<<d<<oendl;
- _content[d].append(txt);
+ m_currentEntry.setDate(d);
+ return true;
+}
+
+bool NHcfg::parseCalc(const QString&name,const QXmlAttributes&attr)
+{
+ ++level;
+ int vindex = attr.index(_content_value);
+ if (vindex == -1) {
+ err = QString("Value for element %1 on entry %2 is missing").arg(name).arg(counter);
+ return false;
+ }
+ int what_c =0;
+ QString what = name.lower();
+ QString value;
+ if (what == _content_date) {
+ what_c = 1;
+ } else if (what == _content_weekd) {
+ what_c = 2;
+ } else if (what == _content_offset) {
+ what_c = 3;
+ } else if (what == _content_dayofmonth) {
+ what_c = 4;
+ } else if (what == _content_datedep) {
+ what_c = 5;
+ } else if (what == _content_month) {
+ what_c = 6;
+ }
+ if (what_c == 0) {
+ err = QString("Unknown element %1 on entry %2").arg(name).arg(counter);
+ return false;
+ }
+ value = attr.value(vindex).lower();
+ QStringList e;
+ QDate d;
+ bool dotformat = false;
+ switch (what_c) {
+ case 1:
+ if (value != "easter") {
+ e = QStringList::split("-",value);
+ if (e.count()!=2) {
+ e = QStringList::split(".",value);
+ dotformat = true;
+ }
+ if (e.count()!=2){err=QString("Datestring %1 is invalid (entry %2)").arg(value).arg(counter);return false;}
+ if (!dotformat) {
+ d=QDate(0,e[0].toInt(),e[1].toInt());
+ } else {
+ d=QDate(0,e[1].toInt(),e[0].toInt());
+ }
+ } else {
+ d=QDate(9999,1,1);
+ }
+ m_currentEntry.setDate(d);
+ break;
+ case 2:
+ m_currentEntry.setWeekday(value);
+ break;
+ case 3:
+ m_currentEntry.setOffet(value.toInt());
+ break;
+ case 4:
+ m_currentEntry.setDayofmonth(value);
+ break;
+ case 5:
+ m_currentEntry.setDaydep(value);
+ break;
+ case 6:
+ m_currentEntry.setMonth(value);
+ break;
+ }
return true;
}
bool NHcfg::endElement(const QString&, const QString&,const QString& name)
{
+// odebug << "End element: " << name << oendl;
+ if (name==_key_entry) {
+ if (m_currentEntry.type()==NHentry::fix) {
+ currentFixList.append(m_currentEntry);
+ } else {
+ currentFloatList.append(m_currentEntry);
+// odebug << "Floatlist count " << currentFloatList.count() << oendl;
+ }
+ } else if (name==_key_calc) {
+
+ }
+ if (stage>=3) {
+ --level;
+ }
+// odebug << "Level == " << level << oendl;
return true;
}
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;
+ m_Offset=0;
}
- _contentname = attr.value(nindx);
- return true;
+
+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
@@ -1,39 +1,75 @@
#ifndef _NATIONAL_CFG_H
#define _NATIONAL_CFG_H
#include <qxml.h>
#include <qstringlist.h>
+#include <qvaluelist.h>
#include <qmap.h>
#include <qdatetime.h>
typedef QMap<QDate,QStringList> 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<NHentry> tentrylist;
+
class NHcfg:public QXmlDefaultHandler
{
public:
NHcfg();
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);
virtual bool fatalError(const QXmlParseException& e);
virtual bool startElement(const QString&, const QString&,const QString& name, const QXmlAttributes& attr);
virtual bool endElement(const QString&, const QString&,const QString& name);
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
@@ -30,52 +30,197 @@ void NationalHoliday::init()
}
void NationalHoliday::load_days()
{
if (init_done) return;
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());
tholidaylist::Iterator it = _days.find(d);
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;
}
QStringList NationalHoliday::entries(unsigned year, unsigned month, unsigned day)
{
return entries(QDate(0,month,day));
}
QMap<QDate,QStringList> NationalHoliday::entries(const QDate&start,const QDate&end)
{
load_days();
+ setyear(start);
QMap<QDate,QStringList> ret;
if (start==end) {
ret[start]=entries(start);
return ret;
}
QDate d;
int daysto;
if (end < 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
@@ -21,16 +21,27 @@ public:
virtual QStringList entries(const QDate&);
virtual QStringList entries(unsigned year, unsigned month, unsigned day);
virtual QMap<QDate,QStringList> entries(const QDate&,const QDate&);
virtual QValueList<EffectiveEvent> events(const QDate&,const QDate&);
virtual Opie::Datebook::HolidayPluginConfigWidget*configWidget(QWidget *parent=0, const char *name = 0, QWidget::WFlags fl = 0);
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